// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-go_gapic. DO NOT EDIT.

package admin

import (
	"context"
	"fmt"
	"math"
	"net/url"
	"time"

	"github.com/golang/protobuf/proto"
	gax "github.com/googleapis/gax-go/v2"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
	"google.golang.org/api/option/internaloption"
	gtransport "google.golang.org/api/transport/grpc"
	adminpb "google.golang.org/genproto/googleapis/analytics/admin/v1alpha"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
)

var newAnalyticsAdminClientHook clientHook

// AnalyticsAdminCallOptions contains the retry settings for each method of AnalyticsAdminClient.
type AnalyticsAdminCallOptions struct {
	GetAccount                        []gax.CallOption
	ListAccounts                      []gax.CallOption
	DeleteAccount                     []gax.CallOption
	UpdateAccount                     []gax.CallOption
	ProvisionAccountTicket            []gax.CallOption
	ListAccountSummaries              []gax.CallOption
	GetProperty                       []gax.CallOption
	ListProperties                    []gax.CallOption
	CreateProperty                    []gax.CallOption
	DeleteProperty                    []gax.CallOption
	UpdateProperty                    []gax.CallOption
	GetUserLink                       []gax.CallOption
	BatchGetUserLinks                 []gax.CallOption
	ListUserLinks                     []gax.CallOption
	AuditUserLinks                    []gax.CallOption
	CreateUserLink                    []gax.CallOption
	BatchCreateUserLinks              []gax.CallOption
	UpdateUserLink                    []gax.CallOption
	BatchUpdateUserLinks              []gax.CallOption
	DeleteUserLink                    []gax.CallOption
	BatchDeleteUserLinks              []gax.CallOption
	GetWebDataStream                  []gax.CallOption
	DeleteWebDataStream               []gax.CallOption
	UpdateWebDataStream               []gax.CallOption
	CreateWebDataStream               []gax.CallOption
	ListWebDataStreams                []gax.CallOption
	GetIosAppDataStream               []gax.CallOption
	DeleteIosAppDataStream            []gax.CallOption
	UpdateIosAppDataStream            []gax.CallOption
	CreateIosAppDataStream            []gax.CallOption
	ListIosAppDataStreams             []gax.CallOption
	GetAndroidAppDataStream           []gax.CallOption
	DeleteAndroidAppDataStream        []gax.CallOption
	UpdateAndroidAppDataStream        []gax.CallOption
	CreateAndroidAppDataStream        []gax.CallOption
	ListAndroidAppDataStreams         []gax.CallOption
	GetEnhancedMeasurementSettings    []gax.CallOption
	UpdateEnhancedMeasurementSettings []gax.CallOption
	CreateFirebaseLink                []gax.CallOption
	UpdateFirebaseLink                []gax.CallOption
	DeleteFirebaseLink                []gax.CallOption
	ListFirebaseLinks                 []gax.CallOption
	GetGlobalSiteTag                  []gax.CallOption
	CreateGoogleAdsLink               []gax.CallOption
	UpdateGoogleAdsLink               []gax.CallOption
	DeleteGoogleAdsLink               []gax.CallOption
	ListGoogleAdsLinks                []gax.CallOption
	GetDataSharingSettings            []gax.CallOption
}

func defaultAnalyticsAdminClientOptions() []option.ClientOption {
	return []option.ClientOption{
		internaloption.WithDefaultEndpoint("analyticsadmin.googleapis.com:443"),
		internaloption.WithDefaultMTLSEndpoint("analyticsadmin.mtls.googleapis.com:443"),
		internaloption.WithDefaultAudience("https://analyticsadmin.googleapis.com/"),
		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
		option.WithGRPCDialOption(grpc.WithDisableServiceConfig()),
		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
	}
}

