Copyright 2015 Google LLC. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Package grpc supports network connections to GRPC servers. This package is not intended for use by end developers. Use the google.golang.org/api/option package to configure API clients.
package grpc

import (
	
	
	
	
	

	
	
	
	
	
	
	grpcgoogle 
	
Install grpclb, which is required for direct path.
	_ 
)
Set at init time by dial_appengine.go. If nil, we're not on App Engine.
Set at init time by dial_socketopt.go. If nil, socketopt is not supported.
Dial returns a GRPC connection for use communicating with a Google cloud service, configured with the given ClientOptions.
func ( context.Context,  ...option.ClientOption) (*grpc.ClientConn, error) {
	,  := processAndValidateOpts()
	if  != nil {
		return nil, 
	}
	if .GRPCConnPool != nil {
		return .GRPCConnPool.Conn(), nil
NOTE(cbro): We removed support for option.WithGRPCConnPool (GRPCConnPoolSize) on 2020-02-12 because RoundRobin and WithBalancer are deprecated and we need to remove usages of it. Connection pooling is only done via DialPool.
	return dial(, false, )
}
DialInsecure returns an insecure GRPC connection for use communicating with fake or mock Google cloud service implementations, such as emulators. The connection is configured with the given ClientOptions.
func ( context.Context,  ...option.ClientOption) (*grpc.ClientConn, error) {
	,  := processAndValidateOpts()
	if  != nil {
		return nil, 
	}
	return dial(, true, )
}
DialPool returns a pool of GRPC connections for the given service. This differs from the connection pooling implementation used by Dial, which uses a custom GRPC load balancer. DialPool should be used instead of Dial when a pool is used by default or a different custom GRPC load balancer is needed. The context and options are shared between each Conn in the pool. The pool size is configured using the WithGRPCConnectionPool option. This API is subject to change as we further refine requirements. It will go away if gRPC stubs accept an interface instead of the concrete ClientConn type. See https://github.com/grpc/grpc-go/issues/1287.
func ( context.Context,  ...option.ClientOption) (ConnPool, error) {
	,  := processAndValidateOpts()
	if  != nil {
		return nil, 
	}
	if .GRPCConnPool != nil {
		return .GRPCConnPool, nil
	}
	 := .GRPCConnPoolSize
WithGRPCConn is technically incompatible with WithGRPCConnectionPool. Always assume pool size is 1 when a grpc.ClientConn is explicitly used.
		 = 1
	}
	.GRPCConnPoolSize = 0 // we don't *need* to set this to zero, but it's safe to.

Fast path for common case for a connection pool with a single connection.
		,  := dial(, false, )
		if  != nil {
			return nil, 
		}
		return &singleConnPool{}, nil
	}

	 := &roundRobinConnPool{}
	for  := 0;  < ; ++ {
		,  := dial(, false, )
		if  != nil {
			defer .Close() // NOTE: error from Close is ignored.
			return nil, 
		}
		.conns = append(.conns, )
	}
	return , nil
}

