Merge pull request #9 from saicheems/update

Update to reflect codegen
diff --git a/call_option.go b/call_option.go
index 3f0e3f6..d7dfa2b 100644
--- a/call_option.go
+++ b/call_option.go
@@ -7,47 +7,57 @@
 )
 
 type CallOption interface {
-	resolve(*callSettings)
+	Resolve(*CallSettings)
 }
 
 type callOptions []CallOption
 
-func (opts callOptions) resolve(s *callSettings) *callSettings {
+func (opts callOptions) Resolve(s *CallSettings) *CallSettings {
 	for _, opt := range opts {
-		opt.resolve(s)
+		opt.Resolve(s)
 	}
 	return s
 }
 
 // Encapsulates the call settings for a particular API call.
-type callSettings struct {
-	timeout       time.Duration
-	retrySettings retrySettings
+type CallSettings struct {
+	Timeout       time.Duration
+	RetrySettings RetrySettings
 }
 
 // Per-call configurable settings for retrying upon transient failure.
-type retrySettings struct {
-	retryCodes      map[codes.Code]bool
-	backoffSettings backoffSettings
+type RetrySettings struct {
+	RetryCodes      map[codes.Code]bool
+	BackoffSettings BackoffSettings
 }
 
 // Parameters to the exponential backoff algorithm for retrying.
-type backoffSettings struct {
-	delayTimeoutSettings multipliableDuration
-	rpcTimeoutSettings   multipliableDuration
-	totalTimeout         time.Duration
+type BackoffSettings struct {
+	DelayTimeoutSettings MultipliableDuration
+	RPCTimeoutSettings   MultipliableDuration
+	TotalTimeout         time.Duration
 }
 
-type multipliableDuration struct {
-	initial    time.Duration
-	max        time.Duration
-	multiplier float64
+type MultipliableDuration struct {
+	Initial    time.Duration
+	Max        time.Duration
+	Multiplier float64
+}
+
+func (w CallSettings) Resolve(s *CallSettings) {
+	s.Timeout = w.Timeout
+	s.RetrySettings = w.RetrySettings
+
+	s.RetrySettings.RetryCodes = make(map[codes.Code]bool, len(w.RetrySettings.RetryCodes))
+	for key, value := range w.RetrySettings.RetryCodes {
+		s.RetrySettings.RetryCodes[key] = value
+	}
 }
 
 type withTimeout time.Duration
 
-func (w withTimeout) resolve(s *callSettings) {
-	s.timeout = time.Duration(w)
+func (w withTimeout) Resolve(s *CallSettings) {
+	s.Timeout = time.Duration(w)
 }
 
 // WithTimeout sets the client-side timeout for API calls if the call isn't
@@ -58,10 +68,10 @@
 
 type withRetryCodes []codes.Code
 
-func (w withRetryCodes) resolve(s *callSettings) {
-	s.retrySettings.retryCodes = make(map[codes.Code]bool)
+func (w withRetryCodes) Resolve(s *CallSettings) {
+	s.RetrySettings.RetryCodes = make(map[codes.Code]bool)
 	for _, code := range []codes.Code(w) {
-		s.retrySettings.retryCodes[code] = true
+		s.RetrySettings.RetryCodes[code] = true
 	}
 }
 
@@ -71,10 +81,10 @@
 	return withRetryCodes(retryCodes)
 }
 
-type withDelayTimeoutSettings multipliableDuration
+type withDelayTimeoutSettings MultipliableDuration
 
-func (w withDelayTimeoutSettings) resolve(s *callSettings) {
-	s.retrySettings.backoffSettings.delayTimeoutSettings = multipliableDuration(w)
+func (w withDelayTimeoutSettings) Resolve(s *CallSettings) {
+	s.RetrySettings.BackoffSettings.DelayTimeoutSettings = MultipliableDuration(w)
 }
 
 // WithDelayTimeoutSettings specifies:
@@ -88,13 +98,13 @@
 //   value is reached, `RetryDelayMultiplier` will no longer be used to
 //   increase delay time.
 func WithDelayTimeoutSettings(initial time.Duration, max time.Duration, multiplier float64) CallOption {
-	return withDelayTimeoutSettings(multipliableDuration{initial, max, multiplier})
+	return withDelayTimeoutSettings(MultipliableDuration{initial, max, multiplier})
 }
 
-type withRPCTimeoutSettings multipliableDuration
+type withRPCTimeoutSettings MultipliableDuration
 
-func (w withRPCTimeoutSettings) resolve(s *callSettings) {
-	s.retrySettings.backoffSettings.rpcTimeoutSettings = multipliableDuration(w)
+func (w withRPCTimeoutSettings) Resolve(s *CallSettings) {
+	s.RetrySettings.BackoffSettings.RPCTimeoutSettings = MultipliableDuration(w)
 }
 
 // WithRPCTimeoutSettings specifies:
@@ -105,13 +115,13 @@
 //   this value is reached, `RPCTimeoutMultiplier` will no longer be used
 //   to increase the timeout.
 func WithRPCTimeoutSettings(initial time.Duration, max time.Duration, multiplier float64) CallOption {
-	return withRPCTimeoutSettings(multipliableDuration{initial, max, multiplier})
+	return withRPCTimeoutSettings(MultipliableDuration{initial, max, multiplier})
 }
 
 type withTotalRetryTimeout time.Duration
 
-func (w withTotalRetryTimeout) resolve(s *callSettings) {
-	s.retrySettings.backoffSettings.totalTimeout = time.Duration(w)
+func (w withTotalRetryTimeout) Resolve(s *CallSettings) {
+	s.RetrySettings.BackoffSettings.TotalTimeout = time.Duration(w)
 }
 
 // WithTotalRetryTimeout sets the total time, in milliseconds, starting from
diff --git a/call_option_test.go b/call_option_test.go
index 6d4190b..190221f 100644
--- a/call_option_test.go
+++ b/call_option_test.go
@@ -8,20 +8,20 @@
 	"google.golang.org/grpc/codes"
 )
 
-func TestCallOptionsPieceByPiece(t *testing.T) {
-	expected := &callSettings{
+func TestCallOptions(t *testing.T) {
+	expected := &CallSettings{
 		time.Second * 1,
-		retrySettings{
+		RetrySettings{
 			map[codes.Code]bool{codes.Unavailable: true, codes.DeadlineExceeded: true},
-			backoffSettings{
-				multipliableDuration{time.Second * 2, time.Second * 4, 3.0},
-				multipliableDuration{time.Second * 5, time.Second * 7, 6.0},
+			BackoffSettings{
+				MultipliableDuration{time.Second * 2, time.Second * 4, 3.0},
+				MultipliableDuration{time.Second * 5, time.Second * 7, 6.0},
 				time.Second * 8,
 			},
 		},
 	}
 
-	settings := &callSettings{}
+	settings := &CallSettings{}
 	opts := []CallOption{
 		WithTimeout(time.Second * 1),
 		WithRetryCodes([]codes.Code{codes.Unavailable, codes.DeadlineExceeded}),
@@ -29,9 +29,21 @@
 		WithRPCTimeoutSettings(time.Second*5, time.Second*7, 6.0),
 		WithTotalRetryTimeout(time.Second * 8),
 	}
-	callOptions(opts).resolve(settings)
+	callOptions(opts).Resolve(settings)
 
 	if !reflect.DeepEqual(settings, expected) {
-		t.Errorf("settings don't match their expected configuration")
+		t.Errorf("piece-by-piece settings don't match their expected configuration")
+	}
+
+	settings = &CallSettings{}
+	expected.Resolve(settings)
+
+	if !reflect.DeepEqual(settings, expected) {
+		t.Errorf("whole settings don't match their expected configuration")
+	}
+
+	expected.RetrySettings.RetryCodes[codes.FailedPrecondition] = true
+	if _, ok := settings.RetrySettings.RetryCodes[codes.FailedPrecondition]; ok {
+		t.Errorf("unexpected modification in the RetryCodes map")
 	}
 }
diff --git a/client_option.go b/client_option.go
index b03544d..10ccc98 100644
--- a/client_option.go
+++ b/client_option.go
@@ -1,29 +1,36 @@
 package gax
 
 type ClientOption interface {
-	resolve(*clientSettings)
+	Resolve(*ClientSettings)
 }
 
 type clientOptions []ClientOption
 
-func (opts clientOptions) resolve(s *clientSettings) *clientSettings {
+func (opts clientOptions) Resolve(s *ClientSettings) *ClientSettings {
 	for _, opt := range opts {
-		opt.resolve(s)
+		opt.Resolve(s)
 	}
 	return s
 }
 
-type clientSettings struct {
-	apiName    string
-	apiVersion string
-	endpoint   string
-	scopes     []string
+type ClientSettings struct {
+	APIName    string
+	APIVersion string
+	Endpoint   string
+	Scopes     []string
+}
+
+func (w ClientSettings) Resolve(s *ClientSettings) {
+	s.APIName = w.APIName
+	s.APIVersion = w.APIVersion
+	s.Endpoint = w.Endpoint
+	s.Scopes = append([]string{}, w.Scopes...)
 }
 
 type withAPIName string
 
-func (w withAPIName) resolve(s *clientSettings) {
-	s.apiName = string(w)
+func (w withAPIName) Resolve(s *ClientSettings) {
+	s.APIName = string(w)
 }
 
 func WithAPIName(apiName string) ClientOption {
@@ -32,8 +39,8 @@
 
 type withAPIVersion string
 
-func (w withAPIVersion) resolve(s *clientSettings) {
-	s.apiVersion = string(w)
+func (w withAPIVersion) Resolve(s *ClientSettings) {
+	s.APIVersion = string(w)
 }
 
 func WithAPIVersion(apiVersion string) ClientOption {
@@ -42,8 +49,8 @@
 
 type withEndpoint string
 
-func (w withEndpoint) resolve(s *clientSettings) {
-	s.endpoint = string(w)
+func (w withEndpoint) Resolve(s *ClientSettings) {
+	s.Endpoint = string(w)
 }
 
 func WithEndpoint(endpoint string) ClientOption {
@@ -52,8 +59,8 @@
 
 type withScopes []string
 
-func (w withScopes) resolve(s *clientSettings) {
-	s.scopes = append(s.scopes[:0], w...)
+func (w withScopes) Resolve(s *ClientSettings) {
+	s.Scopes = append(s.Scopes[:0], w...)
 }
 
 func WithScopes(scopes ...string) ClientOption {
diff --git a/client_option_test.go b/client_option_test.go
index 35710ec..2394054 100644
--- a/client_option_test.go
+++ b/client_option_test.go
@@ -6,23 +6,35 @@
 )
 
 func TestClientOptionsPieceByPiece(t *testing.T) {
-	expected := &clientSettings{
+	expected := &ClientSettings{
 		"myapi",
 		"v0.1.0",
 		"https://example.com:443",
 		[]string{"https://example.com/auth/helloworld", "https://example.com/auth/otherthing"},
 	}
 
-	settings := &clientSettings{}
+	settings := &ClientSettings{}
 	opts := []ClientOption{
 		WithAPIName("myapi"),
 		WithAPIVersion("v0.1.0"),
 		WithEndpoint("https://example.com:443"),
 		WithScopes("https://example.com/auth/helloworld", "https://example.com/auth/otherthing"),
 	}
-	clientOptions(opts).resolve(settings)
+	clientOptions(opts).Resolve(settings)
 
 	if !reflect.DeepEqual(settings, expected) {
-		t.Errorf("settings don't match their expected configuration")
+		t.Errorf("piece-by-piece settings don't match their expected configuration")
+	}
+
+	settings = &ClientSettings{}
+	expected.Resolve(settings)
+
+	if !reflect.DeepEqual(settings, expected) {
+		t.Errorf("whole settings don't match their expected configuration")
+	}
+
+	expected.Scopes[0] = "hello"
+	if settings.Scopes[0] == expected.Scopes[0] {
+		t.Errorf("unexpected modification in Scopes array")
 	}
 }
diff --git a/dial.go b/dial.go
index 336be35..0927eb4 100644
--- a/dial.go
+++ b/dial.go
@@ -11,10 +11,10 @@
 )
 
 func DialGRPC(ctx context.Context, opts ...ClientOption) (*grpc.ClientConn, error) {
-	settings := &clientSettings{}
-	clientOptions(opts).resolve(settings)
+	settings := &ClientSettings{}
+	clientOptions(opts).Resolve(settings)
 
-	tokenSource, err := google.DefaultTokenSource(ctx, settings.scopes...)
+	tokenSource, err := google.DefaultTokenSource(ctx, settings.Scopes...)
 	if err != nil {
 		return nil, fmt.Errorf("google.DefaultTokenSource: %v", err)
 	}
@@ -22,5 +22,5 @@
 		grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: tokenSource}),
 		grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")),
 	}
-	return grpc.Dial(settings.endpoint, grpcOpts...)
+	return grpc.Dial(settings.Endpoint, grpcOpts...)
 }
diff --git a/invoke.go b/invoke.go
index 86841a3..7a368f0 100644
--- a/invoke.go
+++ b/invoke.go
@@ -19,33 +19,33 @@
 
 // invokeWithRetry calls stub using an exponential backoff retry mechanism
 // based on the values provided in retrySettings.
-func invokeWithRetry(ctx context.Context, stub APICall, retrySettings retrySettings) error {
-	backoffSettings := retrySettings.backoffSettings
+func invokeWithRetry(ctx context.Context, stub APICall, retrySettings RetrySettings) error {
+	backoffSettings := retrySettings.BackoffSettings
 	// Forces ctx to expire after a deadline.
-	childCtx, _ := context.WithTimeout(ctx, backoffSettings.totalTimeout)
-	delay := backoffSettings.delayTimeoutSettings.initial
-	timeout := backoffSettings.rpcTimeoutSettings.initial
+	childCtx, _ := context.WithTimeout(ctx, backoffSettings.TotalTimeout)
+	delay := backoffSettings.DelayTimeoutSettings.Initial
+	timeout := backoffSettings.RPCTimeoutSettings.Initial
 	for {
 		// If the deadline is exceeded...
 		if childCtx.Err() != nil {
 			return childCtx.Err()
 		}
-		timeoutCtx, _ := context.WithTimeout(childCtx, backoffSettings.rpcTimeoutSettings.max)
+		timeoutCtx, _ := context.WithTimeout(childCtx, backoffSettings.RPCTimeoutSettings.Max)
 		timeoutCtx, _ = context.WithTimeout(timeoutCtx, timeout)
 		err := stub(timeoutCtx)
 		code := grpc.Code(err)
 		if code == codes.OK {
 			return nil
 		}
-		if !retrySettings.retryCodes[code] {
+		if !retrySettings.RetryCodes[code] {
 			return err
 		}
-		delayCtx, _ := context.WithTimeout(childCtx, backoffSettings.delayTimeoutSettings.max)
+		delayCtx, _ := context.WithTimeout(childCtx, backoffSettings.DelayTimeoutSettings.Max)
 		delayCtx, _ = context.WithTimeout(delayCtx, delay)
 		<-delayCtx.Done()
 
-		delay = scaleDuration(delay, backoffSettings.delayTimeoutSettings.multiplier)
-		timeout = scaleDuration(timeout, backoffSettings.rpcTimeoutSettings.multiplier)
+		delay = scaleDuration(delay, backoffSettings.DelayTimeoutSettings.Multiplier)
+		timeout = scaleDuration(timeout, backoffSettings.RPCTimeoutSettings.Multiplier)
 	}
 }
 
@@ -57,10 +57,10 @@
 
 // Invoke calls stub with a child of context modified by the specified options.
 func Invoke(ctx context.Context, stub APICall, opts ...CallOption) error {
-	settings := &callSettings{}
-	callOptions(opts).resolve(settings)
-	if len(settings.retrySettings.retryCodes) > 0 {
-		return invokeWithRetry(ctx, stub, settings.retrySettings)
+	settings := &CallSettings{}
+	callOptions(opts).Resolve(settings)
+	if len(settings.RetrySettings.RetryCodes) > 0 {
+		return invokeWithRetry(ctx, stub, settings.RetrySettings)
 	}
-	return invokeWithTimeout(ctx, stub, settings.timeout)
+	return invokeWithTimeout(ctx, stub, settings.Timeout)
 }