func defaultAnalyticsAdminCallOptions() *AnalyticsAdminCallOptions {
	return &AnalyticsAdminCallOptions{
		GetAccount:             []gax.CallOption{},
		ListAccounts:           []gax.CallOption{},
		DeleteAccount:          []gax.CallOption{},
		UpdateAccount:          []gax.CallOption{},
		ProvisionAccountTicket: []gax.CallOption{},
		ListAccountSummaries: []gax.CallOption{
			gax.WithRetry(func() gax.Retryer {
				return gax.OnCodes([]codes.Code{
					codes.Unavailable,
					codes.Unknown,
				}, gax.Backoff{
					Initial:    1000 * time.Millisecond,
					Max:        60000 * time.Millisecond,
					Multiplier: 1.30,
				})
			}),
		},
		GetProperty:          []gax.CallOption{},
		ListProperties:       []gax.CallOption{},
		CreateProperty:       []gax.CallOption{},
		DeleteProperty:       []gax.CallOption{},
		UpdateProperty:       []gax.CallOption{},
		GetUserLink:          []gax.CallOption{},
		BatchGetUserLinks:    []gax.CallOption{},
		ListUserLinks:        []gax.CallOption{},
		AuditUserLinks:       []gax.CallOption{},
		CreateUserLink:       []gax.CallOption{},
		BatchCreateUserLinks: []gax.CallOption{},
		UpdateUserLink:       []gax.CallOption{},
		BatchUpdateUserLinks: []gax.CallOption{},
		DeleteUserLink:       []gax.CallOption{},
		BatchDeleteUserLinks: []gax.CallOption{},
		GetWebDataStream:     []gax.CallOption{},
		DeleteWebDataStream: []gax.CallOption{
			gax.WithRetry(func() gax.Retryer {
				return gax.OnCodes([]codes.Code{
					codes.Unavailable,
					codes.Unknown,
				}, gax.Backoff{
					Initial:    1000 * time.Millisecond,
					Max:        60000 * time.Millisecond,
					Multiplier: 1.30,
				})
			}),
		},
		UpdateWebDataStream:               []gax.CallOption{},
		CreateWebDataStream:               []gax.CallOption{},
		ListWebDataStreams:                []gax.CallOption{},
		GetIosAppDataStream:               []gax.CallOption{},
		DeleteIosAppDataStream:            []gax.CallOption{},
		UpdateIosAppDataStream:            []gax.CallOption{},
		CreateIosAppDataStream:            []gax.CallOption{},
		ListIosAppDataStreams:             []gax.CallOption{},
		GetAndroidAppDataStream:           []gax.CallOption{},
		DeleteAndroidAppDataStream:        []gax.CallOption{},
		UpdateAndroidAppDataStream:        []gax.CallOption{},
		CreateAndroidAppDataStream:        []gax.CallOption{},
		ListAndroidAppDataStreams:         []gax.CallOption{},
		GetEnhancedMeasurementSettings:    []gax.CallOption{},
		UpdateEnhancedMeasurementSettings: []gax.CallOption{},
		CreateFirebaseLink:                []gax.CallOption{},
		UpdateFirebaseLink:                []gax.CallOption{},
		DeleteFirebaseLink:                []gax.CallOption{},
		ListFirebaseLinks:                 []gax.CallOption{},
		GetGlobalSiteTag:                  []gax.CallOption{},
		CreateGoogleAdsLink:               []gax.CallOption{},
		UpdateGoogleAdsLink:               []gax.CallOption{},
		DeleteGoogleAdsLink:               []gax.CallOption{},
		ListGoogleAdsLinks:                []gax.CallOption{},
		GetDataSharingSettings: []gax.CallOption{
			gax.WithRetry(func() gax.Retryer {
				return gax.OnCodes([]codes.Code{
					codes.Unavailable,
					codes.Unknown,
				}, gax.Backoff{
					Initial:    1000 * time.Millisecond,
					Max:        60000 * time.Millisecond,
					Multiplier: 1.30,
				})
			}),
		},
	}
}

// AnalyticsAdminClient is a client for interacting with Google Analytics Admin API.
//
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
type AnalyticsAdminClient struct {
	// Connection pool of gRPC connections to the service.
	connPool gtransport.ConnPool

	// flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE
	disableDeadlines bool

	// The gRPC API client.
	analyticsAdminClient adminpb.AnalyticsAdminServiceClient

	// The call options for this service.
	CallOptions *AnalyticsAdminCallOptions

	// The x-goog-* metadata to be sent with each request.
	xGoogMetadata metadata.MD
}

// NewAnalyticsAdminClient creates a new analytics admin service client.
//
// Service Interface for the Analytics Admin API (GA4).
func NewAnalyticsAdminClient(ctx context.Context, opts ...option.ClientOption) (*AnalyticsAdminClient, error) {
	clientOpts := defaultAnalyticsAdminClientOptions()

	if newAnalyticsAdminClientHook != nil {
		hookOpts, err := newAnalyticsAdminClientHook(ctx, clientHookParams{})
		if err != nil {
			return nil, err
		}
		clientOpts = append(clientOpts, hookOpts...)
	}

	disableDeadlines, err := checkDisableDeadlines()
	if err != nil {
		return nil, err
	}

	connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...)
	if err != nil {
		return nil, err
	}
	c := &AnalyticsAdminClient{
		connPool:         connPool,
		disableDeadlines: disableDeadlines,
		CallOptions:      defaultAnalyticsAdminCallOptions(),

		analyticsAdminClient: adminpb.NewAnalyticsAdminServiceClient(connPool),
	}
	c.setGoogleClientInfo()

	return c, nil
}

// Connection returns a connection to the API service.
//
// Deprecated.
func (c *AnalyticsAdminClient) Connection() *grpc.ClientConn {
	return c.connPool.Conn()
}

// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *AnalyticsAdminClient) Close() error {
	return c.connPool.Close()
}

// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *AnalyticsAdminClient) setGoogleClientInfo(keyval ...string) {
	kv := append([]string{"gl-go", versionGo()}, keyval...)
	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version)
	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}