func ( context.Context,  bool,  *internal.DialSettings) (*grpc.ClientConn, error) {
	if .HTTPClient != nil {
		return nil, errors.New("unsupported HTTP client specified")
	}
	if .GRPCConn != nil {
		return .GRPCConn, nil
	}
	var  []grpc.DialOption
	if  {
		 = []grpc.DialOption{grpc.WithInsecure()}
	} else if !.NoAuth {
		if .APIKey != "" {
			log.Print("API keys are not supported for gRPC APIs. Remove the WithAPIKey option from your client-creating call.")
		}
		,  := internal.Creds(, )
		if  != nil {
			return nil, 
		}

		if .QuotaProject == "" {
			.QuotaProject = internal.QuotaProjectFromCreds()
		}
Attempt Direct Path only if: * The endpoint is a host:port (or dns:///host:port). * Credentials are obtained via GCE metadata server, using the default service account. * Opted in via GOOGLE_CLOUD_ENABLE_DIRECT_PATH environment variable. For example, GOOGLE_CLOUD_ENABLE_DIRECT_PATH=spanner,pubsub
For now all DirectPath go clients will be using the following lb config, but in future when different services need different configs, then we should change this to a per-service config.
				grpc.WithDisableServiceConfig(),
				grpc.WithDefaultServiceConfig(`{"loadBalancingConfig":[{"grpclb":{"childPolicy":[{"pick_first":{}}]}}]}`),
TODO(cbro): add support for system parameters (quota project, request reason) via chained interceptor.
Use the Socket API on App Engine. appengine dialer will override socketopt dialer
		 = append(, appengineDialerHook())
	}
Add tracing, but before the other options, so that clients can override the gRPC stats handler. This assumes that gRPC options are processed in order, left to right.
	 = addOCStatsHandler(, )
	 = append(, .GRPCDialOpts...)
	if .UserAgent != "" {
		 = append(, grpc.WithUserAgent(.UserAgent))
	}
TODO(weiranf): This socketopt dialer will be used by default at some point when isDirectPathEnabled will default to true, we guard it by the Directpath env var for now once we can introspect user defined dialer (https://github.com/grpc/grpc-go/issues/2795).
	if timeoutDialerOption != nil && isDirectPathEnabled(.Endpoint) {
		 = append(, timeoutDialerOption)
	}

	return grpc.DialContext(, .Endpoint, ...)
}
generateDefaultMtlsEndpoint attempts to derive the mTLS version of the defaultEndpoint via regex, and returns defaultEndpoint if unsuccessful. We need to applying the following 2 transformations: 1. pubsub.googleapis.com to pubsub.mtls.googleapis.com 2. pubsub.sandbox.googleapis.com to pubsub.mtls.sandbox.googleapis.com TODO(cbro): In the future, the mTLS endpoint will be read from Service Config and passed in as defaultMtlsEndpoint instead of generated from defaultEndpoint, and this function will be removed.
func ( string) string {
	var  = []string{
		".sandbox.googleapis.com", // must come first because .googleapis.com is a substring
		".googleapis.com",
	}
	for ,  := range  {
		if strings.Contains(, ) {
			return strings.Replace(, , ".mtls"+, -1)
		}
	}
	return 
}

func ( []grpc.DialOption,  *internal.DialSettings) []grpc.DialOption {
	if .TelemetryDisabled {
		return 
	}
	return append(, grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))
}
grpcTokenSource supplies PerRPCCredentials from an oauth.TokenSource.
Additional metadata attached as headers.
GetRequestMetadata gets the request metadata as a map from a grpcTokenSource.
func ( grpcTokenSource) ( context.Context,  ...string) (
	map[string]string, error) {
	,  := .TokenSource.GetRequestMetadata(, ...)
	if  != nil {
		return nil, 
	}
Attach system parameter
	if .quotaProject != "" {
		["X-goog-user-project"] = .quotaProject
	}
	if .requestReason != "" {
		["X-goog-request-reason"] = .requestReason
	}
	return , nil
}

func ( oauth2.TokenSource) bool {
	if  == nil {
		return false
	}
	,  := .Token()
	if  != nil {
		return false
	}
	if  == nil {
		return false
	}
	if ,  := .Extra("oauth2.google.tokenSource").(string);  != "compute-metadata" {
		return false
	}
	if ,  := .Extra("oauth2.google.serviceAccount").(string);  != "default" {
		return false
	}
	return true
}

Only host:port is supported, not other schemes (e.g., "tcp://" or "unix://"). Also don't try direct path if the user has chosen an alternate name resolver (i.e., via ":///" prefix). TODO(cbro): once gRPC has introspectible options, check the user hasn't provided a custom dialer in gRPC options.
	if strings.Contains(, "://") && !strings.HasPrefix(, "dns:///") {
		return false
	}
Only try direct path if the user has opted in via the environment variable.
	 := strings.Split(os.Getenv("GOOGLE_CLOUD_ENABLE_DIRECT_PATH"), ",")
Ignore empty string since an empty env variable splits into [""]
		if  != "" && strings.Contains(, ) {
			return true
		}
	}
	return false
}

func ( []option.ClientOption) (*internal.DialSettings, error) {
	var  internal.DialSettings
	for ,  := range  {
		.Apply(&)
	}
	if  := .Validate();  != nil {
		return nil, 
	}
NOTE(cbro): this is used only by the nightly mtls_smoketest and should not otherwise be used. It will be removed or renamed at some point.
	if os.Getenv("GOOGLE_API_USE_MTLS") == "always" {
		.Endpoint = generateDefaultMtlsEndpoint(.Endpoint)
	}

	return &, nil
}

type connPoolOption struct{ ConnPool }
WithConnPool returns a ClientOption that specifies the ConnPool connection to use as the basis of communications. This is only to be used by Google client libraries internally, for example when creating a longrunning API client that shares the same connection pool as a service client.