xref: /aosp_15_r20/external/grpc-grpc/src/objective-c/GRPCClient/GRPCCallOptions.mm (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1/*
2 *
3 * Copyright 2018 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19#import "GRPCCallOptions.h"
20#import "GRPCTransport.h"
21#import "internal/GRPCCallOptions+Internal.h"
22
23// The default values for the call options.
24static NSString *const kDefaultServerAuthority = nil;
25static const NSTimeInterval kDefaultTimeout = 0;
26static const BOOL kDefaultFlowControlEnabled = NO;
27static NSArray<id<GRPCInterceptorFactory>> *const kDefaultInterceptorFactories = nil;
28static GRPCMetadataDictionary *const kDefaultInitialMetadata = nil;
29static NSString *const kDefaultUserAgentPrefix = nil;
30static NSString *const kDefaultUserAgentSuffix = nil;
31static const NSUInteger kDefaultResponseSizeLimit = 0;
32static const GRPCCompressionAlgorithm kDefaultCompressionAlgorithm = GRPCCompressNone;
33static const BOOL kDefaultRetryEnabled = YES;
34static const NSTimeInterval kDefaultMaxRetryInterval =
35    0;  // Use transport's default max retry interval
36static const NSTimeInterval kDefaultMinRetryInterval =
37    0;                                        // Use transport's default min retry interval
38static const double kDefaultRetryFactor = 0;  // Use transport's default retry factor
39static const NSTimeInterval kDefaultKeepaliveInterval = 0;
40static const NSTimeInterval kDefaultKeepaliveTimeout = 0;
41static const NSTimeInterval kDefaultConnectMinTimeout = 0;
42static const NSTimeInterval kDefaultConnectInitialBackoff = 0;
43static const NSTimeInterval kDefaultConnectMaxBackoff = 0;
44static GRPCMetadataDictionary *const kDefaultAdditionalChannelArgs = nil;
45static NSString *const kDefaultPEMRootCertificates = nil;
46static NSString *const kDefaultPEMPrivateKey = nil;
47static NSString *const kDefaultPEMCertificateChain = nil;
48static NSString *const kDefaultOauth2AccessToken = nil;
49static const id<GRPCAuthorizationProtocol> kDefaultAuthTokenProvider = nil;
50static const GRPCTransportType kDefaultTransportType = GRPCTransportTypeChttp2BoringSSL;
51static const GRPCTransportID kDefaultTransport = NULL;
52static NSString *const kDefaultHostNameOverride = nil;
53static const id kDefaultLogContext = nil;
54static NSString *const kDefaultChannelPoolDomain = nil;
55static const NSUInteger kDefaultChannelID = 0;
56
57// Check if two objects are equal. Returns YES if both are nil;
58static BOOL areObjectsEqual(id obj1, id obj2) {
59  if (obj1 == obj2) {
60    return YES;
61  }
62  if (obj1 == nil || obj2 == nil) {
63    return NO;
64  }
65  return [obj1 isEqual:obj2];
66}
67
68@implementation GRPCCallOptions {
69 @protected
70  NSString *_serverAuthority;
71  NSTimeInterval _timeout;
72  BOOL _flowControlEnabled;
73  NSArray<id<GRPCInterceptorFactory>> *_interceptorFactories;
74  NSString *_oauth2AccessToken;
75  id<GRPCAuthorizationProtocol> _authTokenProvider;
76  GRPCMetadataDictionary *_initialMetadata;
77  NSString *_userAgentPrefix;
78  NSString *_userAgentSuffix;
79  NSUInteger _responseSizeLimit;
80  GRPCCompressionAlgorithm _compressionAlgorithm;
81  BOOL _retryEnabled;
82  NSTimeInterval _maxRetryInterval;
83  NSTimeInterval _minRetryInterval;
84  double _retryFactor;
85  NSTimeInterval _keepaliveInterval;
86  NSTimeInterval _keepaliveTimeout;
87  NSTimeInterval _connectMinTimeout;
88  NSTimeInterval _connectInitialBackoff;
89  NSTimeInterval _connectMaxBackoff;
90  GRPCMetadataDictionary *_additionalChannelArgs;
91  NSString *_PEMRootCertificates;
92  NSString *_PEMPrivateKey;
93  NSString *_PEMCertificateChain;
94  GRPCTransportType _transportType;
95  GRPCTransportID _transport;
96  NSString *_hostNameOverride;
97  id<NSObject> _logContext;
98  NSString *_channelPoolDomain;
99  NSUInteger _channelID;
100}
101
102@synthesize serverAuthority = _serverAuthority;
103@synthesize timeout = _timeout;
104@synthesize flowControlEnabled = _flowControlEnabled;
105@synthesize interceptorFactories = _interceptorFactories;
106@synthesize oauth2AccessToken = _oauth2AccessToken;
107@synthesize authTokenProvider = _authTokenProvider;
108@synthesize initialMetadata = _initialMetadata;
109@synthesize userAgentPrefix = _userAgentPrefix;
110@synthesize userAgentSuffix = _userAgentSuffix;
111@synthesize responseSizeLimit = _responseSizeLimit;
112@synthesize compressionAlgorithm = _compressionAlgorithm;
113@synthesize retryEnabled = _retryEnabled;
114@synthesize maxRetryInterval = _maxRetryInterval;
115@synthesize minRetryInterval = _minRetryInterval;
116@synthesize retryFactor = _retryFactor;
117@synthesize keepaliveInterval = _keepaliveInterval;
118@synthesize keepaliveTimeout = _keepaliveTimeout;
119@synthesize connectMinTimeout = _connectMinTimeout;
120@synthesize connectInitialBackoff = _connectInitialBackoff;
121@synthesize connectMaxBackoff = _connectMaxBackoff;
122@synthesize additionalChannelArgs = _additionalChannelArgs;
123@synthesize PEMRootCertificates = _PEMRootCertificates;
124@synthesize PEMPrivateKey = _PEMPrivateKey;
125@synthesize PEMCertificateChain = _PEMCertificateChain;
126@synthesize transportType = _transportType;
127@synthesize transport = _transport;
128@synthesize hostNameOverride = _hostNameOverride;
129@synthesize logContext = _logContext;
130@synthesize channelPoolDomain = _channelPoolDomain;
131@synthesize channelID = _channelID;
132
133- (instancetype)init {
134  return [self initWithServerAuthority:kDefaultServerAuthority
135                               timeout:kDefaultTimeout
136                    flowControlEnabled:kDefaultFlowControlEnabled
137                  interceptorFactories:kDefaultInterceptorFactories
138                     oauth2AccessToken:kDefaultOauth2AccessToken
139                     authTokenProvider:kDefaultAuthTokenProvider
140                       initialMetadata:kDefaultInitialMetadata
141                       userAgentPrefix:kDefaultUserAgentPrefix
142                       userAgentSuffix:kDefaultUserAgentSuffix
143                     responseSizeLimit:kDefaultResponseSizeLimit
144                  compressionAlgorithm:kDefaultCompressionAlgorithm
145                          retryEnabled:kDefaultRetryEnabled
146                      maxRetryInterval:kDefaultMaxRetryInterval
147                      minRetryInterval:kDefaultMinRetryInterval
148                           retryFactor:kDefaultRetryFactor
149                     keepaliveInterval:kDefaultKeepaliveInterval
150                      keepaliveTimeout:kDefaultKeepaliveTimeout
151                     connectMinTimeout:kDefaultConnectMinTimeout
152                 connectInitialBackoff:kDefaultConnectInitialBackoff
153                     connectMaxBackoff:kDefaultConnectMaxBackoff
154                 additionalChannelArgs:kDefaultAdditionalChannelArgs
155                   PEMRootCertificates:kDefaultPEMRootCertificates
156                         PEMPrivateKey:kDefaultPEMPrivateKey
157                   PEMCertificateChain:kDefaultPEMCertificateChain
158                         transportType:kDefaultTransportType
159                             transport:kDefaultTransport
160                      hostNameOverride:kDefaultHostNameOverride
161                            logContext:kDefaultLogContext
162                     channelPoolDomain:kDefaultChannelPoolDomain
163                             channelID:kDefaultChannelID];
164}
165
166- (instancetype)initWithServerAuthority:(NSString *)serverAuthority
167                                timeout:(NSTimeInterval)timeout
168                     flowControlEnabled:(BOOL)flowControlEnabled
169                   interceptorFactories:(NSArray<id<GRPCInterceptorFactory>> *)interceptorFactories
170                      oauth2AccessToken:(NSString *)oauth2AccessToken
171                      authTokenProvider:(id<GRPCAuthorizationProtocol>)authTokenProvider
172                        initialMetadata:(GRPCMetadataDictionary *)initialMetadata
173                        userAgentPrefix:(NSString *)userAgentPrefix
174                        userAgentSuffix:(NSString *)userAgentSuffix
175                      responseSizeLimit:(NSUInteger)responseSizeLimit
176                   compressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm
177                           retryEnabled:(BOOL)retryEnabled
178                       maxRetryInterval:(NSTimeInterval)maxRetryInterval
179                       minRetryInterval:(NSTimeInterval)minRetryInterval
180                            retryFactor:(double)retryFactor
181                      keepaliveInterval:(NSTimeInterval)keepaliveInterval
182                       keepaliveTimeout:(NSTimeInterval)keepaliveTimeout
183                      connectMinTimeout:(NSTimeInterval)connectMinTimeout
184                  connectInitialBackoff:(NSTimeInterval)connectInitialBackoff
185                      connectMaxBackoff:(NSTimeInterval)connectMaxBackoff
186                  additionalChannelArgs:(GRPCMetadataDictionary *)additionalChannelArgs
187                    PEMRootCertificates:(NSString *)PEMRootCertificates
188                          PEMPrivateKey:(NSString *)PEMPrivateKey
189                    PEMCertificateChain:(NSString *)PEMCertificateChain
190                          transportType:(GRPCTransportType)transportType
191                              transport:(GRPCTransportID)transport
192                       hostNameOverride:(NSString *)hostNameOverride
193                             logContext:(id)logContext
194                      channelPoolDomain:(NSString *)channelPoolDomain
195                              channelID:(NSUInteger)channelID {
196  if ((self = [super init])) {
197    _serverAuthority = [serverAuthority copy];
198    _timeout = timeout < 0 ? 0 : timeout;
199    _flowControlEnabled = flowControlEnabled;
200    _interceptorFactories = interceptorFactories;
201    _oauth2AccessToken = [oauth2AccessToken copy];
202    _authTokenProvider = authTokenProvider;
203    _initialMetadata = initialMetadata == nil
204                           ? nil
205                           : [[NSDictionary alloc] initWithDictionary:initialMetadata
206                                                            copyItems:YES];
207    _userAgentPrefix = [userAgentPrefix copy];
208    _userAgentSuffix = [userAgentSuffix copy];
209    _responseSizeLimit = responseSizeLimit;
210    _compressionAlgorithm = compressionAlgorithm;
211    _retryEnabled = retryEnabled;
212    _maxRetryInterval = maxRetryInterval;
213    _minRetryInterval = minRetryInterval;
214    _retryFactor = retryFactor;
215    _keepaliveInterval = keepaliveInterval < 0 ? 0 : keepaliveInterval;
216    _keepaliveTimeout = keepaliveTimeout < 0 ? 0 : keepaliveTimeout;
217    _connectMinTimeout = connectMinTimeout < 0 ? 0 : connectMinTimeout;
218    _connectInitialBackoff = connectInitialBackoff < 0 ? 0 : connectInitialBackoff;
219    _connectMaxBackoff = connectMaxBackoff < 0 ? 0 : connectMaxBackoff;
220    _additionalChannelArgs = additionalChannelArgs == nil
221                                 ? nil
222                                 : [[NSDictionary alloc] initWithDictionary:additionalChannelArgs
223                                                                  copyItems:YES];
224    _PEMRootCertificates = [PEMRootCertificates copy];
225    _PEMPrivateKey = [PEMPrivateKey copy];
226    _PEMCertificateChain = [PEMCertificateChain copy];
227    _transportType = transportType;
228    _transport = transport;
229    _hostNameOverride = [hostNameOverride copy];
230    _logContext = logContext;
231    _channelPoolDomain = [channelPoolDomain copy];
232    _channelID = channelID;
233  }
234  return self;
235}
236
237- (nonnull id)copyWithZone:(NSZone *)zone {
238  GRPCCallOptions *newOptions =
239      [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
240                                                            timeout:_timeout
241                                                 flowControlEnabled:_flowControlEnabled
242                                               interceptorFactories:_interceptorFactories
243                                                  oauth2AccessToken:_oauth2AccessToken
244                                                  authTokenProvider:_authTokenProvider
245                                                    initialMetadata:_initialMetadata
246                                                    userAgentPrefix:_userAgentPrefix
247                                                    userAgentSuffix:_userAgentSuffix
248                                                  responseSizeLimit:_responseSizeLimit
249                                               compressionAlgorithm:_compressionAlgorithm
250                                                       retryEnabled:_retryEnabled
251                                                   maxRetryInterval:_maxRetryInterval
252                                                   minRetryInterval:_minRetryInterval
253                                                        retryFactor:_retryFactor
254                                                  keepaliveInterval:_keepaliveInterval
255                                                   keepaliveTimeout:_keepaliveTimeout
256                                                  connectMinTimeout:_connectMinTimeout
257                                              connectInitialBackoff:_connectInitialBackoff
258                                                  connectMaxBackoff:_connectMaxBackoff
259                                              additionalChannelArgs:_additionalChannelArgs
260                                                PEMRootCertificates:_PEMRootCertificates
261                                                      PEMPrivateKey:_PEMPrivateKey
262                                                PEMCertificateChain:_PEMCertificateChain
263                                                      transportType:_transportType
264                                                          transport:_transport
265                                                   hostNameOverride:_hostNameOverride
266                                                         logContext:_logContext
267                                                  channelPoolDomain:_channelPoolDomain
268                                                          channelID:_channelID];
269  return newOptions;
270}
271
272- (nonnull id)mutableCopyWithZone:(NSZone *)zone {
273  GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
274      initWithServerAuthority:[_serverAuthority copy]
275                      timeout:_timeout
276           flowControlEnabled:_flowControlEnabled
277         interceptorFactories:_interceptorFactories
278            oauth2AccessToken:[_oauth2AccessToken copy]
279            authTokenProvider:_authTokenProvider
280              initialMetadata:[[NSDictionary alloc] initWithDictionary:_initialMetadata
281                                                             copyItems:YES]
282              userAgentPrefix:[_userAgentPrefix copy]
283              userAgentSuffix:[_userAgentSuffix copy]
284            responseSizeLimit:_responseSizeLimit
285         compressionAlgorithm:_compressionAlgorithm
286                 retryEnabled:_retryEnabled
287             maxRetryInterval:_maxRetryInterval
288             minRetryInterval:_minRetryInterval
289                  retryFactor:_retryFactor
290            keepaliveInterval:_keepaliveInterval
291             keepaliveTimeout:_keepaliveTimeout
292            connectMinTimeout:_connectMinTimeout
293        connectInitialBackoff:_connectInitialBackoff
294            connectMaxBackoff:_connectMaxBackoff
295        additionalChannelArgs:[[NSDictionary alloc] initWithDictionary:_additionalChannelArgs
296                                                             copyItems:YES]
297          PEMRootCertificates:[_PEMRootCertificates copy]
298                PEMPrivateKey:[_PEMPrivateKey copy]
299          PEMCertificateChain:[_PEMCertificateChain copy]
300                transportType:_transportType
301                    transport:_transport
302             hostNameOverride:[_hostNameOverride copy]
303                   logContext:_logContext
304            channelPoolDomain:[_channelPoolDomain copy]
305                    channelID:_channelID];
306  return newOptions;
307}
308
309- (BOOL)hasChannelOptionsEqualTo:(GRPCCallOptions *)callOptions {
310  if (callOptions == nil) return NO;
311  if (!areObjectsEqual(callOptions.userAgentPrefix, _userAgentPrefix)) return NO;
312  if (!areObjectsEqual(callOptions.userAgentSuffix, _userAgentSuffix)) return NO;
313  if (!(callOptions.responseSizeLimit == _responseSizeLimit)) return NO;
314  if (!(callOptions.compressionAlgorithm == _compressionAlgorithm)) return NO;
315  if (!(callOptions.retryEnabled == _retryEnabled)) return NO;
316  if (!(callOptions.maxRetryInterval == _maxRetryInterval)) return NO;
317  if (!(callOptions.minRetryInterval == _minRetryInterval)) return NO;
318  if (!(callOptions.retryFactor == _retryFactor)) return NO;
319  if (!(callOptions.keepaliveInterval == _keepaliveInterval)) return NO;
320  if (!(callOptions.keepaliveTimeout == _keepaliveTimeout)) return NO;
321  if (!(callOptions.connectMinTimeout == _connectMinTimeout)) return NO;
322  if (!(callOptions.connectInitialBackoff == _connectInitialBackoff)) return NO;
323  if (!(callOptions.connectMaxBackoff == _connectMaxBackoff)) return NO;
324  if (!areObjectsEqual(callOptions.additionalChannelArgs, _additionalChannelArgs)) return NO;
325  if (!areObjectsEqual(callOptions.PEMRootCertificates, _PEMRootCertificates)) return NO;
326  if (!areObjectsEqual(callOptions.PEMPrivateKey, _PEMPrivateKey)) return NO;
327  if (!areObjectsEqual(callOptions.PEMCertificateChain, _PEMCertificateChain)) return NO;
328  if (!areObjectsEqual(callOptions.hostNameOverride, _hostNameOverride)) return NO;
329  if (!(callOptions.transportType == _transportType)) return NO;
330  if (!(TransportIDIsEqual(callOptions.transport, _transport))) return NO;
331  if (!areObjectsEqual(callOptions.logContext, _logContext)) return NO;
332  if (!areObjectsEqual(callOptions.channelPoolDomain, _channelPoolDomain)) return NO;
333  if (!(callOptions.channelID == _channelID)) return NO;
334
335  return YES;
336}
337
338- (NSUInteger)channelOptionsHash {
339  NSUInteger result = 0;
340  result ^= _userAgentPrefix.hash;
341  result ^= _userAgentSuffix.hash;
342  result ^= _responseSizeLimit;
343  result ^= _compressionAlgorithm;
344  result ^= _retryEnabled;
345  result ^= (unsigned int)(_keepaliveInterval * 1000);
346  result ^= (unsigned int)(_keepaliveTimeout * 1000);
347  result ^= (unsigned int)(_connectMinTimeout * 1000);
348  result ^= (unsigned int)(_connectInitialBackoff * 1000);
349  result ^= (unsigned int)(_connectMaxBackoff * 1000);
350  result ^= _additionalChannelArgs.hash;
351  result ^= _PEMRootCertificates.hash;
352  result ^= _PEMPrivateKey.hash;
353  result ^= _PEMCertificateChain.hash;
354  result ^= _hostNameOverride.hash;
355  result ^= _transportType;
356  result ^= TransportIDHash(_transport);
357  result ^= _logContext.hash;
358  result ^= _channelPoolDomain.hash;
359  result ^= _channelID;
360
361  return result;
362}
363
364@end
365
366@implementation GRPCMutableCallOptions
367
368@dynamic serverAuthority;
369@dynamic timeout;
370@dynamic flowControlEnabled;
371@dynamic interceptorFactories;
372@dynamic oauth2AccessToken;
373@dynamic authTokenProvider;
374@dynamic initialMetadata;
375@dynamic userAgentPrefix;
376@dynamic userAgentSuffix;
377@dynamic responseSizeLimit;
378@dynamic compressionAlgorithm;
379@dynamic retryEnabled;
380@dynamic maxRetryInterval;
381@dynamic minRetryInterval;
382@dynamic retryFactor;
383@dynamic keepaliveInterval;
384@dynamic keepaliveTimeout;
385@dynamic connectMinTimeout;
386@dynamic connectInitialBackoff;
387@dynamic connectMaxBackoff;
388@dynamic additionalChannelArgs;
389@dynamic PEMRootCertificates;
390@dynamic PEMPrivateKey;
391@dynamic PEMCertificateChain;
392@dynamic transportType;
393@dynamic transport;
394@dynamic hostNameOverride;
395@dynamic logContext;
396@dynamic channelPoolDomain;
397@dynamic channelID;
398
399- (instancetype)init {
400  return [self initWithServerAuthority:kDefaultServerAuthority
401                               timeout:kDefaultTimeout
402                    flowControlEnabled:kDefaultFlowControlEnabled
403                  interceptorFactories:kDefaultInterceptorFactories
404                     oauth2AccessToken:kDefaultOauth2AccessToken
405                     authTokenProvider:kDefaultAuthTokenProvider
406                       initialMetadata:kDefaultInitialMetadata
407                       userAgentPrefix:kDefaultUserAgentPrefix
408                       userAgentSuffix:kDefaultUserAgentSuffix
409                     responseSizeLimit:kDefaultResponseSizeLimit
410                  compressionAlgorithm:kDefaultCompressionAlgorithm
411                          retryEnabled:kDefaultRetryEnabled
412                      maxRetryInterval:kDefaultMaxRetryInterval
413                      minRetryInterval:kDefaultMinRetryInterval
414                           retryFactor:kDefaultRetryFactor
415                     keepaliveInterval:kDefaultKeepaliveInterval
416                      keepaliveTimeout:kDefaultKeepaliveTimeout
417                     connectMinTimeout:kDefaultConnectMinTimeout
418                 connectInitialBackoff:kDefaultConnectInitialBackoff
419                     connectMaxBackoff:kDefaultConnectMaxBackoff
420                 additionalChannelArgs:kDefaultAdditionalChannelArgs
421                   PEMRootCertificates:kDefaultPEMRootCertificates
422                         PEMPrivateKey:kDefaultPEMPrivateKey
423                   PEMCertificateChain:kDefaultPEMCertificateChain
424                         transportType:kDefaultTransportType
425                             transport:kDefaultTransport
426                      hostNameOverride:kDefaultHostNameOverride
427                            logContext:kDefaultLogContext
428                     channelPoolDomain:kDefaultChannelPoolDomain
429                             channelID:kDefaultChannelID];
430}
431
432- (nonnull id)copyWithZone:(NSZone *)zone {
433  GRPCCallOptions *newOptions =
434      [[GRPCCallOptions allocWithZone:zone] initWithServerAuthority:_serverAuthority
435                                                            timeout:_timeout
436                                                 flowControlEnabled:_flowControlEnabled
437                                               interceptorFactories:_interceptorFactories
438                                                  oauth2AccessToken:_oauth2AccessToken
439                                                  authTokenProvider:_authTokenProvider
440                                                    initialMetadata:_initialMetadata
441                                                    userAgentPrefix:_userAgentPrefix
442                                                    userAgentSuffix:_userAgentSuffix
443                                                  responseSizeLimit:_responseSizeLimit
444                                               compressionAlgorithm:_compressionAlgorithm
445                                                       retryEnabled:_retryEnabled
446                                                   maxRetryInterval:_maxRetryInterval
447                                                   minRetryInterval:_minRetryInterval
448                                                        retryFactor:_retryFactor
449                                                  keepaliveInterval:_keepaliveInterval
450                                                   keepaliveTimeout:_keepaliveTimeout
451                                                  connectMinTimeout:_connectMinTimeout
452                                              connectInitialBackoff:_connectInitialBackoff
453                                                  connectMaxBackoff:_connectMaxBackoff
454                                              additionalChannelArgs:_additionalChannelArgs
455                                                PEMRootCertificates:_PEMRootCertificates
456                                                      PEMPrivateKey:_PEMPrivateKey
457                                                PEMCertificateChain:_PEMCertificateChain
458                                                      transportType:_transportType
459                                                          transport:_transport
460                                                   hostNameOverride:_hostNameOverride
461                                                         logContext:_logContext
462                                                  channelPoolDomain:_channelPoolDomain
463                                                          channelID:_channelID];
464  return newOptions;
465}
466
467- (nonnull id)mutableCopyWithZone:(NSZone *)zone {
468  GRPCMutableCallOptions *newOptions = [[GRPCMutableCallOptions allocWithZone:zone]
469      initWithServerAuthority:_serverAuthority
470                      timeout:_timeout
471           flowControlEnabled:_flowControlEnabled
472         interceptorFactories:_interceptorFactories
473            oauth2AccessToken:_oauth2AccessToken
474            authTokenProvider:_authTokenProvider
475              initialMetadata:_initialMetadata
476              userAgentPrefix:_userAgentPrefix
477              userAgentSuffix:_userAgentSuffix
478            responseSizeLimit:_responseSizeLimit
479         compressionAlgorithm:_compressionAlgorithm
480                 retryEnabled:_retryEnabled
481             maxRetryInterval:_maxRetryInterval
482             minRetryInterval:_minRetryInterval
483                  retryFactor:_retryFactor
484            keepaliveInterval:_keepaliveInterval
485             keepaliveTimeout:_keepaliveTimeout
486            connectMinTimeout:_connectMinTimeout
487        connectInitialBackoff:_connectInitialBackoff
488            connectMaxBackoff:_connectMaxBackoff
489        additionalChannelArgs:[_additionalChannelArgs copy]
490          PEMRootCertificates:_PEMRootCertificates
491                PEMPrivateKey:_PEMPrivateKey
492          PEMCertificateChain:_PEMCertificateChain
493                transportType:_transportType
494                    transport:_transport
495             hostNameOverride:_hostNameOverride
496                   logContext:_logContext
497            channelPoolDomain:_channelPoolDomain
498                    channelID:_channelID];
499  return newOptions;
500}
501
502- (void)setServerAuthority:(NSString *)serverAuthority {
503  _serverAuthority = [serverAuthority copy];
504}
505
506- (void)setTimeout:(NSTimeInterval)timeout {
507  if (timeout < 0) {
508    _timeout = 0;
509  } else {
510    _timeout = timeout;
511  }
512}
513
514- (void)setFlowControlEnabled:(BOOL)flowControlEnabled {
515  _flowControlEnabled = flowControlEnabled;
516}
517
518- (void)setInterceptorFactories:(NSArray<id<GRPCInterceptorFactory>> *)interceptorFactories {
519  _interceptorFactories = interceptorFactories;
520}
521
522- (void)setOauth2AccessToken:(NSString *)oauth2AccessToken {
523  _oauth2AccessToken = [oauth2AccessToken copy];
524}
525
526- (void)setAuthTokenProvider:(id<GRPCAuthorizationProtocol>)authTokenProvider {
527  _authTokenProvider = authTokenProvider;
528}
529
530- (void)setInitialMetadata:(GRPCMetadataDictionary *)initialMetadata {
531  _initialMetadata = [[NSDictionary alloc] initWithDictionary:initialMetadata copyItems:YES];
532}
533
534- (void)setUserAgentPrefix:(NSString *)userAgentPrefix {
535  _userAgentPrefix = [userAgentPrefix copy];
536}
537
538- (void)setUserAgentSuffix:(NSString *)userAgentSuffix {
539  _userAgentSuffix = [userAgentSuffix copy];
540}
541
542- (void)setResponseSizeLimit:(NSUInteger)responseSizeLimit {
543  _responseSizeLimit = responseSizeLimit;
544}
545
546- (void)setCompressionAlgorithm:(GRPCCompressionAlgorithm)compressionAlgorithm {
547  _compressionAlgorithm = compressionAlgorithm;
548}
549
550- (void)setRetryEnabled:(BOOL)retryEnabled {
551  _retryEnabled = retryEnabled;
552}
553
554- (void)setMaxRetryInterval:(NSTimeInterval)maxRetryInterval {
555  _maxRetryInterval = maxRetryInterval;
556}
557
558- (void)setMinRetryInterval:(NSTimeInterval)minRetryInterval {
559  _minRetryInterval = minRetryInterval;
560}
561
562- (void)setRetryFactor:(double)retryFactor {
563  _retryFactor = retryFactor;
564}
565
566- (void)setKeepaliveInterval:(NSTimeInterval)keepaliveInterval {
567  if (keepaliveInterval < 0) {
568    _keepaliveInterval = 0;
569  } else {
570    _keepaliveInterval = keepaliveInterval;
571  }
572}
573
574- (void)setKeepaliveTimeout:(NSTimeInterval)keepaliveTimeout {
575  if (keepaliveTimeout < 0) {
576    _keepaliveTimeout = 0;
577  } else {
578    _keepaliveTimeout = keepaliveTimeout;
579  }
580}
581
582- (void)setConnectMinTimeout:(NSTimeInterval)connectMinTimeout {
583  if (connectMinTimeout < 0) {
584    _connectMinTimeout = 0;
585  } else {
586    _connectMinTimeout = connectMinTimeout;
587  }
588}
589
590- (void)setConnectInitialBackoff:(NSTimeInterval)connectInitialBackoff {
591  if (connectInitialBackoff < 0) {
592    _connectInitialBackoff = 0;
593  } else {
594    _connectInitialBackoff = connectInitialBackoff;
595  }
596}
597
598- (void)setConnectMaxBackoff:(NSTimeInterval)connectMaxBackoff {
599  if (connectMaxBackoff < 0) {
600    _connectMaxBackoff = 0;
601  } else {
602    _connectMaxBackoff = connectMaxBackoff;
603  }
604}
605
606- (void)setAdditionalChannelArgs:(GRPCMetadataDictionary *)additionalChannelArgs {
607  _additionalChannelArgs = [[NSDictionary alloc] initWithDictionary:additionalChannelArgs
608                                                          copyItems:YES];
609}
610
611- (void)setPEMRootCertificates:(NSString *)PEMRootCertificates {
612  _PEMRootCertificates = [PEMRootCertificates copy];
613}
614
615- (void)setPEMPrivateKey:(NSString *)PEMPrivateKey {
616  _PEMPrivateKey = [PEMPrivateKey copy];
617}
618
619- (void)setPEMCertificateChain:(NSString *)PEMCertificateChain {
620  _PEMCertificateChain = [PEMCertificateChain copy];
621}
622
623- (void)setTransportType:(GRPCTransportType)transportType {
624  _transportType = transportType;
625}
626
627- (void)setTransport:(GRPCTransportID)transport {
628  _transport = transport;
629}
630
631- (void)setHostNameOverride:(NSString *)hostNameOverride {
632  _hostNameOverride = [hostNameOverride copy];
633}
634
635- (void)setLogContext:(id)logContext {
636  _logContext = logContext;
637}
638
639- (void)setChannelPoolDomain:(NSString *)channelPoolDomain {
640  _channelPoolDomain = [channelPoolDomain copy];
641}
642
643- (void)setChannelID:(NSUInteger)channelID {
644  _channelID = channelID;
645}
646
647@end
648