// GetAccount lookup for a single Account.
func (c *AnalyticsAdminClient) GetAccount(ctx context.Context, req *adminpb.GetAccountRequest, opts ...gax.CallOption) (*adminpb.Account, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetAccount[0:len(c.CallOptions.GetAccount):len(c.CallOptions.GetAccount)], opts...)
	var resp *adminpb.Account
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetAccount(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListAccounts returns all accounts accessible by the caller.
//
// Note that these accounts might not currently have GA4 properties.
// Soft-deleted (ie: “trashed”) accounts are excluded by default.
// Returns an empty list if no relevant accounts are found.
func (c *AnalyticsAdminClient) ListAccounts(ctx context.Context, req *adminpb.ListAccountsRequest, opts ...gax.CallOption) *AccountIterator {
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append(c.CallOptions.ListAccounts[0:len(c.CallOptions.ListAccounts):len(c.CallOptions.ListAccounts)], opts...)
	it := &AccountIterator{}
	req = proto.Clone(req).(*adminpb.ListAccountsRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.Account, string, error) {
		var resp *adminpb.ListAccountsResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListAccounts(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetAccounts(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// DeleteAccount marks target Account as soft-deleted (ie: “trashed”) and returns it.
//
// This API does not have a method to restore soft-deleted accounts.
// However, they can be restored using the Trash Can UI.
//
// If the accounts are not restored before the expiration time, the account
// and all child resources (eg: Properties, GoogleAdsLinks, Streams,
// UserLinks) will be permanently purged.
// https://support.google.com/analytics/answer/6154772 (at https://support.google.com/analytics/answer/6154772)
//
// Returns an error if the target is not found.
func (c *AnalyticsAdminClient) DeleteAccount(ctx context.Context, req *adminpb.DeleteAccountRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteAccount[0:len(c.CallOptions.DeleteAccount):len(c.CallOptions.DeleteAccount)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.DeleteAccount(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// UpdateAccount updates an account.
func (c *AnalyticsAdminClient) UpdateAccount(ctx context.Context, req *adminpb.UpdateAccountRequest, opts ...gax.CallOption) (*adminpb.Account, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "account.name", url.QueryEscape(req.GetAccount().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateAccount[0:len(c.CallOptions.UpdateAccount):len(c.CallOptions.UpdateAccount)], opts...)
	var resp *adminpb.Account
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateAccount(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ProvisionAccountTicket requests a ticket for creating an account.
func (c *AnalyticsAdminClient) ProvisionAccountTicket(ctx context.Context, req *adminpb.ProvisionAccountTicketRequest, opts ...gax.CallOption) (*adminpb.ProvisionAccountTicketResponse, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append(c.CallOptions.ProvisionAccountTicket[0:len(c.CallOptions.ProvisionAccountTicket):len(c.CallOptions.ProvisionAccountTicket)], opts...)
	var resp *adminpb.ProvisionAccountTicketResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.ProvisionAccountTicket(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListAccountSummaries returns summaries of all accounts accessible by the caller.
func (c *AnalyticsAdminClient) ListAccountSummaries(ctx context.Context, req *adminpb.ListAccountSummariesRequest, opts ...gax.CallOption) *AccountSummaryIterator {
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append(c.CallOptions.ListAccountSummaries[0:len(c.CallOptions.ListAccountSummaries):len(c.CallOptions.ListAccountSummaries)], opts...)
	it := &AccountSummaryIterator{}
	req = proto.Clone(req).(*adminpb.ListAccountSummariesRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.AccountSummary, string, error) {
		var resp *adminpb.ListAccountSummariesResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListAccountSummaries(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetAccountSummaries(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// GetProperty lookup for a single “GA4” Property.
func (c *AnalyticsAdminClient) GetProperty(ctx context.Context, req *adminpb.GetPropertyRequest, opts ...gax.CallOption) (*adminpb.Property, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetProperty[0:len(c.CallOptions.GetProperty):len(c.CallOptions.GetProperty)], opts...)
	var resp *adminpb.Property
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetProperty(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListProperties returns child Properties under the specified parent Account.
//
// Only “GA4” properties will be returned.
// Properties will be excluded if the caller does not have access.
// Soft-deleted (ie: “trashed”) properties are excluded by default.
// Returns an empty list if no relevant properties are found.
func (c *AnalyticsAdminClient) ListProperties(ctx context.Context, req *adminpb.ListPropertiesRequest, opts ...gax.CallOption) *PropertyIterator {
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append(c.CallOptions.ListProperties[0:len(c.CallOptions.ListProperties):len(c.CallOptions.ListProperties)], opts...)
	it := &PropertyIterator{}
	req = proto.Clone(req).(*adminpb.ListPropertiesRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.Property, string, error) {
		var resp *adminpb.ListPropertiesResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListProperties(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetProperties(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// CreateProperty creates an “GA4” property with the specified location and attributes.
func (c *AnalyticsAdminClient) CreateProperty(ctx context.Context, req *adminpb.CreatePropertyRequest, opts ...gax.CallOption) (*adminpb.Property, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	ctx = insertMetadata(ctx, c.xGoogMetadata)
	opts = append(c.CallOptions.CreateProperty[0:len(c.CallOptions.CreateProperty):len(c.CallOptions.CreateProperty)], opts...)
	var resp *adminpb.Property
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.CreateProperty(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteProperty marks target Property as soft-deleted (ie: “trashed”) and returns it.
//
// This API does not have a method to restore soft-deleted properties.
// However, they can be restored using the Trash Can UI.
//
// If the properties are not restored before the expiration time, the Property
// and all child resources (eg: GoogleAdsLinks, Streams, UserLinks)
// will be permanently purged.
// https://support.google.com/analytics/answer/6154772 (at https://support.google.com/analytics/answer/6154772)
//
// Returns an error if the target is not found, or is not an GA4 Property.
func (c *AnalyticsAdminClient) DeleteProperty(ctx context.Context, req *adminpb.DeletePropertyRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteProperty[0:len(c.CallOptions.DeleteProperty):len(c.CallOptions.DeleteProperty)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.DeleteProperty(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// UpdateProperty updates a property.
func (c *AnalyticsAdminClient) UpdateProperty(ctx context.Context, req *adminpb.UpdatePropertyRequest, opts ...gax.CallOption) (*adminpb.Property, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "property.name", url.QueryEscape(req.GetProperty().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateProperty[0:len(c.CallOptions.UpdateProperty):len(c.CallOptions.UpdateProperty)], opts...)
	var resp *adminpb.Property
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateProperty(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// GetUserLink gets information about a user’s link to an account or property.
func (c *AnalyticsAdminClient) GetUserLink(ctx context.Context, req *adminpb.GetUserLinkRequest, opts ...gax.CallOption) (*adminpb.UserLink, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetUserLink[0:len(c.CallOptions.GetUserLink):len(c.CallOptions.GetUserLink)], opts...)
	var resp *adminpb.UserLink
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetUserLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// BatchGetUserLinks gets information about multiple users’ links to an account or property.
func (c *AnalyticsAdminClient) BatchGetUserLinks(ctx context.Context, req *adminpb.BatchGetUserLinksRequest, opts ...gax.CallOption) (*adminpb.BatchGetUserLinksResponse, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.BatchGetUserLinks[0:len(c.CallOptions.BatchGetUserLinks):len(c.CallOptions.BatchGetUserLinks)], opts...)
	var resp *adminpb.BatchGetUserLinksResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.BatchGetUserLinks(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListUserLinks lists all user links on an account or property.
func (c *AnalyticsAdminClient) ListUserLinks(ctx context.Context, req *adminpb.ListUserLinksRequest, opts ...gax.CallOption) *UserLinkIterator {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.ListUserLinks[0:len(c.CallOptions.ListUserLinks):len(c.CallOptions.ListUserLinks)], opts...)
	it := &UserLinkIterator{}
	req = proto.Clone(req).(*adminpb.ListUserLinksRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.UserLink, string, error) {
		var resp *adminpb.ListUserLinksResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListUserLinks(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetUserLinks(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// AuditUserLinks lists all user links on an account or property, including implicit ones
// that come from effective permissions granted by groups or organization
// admin roles.
//
// If a returned user link does not have direct permissions, they cannot
// be removed from the account or property directly with the DeleteUserLink
// command. They have to be removed from the group/etc that gives them
// permissions, which is currently only usable/discoverable in the GA or GMP
// UIs.
func (c *AnalyticsAdminClient) AuditUserLinks(ctx context.Context, req *adminpb.AuditUserLinksRequest, opts ...gax.CallOption) *AuditUserLinkIterator {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.AuditUserLinks[0:len(c.CallOptions.AuditUserLinks):len(c.CallOptions.AuditUserLinks)], opts...)
	it := &AuditUserLinkIterator{}
	req = proto.Clone(req).(*adminpb.AuditUserLinksRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.AuditUserLink, string, error) {
		var resp *adminpb.AuditUserLinksResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.AuditUserLinks(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetUserLinks(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// CreateUserLink creates a user link on an account or property.
//
// If the user with the specified email already has permissions on the
// account or property, then the user’s existing permissions will be unioned
// with the permissions specified in the new UserLink.
func (c *AnalyticsAdminClient) CreateUserLink(ctx context.Context, req *adminpb.CreateUserLinkRequest, opts ...gax.CallOption) (*adminpb.UserLink, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateUserLink[0:len(c.CallOptions.CreateUserLink):len(c.CallOptions.CreateUserLink)], opts...)
	var resp *adminpb.UserLink
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.CreateUserLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// BatchCreateUserLinks creates information about multiple users’ links to an account or property.
//
// This method is transactional. If any UserLink cannot be created, none of
// the UserLinks will be created.
func (c *AnalyticsAdminClient) BatchCreateUserLinks(ctx context.Context, req *adminpb.BatchCreateUserLinksRequest, opts ...gax.CallOption) (*adminpb.BatchCreateUserLinksResponse, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.BatchCreateUserLinks[0:len(c.CallOptions.BatchCreateUserLinks):len(c.CallOptions.BatchCreateUserLinks)], opts...)
	var resp *adminpb.BatchCreateUserLinksResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.BatchCreateUserLinks(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// UpdateUserLink updates a user link on an account or property.
func (c *AnalyticsAdminClient) UpdateUserLink(ctx context.Context, req *adminpb.UpdateUserLinkRequest, opts ...gax.CallOption) (*adminpb.UserLink, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "user_link.name", url.QueryEscape(req.GetUserLink().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateUserLink[0:len(c.CallOptions.UpdateUserLink):len(c.CallOptions.UpdateUserLink)], opts...)
	var resp *adminpb.UserLink
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateUserLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// BatchUpdateUserLinks updates information about multiple users’ links to an account or property.
func (c *AnalyticsAdminClient) BatchUpdateUserLinks(ctx context.Context, req *adminpb.BatchUpdateUserLinksRequest, opts ...gax.CallOption) (*adminpb.BatchUpdateUserLinksResponse, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.BatchUpdateUserLinks[0:len(c.CallOptions.BatchUpdateUserLinks):len(c.CallOptions.BatchUpdateUserLinks)], opts...)
	var resp *adminpb.BatchUpdateUserLinksResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.BatchUpdateUserLinks(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteUserLink deletes a user link on an account or property.
func (c *AnalyticsAdminClient) DeleteUserLink(ctx context.Context, req *adminpb.DeleteUserLinkRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteUserLink[0:len(c.CallOptions.DeleteUserLink):len(c.CallOptions.DeleteUserLink)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.DeleteUserLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// BatchDeleteUserLinks deletes information about multiple users’ links to an account or property.
func (c *AnalyticsAdminClient) BatchDeleteUserLinks(ctx context.Context, req *adminpb.BatchDeleteUserLinksRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.BatchDeleteUserLinks[0:len(c.CallOptions.BatchDeleteUserLinks):len(c.CallOptions.BatchDeleteUserLinks)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.BatchDeleteUserLinks(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// GetWebDataStream lookup for a single WebDataStream
func (c *AnalyticsAdminClient) GetWebDataStream(ctx context.Context, req *adminpb.GetWebDataStreamRequest, opts ...gax.CallOption) (*adminpb.WebDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetWebDataStream[0:len(c.CallOptions.GetWebDataStream):len(c.CallOptions.GetWebDataStream)], opts...)
	var resp *adminpb.WebDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetWebDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteWebDataStream deletes a web stream on a property.
func (c *AnalyticsAdminClient) DeleteWebDataStream(ctx context.Context, req *adminpb.DeleteWebDataStreamRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteWebDataStream[0:len(c.CallOptions.DeleteWebDataStream):len(c.CallOptions.DeleteWebDataStream)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.DeleteWebDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// UpdateWebDataStream updates a web stream on a property.
func (c *AnalyticsAdminClient) UpdateWebDataStream(ctx context.Context, req *adminpb.UpdateWebDataStreamRequest, opts ...gax.CallOption) (*adminpb.WebDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "web_data_stream.name", url.QueryEscape(req.GetWebDataStream().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateWebDataStream[0:len(c.CallOptions.UpdateWebDataStream):len(c.CallOptions.UpdateWebDataStream)], opts...)
	var resp *adminpb.WebDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateWebDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// CreateWebDataStream creates a web stream with the specified location and attributes.
func (c *AnalyticsAdminClient) CreateWebDataStream(ctx context.Context, req *adminpb.CreateWebDataStreamRequest, opts ...gax.CallOption) (*adminpb.WebDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateWebDataStream[0:len(c.CallOptions.CreateWebDataStream):len(c.CallOptions.CreateWebDataStream)], opts...)
	var resp *adminpb.WebDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.CreateWebDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListWebDataStreams returns child web data streams under the specified parent property.
//
// Web data streams will be excluded if the caller does not have access.
// Returns an empty list if no relevant web data streams are found.
func (c *AnalyticsAdminClient) ListWebDataStreams(ctx context.Context, req *adminpb.ListWebDataStreamsRequest, opts ...gax.CallOption) *WebDataStreamIterator {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.ListWebDataStreams[0:len(c.CallOptions.ListWebDataStreams):len(c.CallOptions.ListWebDataStreams)], opts...)
	it := &WebDataStreamIterator{}
	req = proto.Clone(req).(*adminpb.ListWebDataStreamsRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.WebDataStream, string, error) {
		var resp *adminpb.ListWebDataStreamsResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListWebDataStreams(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetWebDataStreams(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// GetIosAppDataStream lookup for a single IosAppDataStream
func (c *AnalyticsAdminClient) GetIosAppDataStream(ctx context.Context, req *adminpb.GetIosAppDataStreamRequest, opts ...gax.CallOption) (*adminpb.IosAppDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetIosAppDataStream[0:len(c.CallOptions.GetIosAppDataStream):len(c.CallOptions.GetIosAppDataStream)], opts...)
	var resp *adminpb.IosAppDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetIosAppDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteIosAppDataStream deletes an iOS app stream on a property.
func (c *AnalyticsAdminClient) DeleteIosAppDataStream(ctx context.Context, req *adminpb.DeleteIosAppDataStreamRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteIosAppDataStream[0:len(c.CallOptions.DeleteIosAppDataStream):len(c.CallOptions.DeleteIosAppDataStream)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.DeleteIosAppDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// UpdateIosAppDataStream updates an iOS app stream on a property.
func (c *AnalyticsAdminClient) UpdateIosAppDataStream(ctx context.Context, req *adminpb.UpdateIosAppDataStreamRequest, opts ...gax.CallOption) (*adminpb.IosAppDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "ios_app_data_stream.name", url.QueryEscape(req.GetIosAppDataStream().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateIosAppDataStream[0:len(c.CallOptions.UpdateIosAppDataStream):len(c.CallOptions.UpdateIosAppDataStream)], opts...)
	var resp *adminpb.IosAppDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateIosAppDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// CreateIosAppDataStream creates an iOS app stream with the specified location and attributes.
//
// Note that an iOS app stream must be linked to a Firebase app to receive
// traffic.
//
// To create a working app stream, make sure your property is linked to a
// Firebase project. Then, use the Firebase API to create a Firebase app,
// which will also create an appropriate data stream in Analytics (may take up
// to 24 hours).
func (c *AnalyticsAdminClient) CreateIosAppDataStream(ctx context.Context, req *adminpb.CreateIosAppDataStreamRequest, opts ...gax.CallOption) (*adminpb.IosAppDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateIosAppDataStream[0:len(c.CallOptions.CreateIosAppDataStream):len(c.CallOptions.CreateIosAppDataStream)], opts...)
	var resp *adminpb.IosAppDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.CreateIosAppDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListIosAppDataStreams returns child iOS app data streams under the specified parent property.
//
// iOS app data streams will be excluded if the caller does not have access.
// Returns an empty list if no relevant iOS app data streams are found.
func (c *AnalyticsAdminClient) ListIosAppDataStreams(ctx context.Context, req *adminpb.ListIosAppDataStreamsRequest, opts ...gax.CallOption) *IosAppDataStreamIterator {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.ListIosAppDataStreams[0:len(c.CallOptions.ListIosAppDataStreams):len(c.CallOptions.ListIosAppDataStreams)], opts...)
	it := &IosAppDataStreamIterator{}
	req = proto.Clone(req).(*adminpb.ListIosAppDataStreamsRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.IosAppDataStream, string, error) {
		var resp *adminpb.ListIosAppDataStreamsResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListIosAppDataStreams(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetIosAppDataStreams(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// GetAndroidAppDataStream lookup for a single AndroidAppDataStream
func (c *AnalyticsAdminClient) GetAndroidAppDataStream(ctx context.Context, req *adminpb.GetAndroidAppDataStreamRequest, opts ...gax.CallOption) (*adminpb.AndroidAppDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetAndroidAppDataStream[0:len(c.CallOptions.GetAndroidAppDataStream):len(c.CallOptions.GetAndroidAppDataStream)], opts...)
	var resp *adminpb.AndroidAppDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetAndroidAppDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteAndroidAppDataStream deletes an android app stream on a property.
func (c *AnalyticsAdminClient) DeleteAndroidAppDataStream(ctx context.Context, req *adminpb.DeleteAndroidAppDataStreamRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteAndroidAppDataStream[0:len(c.CallOptions.DeleteAndroidAppDataStream):len(c.CallOptions.DeleteAndroidAppDataStream)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.DeleteAndroidAppDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// UpdateAndroidAppDataStream updates an android app stream on a property.
func (c *AnalyticsAdminClient) UpdateAndroidAppDataStream(ctx context.Context, req *adminpb.UpdateAndroidAppDataStreamRequest, opts ...gax.CallOption) (*adminpb.AndroidAppDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "android_app_data_stream.name", url.QueryEscape(req.GetAndroidAppDataStream().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateAndroidAppDataStream[0:len(c.CallOptions.UpdateAndroidAppDataStream):len(c.CallOptions.UpdateAndroidAppDataStream)], opts...)
	var resp *adminpb.AndroidAppDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateAndroidAppDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// CreateAndroidAppDataStream creates an Android app stream with the specified location and attributes.
//
// Note that an Android app stream must be linked to a Firebase app to receive
// traffic.
//
// To create a working app stream, make sure your property is linked to a
// Firebase project. Then, use the Firebase API to create a Firebase app,
// which will also create an appropriate data stream in Analytics (may take up
// to 24 hours).
func (c *AnalyticsAdminClient) CreateAndroidAppDataStream(ctx context.Context, req *adminpb.CreateAndroidAppDataStreamRequest, opts ...gax.CallOption) (*adminpb.AndroidAppDataStream, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateAndroidAppDataStream[0:len(c.CallOptions.CreateAndroidAppDataStream):len(c.CallOptions.CreateAndroidAppDataStream)], opts...)
	var resp *adminpb.AndroidAppDataStream
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.CreateAndroidAppDataStream(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListAndroidAppDataStreams returns child android app streams under the specified parent property.
//
// Android app streams will be excluded if the caller does not have access.
// Returns an empty list if no relevant android app streams are found.
func (c *AnalyticsAdminClient) ListAndroidAppDataStreams(ctx context.Context, req *adminpb.ListAndroidAppDataStreamsRequest, opts ...gax.CallOption) *AndroidAppDataStreamIterator {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.ListAndroidAppDataStreams[0:len(c.CallOptions.ListAndroidAppDataStreams):len(c.CallOptions.ListAndroidAppDataStreams)], opts...)
	it := &AndroidAppDataStreamIterator{}
	req = proto.Clone(req).(*adminpb.ListAndroidAppDataStreamsRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.AndroidAppDataStream, string, error) {
		var resp *adminpb.ListAndroidAppDataStreamsResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListAndroidAppDataStreams(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetAndroidAppDataStreams(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// GetEnhancedMeasurementSettings returns the singleton enhanced measurement settings for this web stream.
// Note that the stream must enable enhanced measurement for these settings to
// take effect.
func (c *AnalyticsAdminClient) GetEnhancedMeasurementSettings(ctx context.Context, req *adminpb.GetEnhancedMeasurementSettingsRequest, opts ...gax.CallOption) (*adminpb.EnhancedMeasurementSettings, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetEnhancedMeasurementSettings[0:len(c.CallOptions.GetEnhancedMeasurementSettings):len(c.CallOptions.GetEnhancedMeasurementSettings)], opts...)
	var resp *adminpb.EnhancedMeasurementSettings
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetEnhancedMeasurementSettings(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// UpdateEnhancedMeasurementSettings updates the singleton enhanced measurement settings for this web stream.
// Note that the stream must enable enhanced measurement for these settings to
// take effect.
func (c *AnalyticsAdminClient) UpdateEnhancedMeasurementSettings(ctx context.Context, req *adminpb.UpdateEnhancedMeasurementSettingsRequest, opts ...gax.CallOption) (*adminpb.EnhancedMeasurementSettings, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "enhanced_measurement_settings.name", url.QueryEscape(req.GetEnhancedMeasurementSettings().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateEnhancedMeasurementSettings[0:len(c.CallOptions.UpdateEnhancedMeasurementSettings):len(c.CallOptions.UpdateEnhancedMeasurementSettings)], opts...)
	var resp *adminpb.EnhancedMeasurementSettings
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateEnhancedMeasurementSettings(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// CreateFirebaseLink creates a FirebaseLink.
//
// Properties can have at most one FirebaseLink.
func (c *AnalyticsAdminClient) CreateFirebaseLink(ctx context.Context, req *adminpb.CreateFirebaseLinkRequest, opts ...gax.CallOption) (*adminpb.FirebaseLink, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateFirebaseLink[0:len(c.CallOptions.CreateFirebaseLink):len(c.CallOptions.CreateFirebaseLink)], opts...)
	var resp *adminpb.FirebaseLink
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.CreateFirebaseLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// UpdateFirebaseLink updates a FirebaseLink on a property
func (c *AnalyticsAdminClient) UpdateFirebaseLink(ctx context.Context, req *adminpb.UpdateFirebaseLinkRequest, opts ...gax.CallOption) (*adminpb.FirebaseLink, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "firebase_link.name", url.QueryEscape(req.GetFirebaseLink().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateFirebaseLink[0:len(c.CallOptions.UpdateFirebaseLink):len(c.CallOptions.UpdateFirebaseLink)], opts...)
	var resp *adminpb.FirebaseLink
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateFirebaseLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteFirebaseLink deletes a FirebaseLink on a property
func (c *AnalyticsAdminClient) DeleteFirebaseLink(ctx context.Context, req *adminpb.DeleteFirebaseLinkRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteFirebaseLink[0:len(c.CallOptions.DeleteFirebaseLink):len(c.CallOptions.DeleteFirebaseLink)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.DeleteFirebaseLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// ListFirebaseLinks lists FirebaseLinks on a property.
// Properties can have at most one FirebaseLink.
func (c *AnalyticsAdminClient) ListFirebaseLinks(ctx context.Context, req *adminpb.ListFirebaseLinksRequest, opts ...gax.CallOption) *FirebaseLinkIterator {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.ListFirebaseLinks[0:len(c.CallOptions.ListFirebaseLinks):len(c.CallOptions.ListFirebaseLinks)], opts...)
	it := &FirebaseLinkIterator{}
	req = proto.Clone(req).(*adminpb.ListFirebaseLinksRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.FirebaseLink, string, error) {
		var resp *adminpb.ListFirebaseLinksResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListFirebaseLinks(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetFirebaseLinks(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// GetGlobalSiteTag returns the Site Tag for the specified web stream.
// Site Tags are immutable singletons.
func (c *AnalyticsAdminClient) GetGlobalSiteTag(ctx context.Context, req *adminpb.GetGlobalSiteTagRequest, opts ...gax.CallOption) (*adminpb.GlobalSiteTag, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetGlobalSiteTag[0:len(c.CallOptions.GetGlobalSiteTag):len(c.CallOptions.GetGlobalSiteTag)], opts...)
	var resp *adminpb.GlobalSiteTag
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetGlobalSiteTag(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// CreateGoogleAdsLink creates a GoogleAdsLink.
func (c *AnalyticsAdminClient) CreateGoogleAdsLink(ctx context.Context, req *adminpb.CreateGoogleAdsLinkRequest, opts ...gax.CallOption) (*adminpb.GoogleAdsLink, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateGoogleAdsLink[0:len(c.CallOptions.CreateGoogleAdsLink):len(c.CallOptions.CreateGoogleAdsLink)], opts...)
	var resp *adminpb.GoogleAdsLink
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.CreateGoogleAdsLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// UpdateGoogleAdsLink updates a GoogleAdsLink on a property
func (c *AnalyticsAdminClient) UpdateGoogleAdsLink(ctx context.Context, req *adminpb.UpdateGoogleAdsLinkRequest, opts ...gax.CallOption) (*adminpb.GoogleAdsLink, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "google_ads_link.name", url.QueryEscape(req.GetGoogleAdsLink().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateGoogleAdsLink[0:len(c.CallOptions.UpdateGoogleAdsLink):len(c.CallOptions.UpdateGoogleAdsLink)], opts...)
	var resp *adminpb.GoogleAdsLink
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.UpdateGoogleAdsLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteGoogleAdsLink deletes a GoogleAdsLink on a property
func (c *AnalyticsAdminClient) DeleteGoogleAdsLink(ctx context.Context, req *adminpb.DeleteGoogleAdsLinkRequest, opts ...gax.CallOption) error {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteGoogleAdsLink[0:len(c.CallOptions.DeleteGoogleAdsLink):len(c.CallOptions.DeleteGoogleAdsLink)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.analyticsAdminClient.DeleteGoogleAdsLink(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// ListGoogleAdsLinks lists GoogleAdsLinks on a property.
func (c *AnalyticsAdminClient) ListGoogleAdsLinks(ctx context.Context, req *adminpb.ListGoogleAdsLinksRequest, opts ...gax.CallOption) *GoogleAdsLinkIterator {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.ListGoogleAdsLinks[0:len(c.CallOptions.ListGoogleAdsLinks):len(c.CallOptions.ListGoogleAdsLinks)], opts...)
	it := &GoogleAdsLinkIterator{}
	req = proto.Clone(req).(*adminpb.ListGoogleAdsLinksRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*adminpb.GoogleAdsLink, string, error) {
		var resp *adminpb.ListGoogleAdsLinksResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.analyticsAdminClient.ListGoogleAdsLinks(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetGoogleAdsLinks(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// GetDataSharingSettings get data sharing settings on an account.
// Data sharing settings are singletons.
func (c *AnalyticsAdminClient) GetDataSharingSettings(ctx context.Context, req *adminpb.GetDataSharingSettingsRequest, opts ...gax.CallOption) (*adminpb.DataSharingSettings, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetDataSharingSettings[0:len(c.CallOptions.GetDataSharingSettings):len(c.CallOptions.GetDataSharingSettings)], opts...)
	var resp *adminpb.DataSharingSettings
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.analyticsAdminClient.GetDataSharingSettings(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// AccountIterator manages a stream of *adminpb.Account.
type AccountIterator struct {
	items    []*adminpb.Account
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.Account, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *AccountIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *AccountIterator) Next() (*adminpb.Account, error) {
	var item *adminpb.Account
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *AccountIterator) bufLen() int {
	return len(it.items)
}

func (it *AccountIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// AccountSummaryIterator manages a stream of *adminpb.AccountSummary.
type AccountSummaryIterator struct {
	items    []*adminpb.AccountSummary
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.AccountSummary, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *AccountSummaryIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *AccountSummaryIterator) Next() (*adminpb.AccountSummary, error) {
	var item *adminpb.AccountSummary
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *AccountSummaryIterator) bufLen() int {
	return len(it.items)
}

func (it *AccountSummaryIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// AndroidAppDataStreamIterator manages a stream of *adminpb.AndroidAppDataStream.
type AndroidAppDataStreamIterator struct {
	items    []*adminpb.AndroidAppDataStream
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.AndroidAppDataStream, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *AndroidAppDataStreamIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *AndroidAppDataStreamIterator) Next() (*adminpb.AndroidAppDataStream, error) {
	var item *adminpb.AndroidAppDataStream
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *AndroidAppDataStreamIterator) bufLen() int {
	return len(it.items)
}

func (it *AndroidAppDataStreamIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// AuditUserLinkIterator manages a stream of *adminpb.AuditUserLink.
type AuditUserLinkIterator struct {
	items    []*adminpb.AuditUserLink
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.AuditUserLink, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *AuditUserLinkIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *AuditUserLinkIterator) Next() (*adminpb.AuditUserLink, error) {
	var item *adminpb.AuditUserLink
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *AuditUserLinkIterator) bufLen() int {
	return len(it.items)
}

func (it *AuditUserLinkIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// FirebaseLinkIterator manages a stream of *adminpb.FirebaseLink.
type FirebaseLinkIterator struct {
	items    []*adminpb.FirebaseLink
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.FirebaseLink, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *FirebaseLinkIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *FirebaseLinkIterator) Next() (*adminpb.FirebaseLink, error) {
	var item *adminpb.FirebaseLink
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *FirebaseLinkIterator) bufLen() int {
	return len(it.items)
}

func (it *FirebaseLinkIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// GoogleAdsLinkIterator manages a stream of *adminpb.GoogleAdsLink.
type GoogleAdsLinkIterator struct {
	items    []*adminpb.GoogleAdsLink
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.GoogleAdsLink, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *GoogleAdsLinkIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *GoogleAdsLinkIterator) Next() (*adminpb.GoogleAdsLink, error) {
	var item *adminpb.GoogleAdsLink
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *GoogleAdsLinkIterator) bufLen() int {
	return len(it.items)
}

func (it *GoogleAdsLinkIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// IosAppDataStreamIterator manages a stream of *adminpb.IosAppDataStream.
type IosAppDataStreamIterator struct {
	items    []*adminpb.IosAppDataStream
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.IosAppDataStream, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *IosAppDataStreamIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *IosAppDataStreamIterator) Next() (*adminpb.IosAppDataStream, error) {
	var item *adminpb.IosAppDataStream
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *IosAppDataStreamIterator) bufLen() int {
	return len(it.items)
}

func (it *IosAppDataStreamIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// PropertyIterator manages a stream of *adminpb.Property.
type PropertyIterator struct {
	items    []*adminpb.Property
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.Property, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *PropertyIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *PropertyIterator) Next() (*adminpb.Property, error) {
	var item *adminpb.Property
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *PropertyIterator) bufLen() int {
	return len(it.items)
}

func (it *PropertyIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// UserLinkIterator manages a stream of *adminpb.UserLink.
type UserLinkIterator struct {
	items    []*adminpb.UserLink
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.UserLink, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *UserLinkIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *UserLinkIterator) Next() (*adminpb.UserLink, error) {
	var item *adminpb.UserLink
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *UserLinkIterator) bufLen() int {
	return len(it.items)
}

func (it *UserLinkIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}

// WebDataStreamIterator manages a stream of *adminpb.WebDataStream.
type WebDataStreamIterator struct {
	items    []*adminpb.WebDataStream
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*adminpb.WebDataStream, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *WebDataStreamIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *WebDataStreamIterator) Next() (*adminpb.WebDataStream, error) {
	var item *adminpb.WebDataStream
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *WebDataStreamIterator) bufLen() int {
	return len(it.items)
}

func (it *WebDataStreamIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}
