// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package storagetransfer provides access to the Storage Transfer API.
//
// For product documentation, see: https://cloud.google.com/storage-transfer/docs
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/storagetransfer/v1"
//   ...
//   ctx := context.Background()
//   storagetransferService, err := storagetransfer.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   storagetransferService, err := storagetransfer.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   storagetransferService, err := storagetransfer.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package storagetransfer // import "google.golang.org/api/storagetransfer/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint

const apiId = "storagetransfer:v1"
const apiName = "storagetransfer"
const apiVersion = "v1"
const basePath = "https://storagetransfer.googleapis.com/"
const mtlsBasePath = "https://storagetransfer.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud-platform",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.GoogleServiceAccounts = NewGoogleServiceAccountsService(s)
	s.TransferJobs = NewTransferJobsService(s)
	s.TransferOperations = NewTransferOperationsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	GoogleServiceAccounts *GoogleServiceAccountsService

	TransferJobs *TransferJobsService

	TransferOperations *TransferOperationsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewGoogleServiceAccountsService(s *Service) *GoogleServiceAccountsService {
	rs := &GoogleServiceAccountsService{s: s}
	return rs
}

type GoogleServiceAccountsService struct {
	s *Service
}

func NewTransferJobsService(s *Service) *TransferJobsService {
	rs := &TransferJobsService{s: s}
	return rs
}

type TransferJobsService struct {
	s *Service
}

func NewTransferOperationsService(s *Service) *TransferOperationsService {
	rs := &TransferOperationsService{s: s}
	return rs
}

type TransferOperationsService struct {
	s *Service
}

// AwsAccessKey: AWS access key (see [AWS Security
// Credentials](https://docs.aws.amazon.com/general/latest/gr/aws-securit
// y-credentials.html)).
type AwsAccessKey struct {
	// AccessKeyId: Required. AWS access key ID.
	AccessKeyId string `json:"accessKeyId,omitempty"`

	// SecretAccessKey: Required. AWS secret access key. This field is not
	// returned in RPC responses.
	SecretAccessKey string `json:"secretAccessKey,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccessKeyId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AccessKeyId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AwsAccessKey) MarshalJSON() ([]byte, error) {
	type NoMethod AwsAccessKey
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AwsS3Data: An AwsS3Data resource can be a data source, but not a data
// sink. In an AwsS3Data resource, an object's name is the S3 object's
// key name.
type AwsS3Data struct {
	// AwsAccessKey: Required. Input only. AWS access key used to sign the
	// API requests to the AWS S3 bucket. Permissions on the bucket must be
	// granted to the access ID of the AWS access key.
	AwsAccessKey *AwsAccessKey `json:"awsAccessKey,omitempty"`

	// BucketName: Required. S3 Bucket name (see [Creating a
	// bucket](https://docs.aws.amazon.com/AmazonS3/latest/dev/create-bucket-
	// get-location-example.html)).
	BucketName string `json:"bucketName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AwsAccessKey") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AwsAccessKey") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AwsS3Data) MarshalJSON() ([]byte, error) {
	type NoMethod AwsS3Data
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AzureBlobStorageData: An AzureBlobStorageData resource can be a data
// source, but not a data sink. An AzureBlobStorageData resource
// represents one Azure container. The storage account determines the
// [Azure
// endpoint](https://docs.microsoft.com/en-us/azure/storage/common/storag
// e-create-storage-account#storage-account-endpoints). In an
// AzureBlobStorageData resource, a blobs's name is the [Azure Blob
// Storage blob's key
// name](https://docs.microsoft.com/en-us/rest/api/storageservices/naming
// -and-referencing-containers--blobs--and-metadata#blob-names).
type AzureBlobStorageData struct {
	// AzureCredentials: Required. Input only. Credentials used to
	// authenticate API requests to Azure.
	AzureCredentials *AzureCredentials `json:"azureCredentials,omitempty"`

	// Container: Required. The container to transfer from the Azure Storage
	// account.
	Container string `json:"container,omitempty"`

	// StorageAccount: Required. The name of the Azure Storage account.
	StorageAccount string `json:"storageAccount,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AzureCredentials") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AzureCredentials") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AzureBlobStorageData) MarshalJSON() ([]byte, error) {
	type NoMethod AzureBlobStorageData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AzureCredentials: Azure credentials
type AzureCredentials struct {
	// SasToken: Required. Azure shared access signature. (see [Grant
	// limited access to Azure Storage resources using shared access
	// signatures
	// (SAS)](https://docs.microsoft.com/en-us/azure/storage/common/storage-s
	// as-overview)).
	SasToken string `json:"sasToken,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SasToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SasToken") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AzureCredentials) MarshalJSON() ([]byte, error) {
	type NoMethod AzureCredentials
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CancelOperationRequest: The request message for
// Operations.CancelOperation.
type CancelOperationRequest struct {
}

// Date: Represents a whole or partial calendar date, such as a
// birthday. The time of day and time zone are either specified
// elsewhere or are insignificant. The date is relative to the Gregorian
// Calendar. This can represent one of the following: * A full date,
// with non-zero year, month, and day values * A month and day value,
// with a zero year, such as an anniversary * A year on its own, with
// zero month and day values * A year and month value, with a zero day,
// such as a credit card expiration date Related types are
// google.type.TimeOfDay and `google.protobuf.Timestamp`.
type Date struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and
	// month, or 0 to specify a year by itself or a year and month where the
	// day isn't significant.
	Day int64 `json:"day,omitempty"`

	// Month: Month of a year. Must be from 1 to 12, or 0 to specify a year
	// without a month and day.
	Month int64 `json:"month,omitempty"`

	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a
	// date without a year.
	Year int64 `json:"year,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Day") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Day") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Date) MarshalJSON() ([]byte, error) {
	type NoMethod Date
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Empty: A generic empty message that you can re-use to avoid defining
// duplicated empty messages in your APIs. A typical example is to use
// it as the request or the response type of an API method. For
// instance: service Foo { rpc Bar(google.protobuf.Empty) returns
// (google.protobuf.Empty); } The JSON representation for `Empty` is
// empty JSON object `{}`.
type Empty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// ErrorLogEntry: An entry describing an error that has occurred.
type ErrorLogEntry struct {
	// ErrorDetails: A list of messages that carry the error details.
	ErrorDetails []string `json:"errorDetails,omitempty"`

	// Url: Required. A URL that refers to the target (a data source, a data
	// sink, or an object) with which the error is associated.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ErrorDetails") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ErrorDetails") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ErrorLogEntry) MarshalJSON() ([]byte, error) {
	type NoMethod ErrorLogEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ErrorSummary: A summary of errors by error code, plus a count and
// sample error log entries.
type ErrorSummary struct {
	// ErrorCode: Required.
	//
	// Possible values:
	//   "OK" - Not an error; returned on success HTTP Mapping: 200 OK
	//   "CANCELLED" - The operation was cancelled, typically by the caller.
	// HTTP Mapping: 499 Client Closed Request
	//   "UNKNOWN" - Unknown error. For example, this error may be returned
	// when a `Status` value received from another address space belongs to
	// an error space that is not known in this address space. Also errors
	// raised by APIs that do not return enough error information may be
	// converted to this error. HTTP Mapping: 500 Internal Server Error
	//   "INVALID_ARGUMENT" - The client specified an invalid argument. Note
	// that this differs from `FAILED_PRECONDITION`. `INVALID_ARGUMENT`
	// indicates arguments that are problematic regardless of the state of
	// the system (e.g., a malformed file name). HTTP Mapping: 400 Bad
	// Request
	//   "DEADLINE_EXCEEDED" - The deadline expired before the operation
	// could complete. For operations that change the state of the system,
	// this error may be returned even if the operation has completed
	// successfully. For example, a successful response from a server could
	// have been delayed long enough for the deadline to expire. HTTP
	// Mapping: 504 Gateway Timeout
	//   "NOT_FOUND" - Some requested entity (e.g., file or directory) was
	// not found. Note to server developers: if a request is denied for an
	// entire class of users, such as gradual feature rollout or
	// undocumented allowlist, `NOT_FOUND` may be used. If a request is
	// denied for some users within a class of users, such as user-based
	// access control, `PERMISSION_DENIED` must be used. HTTP Mapping: 404
	// Not Found
	//   "ALREADY_EXISTS" - The entity that a client attempted to create
	// (e.g., file or directory) already exists. HTTP Mapping: 409 Conflict
	//   "PERMISSION_DENIED" - The caller does not have permission to
	// execute the specified operation. `PERMISSION_DENIED` must not be used
	// for rejections caused by exhausting some resource (use
	// `RESOURCE_EXHAUSTED` instead for those errors). `PERMISSION_DENIED`
	// must not be used if the caller can not be identified (use
	// `UNAUTHENTICATED` instead for those errors). This error code does not
	// imply the request is valid or the requested entity exists or
	// satisfies other pre-conditions. HTTP Mapping: 403 Forbidden
	//   "UNAUTHENTICATED" - The request does not have valid authentication
	// credentials for the operation. HTTP Mapping: 401 Unauthorized
	//   "RESOURCE_EXHAUSTED" - Some resource has been exhausted, perhaps a
	// per-user quota, or perhaps the entire file system is out of space.
	// HTTP Mapping: 429 Too Many Requests
	//   "FAILED_PRECONDITION" - The operation was rejected because the
	// system is not in a state required for the operation's execution. For
	// example, the directory to be deleted is non-empty, an rmdir operation
	// is applied to a non-directory, etc. Service implementors can use the
	// following guidelines to decide between `FAILED_PRECONDITION`,
	// `ABORTED`, and `UNAVAILABLE`: (a) Use `UNAVAILABLE` if the client can
	// retry just the failing call. (b) Use `ABORTED` if the client should
	// retry at a higher level (e.g., when a client-specified test-and-set
	// fails, indicating the client should restart a read-modify-write
	// sequence). (c) Use `FAILED_PRECONDITION` if the client should not
	// retry until the system state has been explicitly fixed. E.g., if an
	// "rmdir" fails because the directory is non-empty,
	// `FAILED_PRECONDITION` should be returned since the client should not
	// retry unless the files are deleted from the directory. HTTP Mapping:
	// 400 Bad Request
	//   "ABORTED" - The operation was aborted, typically due to a
	// concurrency issue such as a sequencer check failure or transaction
	// abort. See the guidelines above for deciding between
	// `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. HTTP Mapping:
	// 409 Conflict
	//   "OUT_OF_RANGE" - The operation was attempted past the valid range.
	// E.g., seeking or reading past end-of-file. Unlike `INVALID_ARGUMENT`,
	// this error indicates a problem that may be fixed if the system state
	// changes. For example, a 32-bit file system will generate
	// `INVALID_ARGUMENT` if asked to read at an offset that is not in the
	// range [0,2^32-1], but it will generate `OUT_OF_RANGE` if asked to
	// read from an offset past the current file size. There is a fair bit
	// of overlap between `FAILED_PRECONDITION` and `OUT_OF_RANGE`. We
	// recommend using `OUT_OF_RANGE` (the more specific error) when it
	// applies so that callers who are iterating through a space can easily
	// look for an `OUT_OF_RANGE` error to detect when they are done. HTTP
	// Mapping: 400 Bad Request
	//   "UNIMPLEMENTED" - The operation is not implemented or is not
	// supported/enabled in this service. HTTP Mapping: 501 Not Implemented
	//   "INTERNAL" - Internal errors. This means that some invariants
	// expected by the underlying system have been broken. This error code
	// is reserved for serious errors. HTTP Mapping: 500 Internal Server
	// Error
	//   "UNAVAILABLE" - The service is currently unavailable. This is most
	// likely a transient condition, which can be corrected by retrying with
	// a backoff. Note that it is not always safe to retry non-idempotent
	// operations. See the guidelines above for deciding between
	// `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. HTTP Mapping:
	// 503 Service Unavailable
	//   "DATA_LOSS" - Unrecoverable data loss or corruption. HTTP Mapping:
	// 500 Internal Server Error
	ErrorCode string `json:"errorCode,omitempty"`

	// ErrorCount: Required. Count of this type of error.
	ErrorCount int64 `json:"errorCount,omitempty,string"`

	// ErrorLogEntries: Error samples. At most 5 error log entries will be
	// recorded for a given error code for a single transfer operation.
	ErrorLogEntries []*ErrorLogEntry `json:"errorLogEntries,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ErrorCode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ErrorCode") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ErrorSummary) MarshalJSON() ([]byte, error) {
	type NoMethod ErrorSummary
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GcsData: In a GcsData resource, an object's name is the Cloud Storage
// object's name and its "last modification time" refers to the object's
// `updated` property of Cloud Storage objects, which changes when the
// content or the metadata of the object is updated.
type GcsData struct {
	// BucketName: Required. Cloud Storage bucket name (see [Bucket Name
	// Requirements](https://cloud.google.com/storage/docs/naming#requirement
	// s)).
	BucketName string `json:"bucketName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BucketName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BucketName") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GcsData) MarshalJSON() ([]byte, error) {
	type NoMethod GcsData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleServiceAccount: Google service account
type GoogleServiceAccount struct {
	// AccountEmail: Email address of the service account.
	AccountEmail string `json:"accountEmail,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountEmail") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AccountEmail") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleServiceAccount) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleServiceAccount
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HttpData: An HttpData resource specifies a list of objects on the web
// to be transferred over HTTP. The information of the objects to be
// transferred is contained in a file referenced by a URL. The first
// line in the file must be "TsvHttpData-1.0", which specifies the
// format of the file. Subsequent lines specify the information of the
// list of objects, one object per list entry. Each entry has the
// following tab-delimited fields: * **HTTP URL** — The location of
// the object. * **Length** — The size of the object in bytes. *
// **MD5** — The base64-encoded MD5 hash of the object. For an example
// of a valid TSV file, see [Transferring data from
// URLs](https://cloud.google.com/storage-transfer/docs/create-url-list).
//  When transferring data based on a URL list, keep the following in
// mind: * When an object located at `http(s)://hostname:port/` is
// transferred to a data sink, the name of the object at the data sink
// is `/`. * If the specified size of an object does not match the
// actual size of the object fetched, the object will not be
// transferred. * If the specified MD5 does not match the MD5 computed
// from the transferred bytes, the object transfer will fail. For more
// information, see [Generating MD5
// hashes](https://cloud.google.com/storage-transfer/docs/create-url-list
// #md5) * Ensure that each URL you specify is publicly accessible. For
// example, in Cloud Storage you can [share an object publicly]
// (https://cloud.google.com/storage/docs/cloud-console#_sharingdata)
// and get a link to it. * Storage Transfer Service obeys `robots.txt`
// rules and requires the source HTTP server to support `Range` requests
// and to return a `Content-Length` header in each response. *
// ObjectConditions have no effect when filtering objects to transfer.
type HttpData struct {
	// ListUrl: Required. The URL that points to the file that stores the
	// object list entries. This file must allow public access. Currently,
	// only URLs with HTTP and HTTPS schemes are supported.
	ListUrl string `json:"listUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ListUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ListUrl") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *HttpData) MarshalJSON() ([]byte, error) {
	type NoMethod HttpData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListOperationsResponse: The response message for
// Operations.ListOperations.
type ListOperationsResponse struct {
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Operations: A list of operations that matches the specified filter in
	// the request.
	Operations []*Operation `json:"operations,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListOperationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListOperationsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListTransferJobsResponse: Response from ListTransferJobs.
type ListTransferJobsResponse struct {
	// NextPageToken: The list next page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TransferJobs: A list of transfer jobs.
	TransferJobs []*TransferJob `json:"transferJobs,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListTransferJobsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListTransferJobsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotificationConfig: Specification to configure notifications
// published to Cloud Pub/Sub. Notifications will be published to the
// customer-provided topic using the following
// `PubsubMessage.attributes`: * "eventType": one of the EventType
// values * "payloadFormat": one of the PayloadFormat values *
// "projectId": the project_id of the `TransferOperation` *
// "transferJobName": the transfer_job_name of the `TransferOperation`
// * "transferOperationName": the name of the `TransferOperation` The
// `PubsubMessage.data` will contain a TransferOperation resource
// formatted according to the specified `PayloadFormat`.
type NotificationConfig struct {
	// EventTypes: Event types for which a notification is desired. If
	// empty, send notifications for all event types.
	//
	// Possible values:
	//   "EVENT_TYPE_UNSPECIFIED" - Illegal value, to avoid allowing a
	// default.
	//   "TRANSFER_OPERATION_SUCCESS" - `TransferOperation` completed with
	// status SUCCESS.
	//   "TRANSFER_OPERATION_FAILED" - `TransferOperation` completed with
	// status FAILED.
	//   "TRANSFER_OPERATION_ABORTED" - `TransferOperation` completed with
	// status ABORTED.
	EventTypes []string `json:"eventTypes,omitempty"`

	// PayloadFormat: Required. The desired format of the notification
	// message payloads.
	//
	// Possible values:
	//   "PAYLOAD_FORMAT_UNSPECIFIED" - Illegal value, to avoid allowing a
	// default.
	//   "NONE" - No payload is included with the notification.
	//   "JSON" - `TransferOperation` is [formatted as a JSON
	// response](https://developers.google.com/protocol-buffers/docs/proto3#j
	// son), in application/json.
	PayloadFormat string `json:"payloadFormat,omitempty"`

	// PubsubTopic: Required. The `Topic.name` of the Cloud Pub/Sub topic to
	// which to publish notifications. Must be of the format:
	// `projects/{project}/topics/{topic}`. Not matching this format will
	// result in an INVALID_ARGUMENT error.
	PubsubTopic string `json:"pubsubTopic,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EventTypes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EventTypes") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NotificationConfig) MarshalJSON() ([]byte, error) {
	type NoMethod NotificationConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ObjectConditions: Conditions that determine which objects will be
// transferred. Applies only to Cloud Data Sources such as S3, Azure,
// and Cloud Storage. The "last modification time" refers to the time of
// the last change to the object's content or metadata — specifically,
// this is the `updated` property of Cloud Storage objects, the
// `LastModified` field of S3 objects, and the `Last-Modified` header of
// Azure blobs.
type ObjectConditions struct {
	// ExcludePrefixes: `exclude_prefixes` must follow the requirements
	// described for include_prefixes. The max size of `exclude_prefixes` is
	// 1000.
	ExcludePrefixes []string `json:"excludePrefixes,omitempty"`

	// IncludePrefixes: If `include_prefixes` is specified, objects that
	// satisfy the object conditions must have names that start with one of
	// the `include_prefixes` and that do not start with any of the
	// exclude_prefixes. If `include_prefixes` is not specified, all objects
	// except those that have names starting with one of the
	// `exclude_prefixes` must satisfy the object conditions. Requirements:
	// * Each include-prefix and exclude-prefix can contain any sequence of
	// Unicode characters, to a max length of 1024 bytes when UTF8-encoded,
	// and must not contain Carriage Return or Line Feed characters.
	// Wildcard matching and regular expression matching are not supported.
	// * Each include-prefix and exclude-prefix must omit the leading slash.
	// For example, to include the `requests.gz` object in a transfer from
	// `s3://my-aws-bucket/logs/y=2015/requests.gz`, specify the include
	// prefix as `logs/y=2015/requests.gz`. * None of the include-prefix or
	// the exclude-prefix values can be empty, if specified. * Each
	// include-prefix must include a distinct portion of the object
	// namespace. No include-prefix may be a prefix of another
	// include-prefix. * Each exclude-prefix must exclude a distinct portion
	// of the object namespace. No exclude-prefix may be a prefix of another
	// exclude-prefix. * If `include_prefixes` is specified, then each
	// exclude-prefix must start with the value of a path explicitly
	// included by `include_prefixes`. The max size of `include_prefixes` is
	// 1000.
	IncludePrefixes []string `json:"includePrefixes,omitempty"`

	// LastModifiedBefore: If specified, only objects with a "last
	// modification time" before this timestamp and objects that don't have
	// a "last modification time" will be transferred.
	LastModifiedBefore string `json:"lastModifiedBefore,omitempty"`

	// LastModifiedSince: If specified, only objects with a "last
	// modification time" on or after this timestamp and objects that don't
	// have a "last modification time" are transferred. The
	// `last_modified_since` and `last_modified_before` fields can be used
	// together for chunked data processing. For example, consider a script
	// that processes each day's worth of data at a time. For that you'd set
	// each of the fields as follows: * `last_modified_since` to the start
	// of the day * `last_modified_before` to the end of the day
	LastModifiedSince string `json:"lastModifiedSince,omitempty"`

	// MaxTimeElapsedSinceLastModification: If specified, only objects with
	// a "last modification time" on or after `NOW` -
	// `max_time_elapsed_since_last_modification` and objects that don't
	// have a "last modification time" are transferred. For each
	// TransferOperation started by this TransferJob, `NOW` refers to the
	// start_time of the `TransferOperation`.
	MaxTimeElapsedSinceLastModification string `json:"maxTimeElapsedSinceLastModification,omitempty"`

	// MinTimeElapsedSinceLastModification: If specified, only objects with
	// a "last modification time" before `NOW` -
	// `min_time_elapsed_since_last_modification` and objects that don't
	// have a "last modification time" are transferred. For each
	// TransferOperation started by this TransferJob, `NOW` refers to the
	// start_time of the `TransferOperation`.
	MinTimeElapsedSinceLastModification string `json:"minTimeElapsedSinceLastModification,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExcludePrefixes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ExcludePrefixes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ObjectConditions) MarshalJSON() ([]byte, error) {
	type NoMethod ObjectConditions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Operation: This resource represents a long-running operation that is
// the result of a network API call.
type Operation struct {
	// Done: If the value is `false`, it means the operation is still in
	// progress. If `true`, the operation is completed, and either `error`
	// or `response` is available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *Status `json:"error,omitempty"`

	// Metadata: Represents the transfer operation object. To request a
	// TransferOperation object, use transferOperations.get.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that originally returns it. If you use the default HTTP
	// mapping, the `name` should have the format of
	// `transferOperations/some/unique/name`.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success. If
	// the original method returns no data on success, such as `Delete`, the
	// response is `google.protobuf.Empty`. If the original method is
	// standard `Get`/`Create`/`Update`, the response should be the
	// resource. For other methods, the response should have the type
	// `XxxResponse`, where `Xxx` is the original method name. For example,
	// if the original method name is `TakeSnapshot()`, the inferred
	// response type is `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Done") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Done") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PauseTransferOperationRequest: Request passed to
// PauseTransferOperation.
type PauseTransferOperationRequest struct {
}

// ResumeTransferOperationRequest: Request passed to
// ResumeTransferOperation.
type ResumeTransferOperationRequest struct {
}

// Schedule: Transfers can be scheduled to recur or to run just once.
type Schedule struct {
	// ScheduleEndDate: The last day a transfer runs. Date boundaries are
	// determined relative to UTC time. A job will run once per 24 hours
	// within the following guidelines: * If `schedule_end_date` and
	// schedule_start_date are the same and in the future relative to UTC,
	// the transfer is executed only one time. * If `schedule_end_date` is
	// later than `schedule_start_date` and `schedule_end_date` is in the
	// future relative to UTC, the job will run each day at
	// start_time_of_day through `schedule_end_date`.
	ScheduleEndDate *Date `json:"scheduleEndDate,omitempty"`

	// ScheduleStartDate: Required. The start date of a transfer. Date
	// boundaries are determined relative to UTC time. If
	// `schedule_start_date` and start_time_of_day are in the past relative
	// to the job's creation time, the transfer starts the day after you
	// schedule the transfer request. **Note:** When starting jobs at or
	// near midnight UTC it is possible that a job will start later than
	// expected. For example, if you send an outbound request on June 1 one
	// millisecond prior to midnight UTC and the Storage Transfer Service
	// server receives the request on June 2, then it will create a
	// TransferJob with `schedule_start_date` set to June 2 and a
	// `start_time_of_day` set to midnight UTC. The first scheduled
	// TransferOperation will take place on June 3 at midnight UTC.
	ScheduleStartDate *Date `json:"scheduleStartDate,omitempty"`

	// StartTimeOfDay: The time in UTC that a transfer job is scheduled to
	// run. Transfers may start later than this time. If `start_time_of_day`
	// is not specified: * One-time transfers run immediately. * Recurring
	// transfers run immediately, and each day at midnight UTC, through
	// schedule_end_date. If `start_time_of_day` is specified: * One-time
	// transfers run at the specified time. * Recurring transfers run at the
	// specified time each day, through `schedule_end_date`.
	StartTimeOfDay *TimeOfDay `json:"startTimeOfDay,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ScheduleEndDate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ScheduleEndDate") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Schedule) MarshalJSON() ([]byte, error) {
	type NoMethod Schedule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Status: The `Status` type defines a logical error model that is
// suitable for different programming environments, including REST APIs
// and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each
// `Status` message contains three pieces of data: error code, error
// message, and error details. You can find out more about this error
// model and how to work with it in the [API Design
// Guide](https://cloud.google.com/apis/design/errors).
type Status struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details. There is a
	// common set of message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any user-facing error message should be localized and sent
	// in the google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Status) MarshalJSON() ([]byte, error) {
	type NoMethod Status
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TimeOfDay: Represents a time of day. The date and time zone are
// either not significant or are specified elsewhere. An API may choose
// to allow leap seconds. Related types are google.type.Date and
// `google.protobuf.Timestamp`.
type TimeOfDay struct {
	// Hours: Hours of day in 24 hour format. Should be from 0 to 23. An API
	// may choose to allow the value "24:00:00" for scenarios like business
	// closing time.
	Hours int64 `json:"hours,omitempty"`

	// Minutes: Minutes of hour of day. Must be from 0 to 59.
	Minutes int64 `json:"minutes,omitempty"`

	// Nanos: Fractions of seconds in nanoseconds. Must be from 0 to
	// 999,999,999.
	Nanos int64 `json:"nanos,omitempty"`

	// Seconds: Seconds of minutes of the time. Must normally be from 0 to
	// 59. An API may allow the value 60 if it allows leap-seconds.
	Seconds int64 `json:"seconds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Hours") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Hours") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TimeOfDay) MarshalJSON() ([]byte, error) {
	type NoMethod TimeOfDay
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TransferCounters: A collection of counters that report the progress
// of a transfer operation.
type TransferCounters struct {
	// BytesCopiedToSink: Bytes that are copied to the data sink.
	BytesCopiedToSink int64 `json:"bytesCopiedToSink,omitempty,string"`

	// BytesDeletedFromSink: Bytes that are deleted from the data sink.
	BytesDeletedFromSink int64 `json:"bytesDeletedFromSink,omitempty,string"`

	// BytesDeletedFromSource: Bytes that are deleted from the data source.
	BytesDeletedFromSource int64 `json:"bytesDeletedFromSource,omitempty,string"`

	// BytesFailedToDeleteFromSink: Bytes that failed to be deleted from the
	// data sink.
	BytesFailedToDeleteFromSink int64 `json:"bytesFailedToDeleteFromSink,omitempty,string"`

	// BytesFoundFromSource: Bytes found in the data source that are
	// scheduled to be transferred, excluding any that are filtered based on
	// object conditions or skipped due to sync.
	BytesFoundFromSource int64 `json:"bytesFoundFromSource,omitempty,string"`

	// BytesFoundOnlyFromSink: Bytes found only in the data sink that are
	// scheduled to be deleted.
	BytesFoundOnlyFromSink int64 `json:"bytesFoundOnlyFromSink,omitempty,string"`

	// BytesFromSourceFailed: Bytes in the data source that failed to be
	// transferred or that failed to be deleted after being transferred.
	BytesFromSourceFailed int64 `json:"bytesFromSourceFailed,omitempty,string"`

	// BytesFromSourceSkippedBySync: Bytes in the data source that are not
	// transferred because they already exist in the data sink.
	BytesFromSourceSkippedBySync int64 `json:"bytesFromSourceSkippedBySync,omitempty,string"`

	// ObjectsCopiedToSink: Objects that are copied to the data sink.
	ObjectsCopiedToSink int64 `json:"objectsCopiedToSink,omitempty,string"`

	// ObjectsDeletedFromSink: Objects that are deleted from the data sink.
	ObjectsDeletedFromSink int64 `json:"objectsDeletedFromSink,omitempty,string"`

	// ObjectsDeletedFromSource: Objects that are deleted from the data
	// source.
	ObjectsDeletedFromSource int64 `json:"objectsDeletedFromSource,omitempty,string"`

	// ObjectsFailedToDeleteFromSink: Objects that failed to be deleted from
	// the data sink.
	ObjectsFailedToDeleteFromSink int64 `json:"objectsFailedToDeleteFromSink,omitempty,string"`

	// ObjectsFoundFromSource: Objects found in the data source that are
	// scheduled to be transferred, excluding any that are filtered based on
	// object conditions or skipped due to sync.
	ObjectsFoundFromSource int64 `json:"objectsFoundFromSource,omitempty,string"`

	// ObjectsFoundOnlyFromSink: Objects found only in the data sink that
	// are scheduled to be deleted.
	ObjectsFoundOnlyFromSink int64 `json:"objectsFoundOnlyFromSink,omitempty,string"`

	// ObjectsFromSourceFailed: Objects in the data source that failed to be
	// transferred or that failed to be deleted after being transferred.
	ObjectsFromSourceFailed int64 `json:"objectsFromSourceFailed,omitempty,string"`

	// ObjectsFromSourceSkippedBySync: Objects in the data source that are
	// not transferred because they already exist in the data sink.
	ObjectsFromSourceSkippedBySync int64 `json:"objectsFromSourceSkippedBySync,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "BytesCopiedToSink")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BytesCopiedToSink") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TransferCounters) MarshalJSON() ([]byte, error) {
	type NoMethod TransferCounters
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TransferJob: This resource represents the configuration of a transfer
// job that runs periodically.
type TransferJob struct {
	// CreationTime: Output only. The time that the transfer job was
	// created.
	CreationTime string `json:"creationTime,omitempty"`

	// DeletionTime: Output only. The time that the transfer job was
	// deleted.
	DeletionTime string `json:"deletionTime,omitempty"`

	// Description: A description provided by the user for the job. Its max
	// length is 1024 bytes when Unicode-encoded.
	Description string `json:"description,omitempty"`

	// LastModificationTime: Output only. The time that the transfer job was
	// last modified.
	LastModificationTime string `json:"lastModificationTime,omitempty"`

	// LatestOperationName: The name of the most recently started
	// TransferOperation of this JobConfig. Present if and only if at least
	// one TransferOperation has been created for this JobConfig.
	LatestOperationName string `json:"latestOperationName,omitempty"`

	// Name: A unique name (within the transfer project) assigned when the
	// job is created. If this field is empty in a CreateTransferJobRequest,
	// Storage Transfer Service will assign a unique name. Otherwise, the
	// specified name is used as the unique name for this job. If the
	// specified name is in use by a job, the creation request fails with an
	// ALREADY_EXISTS error. This name must start with "transferJobs/"
	// prefix and end with a letter or a number, and should be no more than
	// 128 characters. Example:
	// "transferJobs/[A-Za-z0-9-._~]*[A-Za-z0-9]$" Invalid job names will
	// fail with an INVALID_ARGUMENT error.
	Name string `json:"name,omitempty"`

	// NotificationConfig: Notification configuration.
	NotificationConfig *NotificationConfig `json:"notificationConfig,omitempty"`

	// ProjectId: The ID of the Google Cloud Platform Project that owns the
	// job.
	ProjectId string `json:"projectId,omitempty"`

	// Schedule: Schedule specification.
	Schedule *Schedule `json:"schedule,omitempty"`

	// Status: Status of the job. This value MUST be specified for
	// `CreateTransferJobRequests`. **Note:** The effect of the new job
	// status takes place during a subsequent job run. For example, if you
	// change the job status from ENABLED to DISABLED, and an operation
	// spawned by the transfer is running, the status change would not
	// affect the current operation.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Zero is an illegal value.
	//   "ENABLED" - New transfers will be performed based on the schedule.
	//   "DISABLED" - New transfers will not be scheduled.
	//   "DELETED" - This is a soft delete state. After a transfer job is
	// set to this state, the job and all the transfer executions are
	// subject to garbage collection. Transfer jobs become eligible for
	// garbage collection 30 days after their status is set to `DELETED`.
	Status string `json:"status,omitempty"`

	// TransferSpec: Transfer specification.
	TransferSpec *TransferSpec `json:"transferSpec,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreationTime") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreationTime") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TransferJob) MarshalJSON() ([]byte, error) {
	type NoMethod TransferJob
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TransferOperation: A description of the execution of a transfer.
type TransferOperation struct {
	// Counters: Information about the progress of the transfer operation.
	Counters *TransferCounters `json:"counters,omitempty"`

	// EndTime: End time of this transfer execution.
	EndTime string `json:"endTime,omitempty"`

	// ErrorBreakdowns: Summarizes errors encountered with sample error log
	// entries.
	ErrorBreakdowns []*ErrorSummary `json:"errorBreakdowns,omitempty"`

	// Name: A globally unique ID assigned by the system.
	Name string `json:"name,omitempty"`

	// NotificationConfig: Notification configuration.
	NotificationConfig *NotificationConfig `json:"notificationConfig,omitempty"`

	// ProjectId: The ID of the Google Cloud Platform Project that owns the
	// operation.
	ProjectId string `json:"projectId,omitempty"`

	// StartTime: Start time of this transfer execution.
	StartTime string `json:"startTime,omitempty"`

	// Status: Status of the transfer operation.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Zero is an illegal value.
	//   "IN_PROGRESS" - In progress.
	//   "PAUSED" - Paused.
	//   "SUCCESS" - Completed successfully.
	//   "FAILED" - Terminated due to an unrecoverable failure.
	//   "ABORTED" - Aborted by the user.
	//   "QUEUED" - Temporarily delayed by the system. No user action is
	// required.
	Status string `json:"status,omitempty"`

	// TransferJobName: The name of the transfer job that triggers this
	// transfer operation.
	TransferJobName string `json:"transferJobName,omitempty"`

	// TransferSpec: Transfer specification.
	TransferSpec *TransferSpec `json:"transferSpec,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Counters") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Counters") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TransferOperation) MarshalJSON() ([]byte, error) {
	type NoMethod TransferOperation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TransferOptions: TransferOptions define the actions to be performed
// on objects in a transfer.
type TransferOptions struct {
	// DeleteObjectsFromSourceAfterTransfer: Whether objects should be
	// deleted from the source after they are transferred to the sink.
	// **Note:** This option and delete_objects_unique_in_sink are mutually
	// exclusive.
	DeleteObjectsFromSourceAfterTransfer bool `json:"deleteObjectsFromSourceAfterTransfer,omitempty"`

	// DeleteObjectsUniqueInSink: Whether objects that exist only in the
	// sink should be deleted. **Note:** This option and
	// delete_objects_from_source_after_transfer are mutually exclusive.
	DeleteObjectsUniqueInSink bool `json:"deleteObjectsUniqueInSink,omitempty"`

	// OverwriteObjectsAlreadyExistingInSink: Whether overwriting objects
	// that already exist in the sink is allowed.
	OverwriteObjectsAlreadyExistingInSink bool `json:"overwriteObjectsAlreadyExistingInSink,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "DeleteObjectsFromSourceAfterTransfer") to unconditionally include in
	// API requests. By default, fields with empty values are omitted from
	// API requests. However, any non-pointer, non-interface field appearing
	// in ForceSendFields will be sent to the server regardless of whether
	// the field is empty or not. This may be used to include empty fields
	// in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g.
	// "DeleteObjectsFromSourceAfterTransfer") to include in API requests
	// with the JSON null value. By default, fields with empty values are
	// omitted from API requests. However, any field with an empty value
	// appearing in NullFields will be sent to the server as null. It is an
	// error if a field in this list has a non-empty value. This may be used
	// to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TransferOptions) MarshalJSON() ([]byte, error) {
	type NoMethod TransferOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TransferSpec: Configuration for running a transfer.
type TransferSpec struct {
	// AwsS3DataSource: An AWS S3 data source.
	AwsS3DataSource *AwsS3Data `json:"awsS3DataSource,omitempty"`

	// AzureBlobStorageDataSource: An Azure Blob Storage data source.
	AzureBlobStorageDataSource *AzureBlobStorageData `json:"azureBlobStorageDataSource,omitempty"`

	// GcsDataSink: A Cloud Storage data sink.
	GcsDataSink *GcsData `json:"gcsDataSink,omitempty"`

	// GcsDataSource: A Cloud Storage data source.
	GcsDataSource *GcsData `json:"gcsDataSource,omitempty"`

	// HttpDataSource: An HTTP URL data source.
	HttpDataSource *HttpData `json:"httpDataSource,omitempty"`

	// ObjectConditions: Only objects that satisfy these object conditions
	// are included in the set of data source and data sink objects. Object
	// conditions based on objects' "last modification time" do not exclude
	// objects in a data sink.
	ObjectConditions *ObjectConditions `json:"objectConditions,omitempty"`

	// TransferOptions: If the option delete_objects_unique_in_sink is
	// `true` and time-based object conditions such as 'last modification
	// time' are specified, the request fails with an INVALID_ARGUMENT
	// error.
	TransferOptions *TransferOptions `json:"transferOptions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AwsS3DataSource") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AwsS3DataSource") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TransferSpec) MarshalJSON() ([]byte, error) {
	type NoMethod TransferSpec
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTransferJobRequest: Request passed to UpdateTransferJob.
type UpdateTransferJobRequest struct {
	// ProjectId: Required. The ID of the Google Cloud Platform Console
	// project that owns the job.
	ProjectId string `json:"projectId,omitempty"`

	// TransferJob: Required. The job to update. `transferJob` is expected
	// to specify only four fields: description, transfer_spec,
	// notification_config, and status. An `UpdateTransferJobRequest` that
	// specifies other fields will be rejected with the error
	// INVALID_ARGUMENT. Updating a job satus to DELETED requires
	// `storagetransfer.jobs.delete` permissions.
	TransferJob *TransferJob `json:"transferJob,omitempty"`

	// UpdateTransferJobFieldMask: The field mask of the fields in
	// `transferJob` that are to be updated in this request. Fields in
	// `transferJob` that can be updated are: description, transfer_spec,
	// notification_config, and status. To update the `transfer_spec` of the
	// job, a complete transfer specification must be provided. An
	// incomplete specification missing any required fields will be rejected
	// with the error INVALID_ARGUMENT.
	UpdateTransferJobFieldMask string `json:"updateTransferJobFieldMask,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ProjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ProjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTransferJobRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTransferJobRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "storagetransfer.googleServiceAccounts.get":

type GoogleServiceAccountsGetCall struct {
	s            *Service
	projectId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the Google service account that is used by Storage
// Transfer Service to access buckets in the project where transfers run
// or in other projects. Each Google service account is associated with
// one Google Cloud Platform Console project. Users should add this
// service account to the Google Cloud Storage bucket ACLs to grant
// access to Storage Transfer Service. This service account is created
// and owned by Storage Transfer Service and can only be used by Storage
// Transfer Service.
func (r *GoogleServiceAccountsService) Get(projectId string) *GoogleServiceAccountsGetCall {
	c := &GoogleServiceAccountsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *GoogleServiceAccountsGetCall) Fields(s ...googleapi.Field) *GoogleServiceAccountsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *GoogleServiceAccountsGetCall) IfNoneMatch(entityTag string) *GoogleServiceAccountsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *GoogleServiceAccountsGetCall) Context(ctx context.Context) *GoogleServiceAccountsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *GoogleServiceAccountsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GoogleServiceAccountsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/googleServiceAccounts/{projectId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"projectId": c.projectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.googleServiceAccounts.get" call.
// Exactly one of *GoogleServiceAccount or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleServiceAccount.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *GoogleServiceAccountsGetCall) Do(opts ...googleapi.CallOption) (*GoogleServiceAccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleServiceAccount{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the Google service account that is used by Storage Transfer Service to access buckets in the project where transfers run or in other projects. Each Google service account is associated with one Google Cloud Platform Console project. Users should add this service account to the Google Cloud Storage bucket ACLs to grant access to Storage Transfer Service. This service account is created and owned by Storage Transfer Service and can only be used by Storage Transfer Service.",
	//   "flatPath": "v1/googleServiceAccounts/{projectId}",
	//   "httpMethod": "GET",
	//   "id": "storagetransfer.googleServiceAccounts.get",
	//   "parameterOrder": [
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "projectId": {
	//       "description": "Required. The ID of the Google Cloud Platform Console project that the Google service account is associated with.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/googleServiceAccounts/{projectId}",
	//   "response": {
	//     "$ref": "GoogleServiceAccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "storagetransfer.transferJobs.create":

type TransferJobsCreateCall struct {
	s           *Service
	transferjob *TransferJob
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Create: Creates a transfer job that runs periodically.
func (r *TransferJobsService) Create(transferjob *TransferJob) *TransferJobsCreateCall {
	c := &TransferJobsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.transferjob = transferjob
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferJobsCreateCall) Fields(s ...googleapi.Field) *TransferJobsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferJobsCreateCall) Context(ctx context.Context) *TransferJobsCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferJobsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferJobsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.transferjob)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/transferJobs")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferJobs.create" call.
// Exactly one of *TransferJob or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TransferJob.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TransferJobsCreateCall) Do(opts ...googleapi.CallOption) (*TransferJob, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TransferJob{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a transfer job that runs periodically.",
	//   "flatPath": "v1/transferJobs",
	//   "httpMethod": "POST",
	//   "id": "storagetransfer.transferJobs.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/transferJobs",
	//   "request": {
	//     "$ref": "TransferJob"
	//   },
	//   "response": {
	//     "$ref": "TransferJob"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "storagetransfer.transferJobs.get":

type TransferJobsGetCall struct {
	s            *Service
	jobName      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a transfer job.
func (r *TransferJobsService) Get(jobName string, projectId string) *TransferJobsGetCall {
	c := &TransferJobsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.jobName = jobName
	c.urlParams_.Set("projectId", projectId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferJobsGetCall) Fields(s ...googleapi.Field) *TransferJobsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TransferJobsGetCall) IfNoneMatch(entityTag string) *TransferJobsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferJobsGetCall) Context(ctx context.Context) *TransferJobsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferJobsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferJobsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+jobName}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"jobName": c.jobName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferJobs.get" call.
// Exactly one of *TransferJob or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TransferJob.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TransferJobsGetCall) Do(opts ...googleapi.CallOption) (*TransferJob, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TransferJob{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a transfer job.",
	//   "flatPath": "v1/transferJobs/{transferJobsId}",
	//   "httpMethod": "GET",
	//   "id": "storagetransfer.transferJobs.get",
	//   "parameterOrder": [
	//     "jobName",
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "jobName": {
	//       "description": "Required. \" The job to get.",
	//       "location": "path",
	//       "pattern": "^transferJobs/.*$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. The ID of the Google Cloud Platform Console project that owns the job.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+jobName}",
	//   "response": {
	//     "$ref": "TransferJob"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "storagetransfer.transferJobs.list":

type TransferJobsListCall struct {
	s            *Service
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists transfer jobs.
func (r *TransferJobsService) List(filter string) *TransferJobsListCall {
	c := &TransferJobsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The list page size.
// The max allowed value is 256.
func (c *TransferJobsListCall) PageSize(pageSize int64) *TransferJobsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The list page
// token.
func (c *TransferJobsListCall) PageToken(pageToken string) *TransferJobsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferJobsListCall) Fields(s ...googleapi.Field) *TransferJobsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TransferJobsListCall) IfNoneMatch(entityTag string) *TransferJobsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferJobsListCall) Context(ctx context.Context) *TransferJobsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferJobsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferJobsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/transferJobs")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferJobs.list" call.
// Exactly one of *ListTransferJobsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListTransferJobsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TransferJobsListCall) Do(opts ...googleapi.CallOption) (*ListTransferJobsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListTransferJobsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists transfer jobs.",
	//   "flatPath": "v1/transferJobs",
	//   "httpMethod": "GET",
	//   "id": "storagetransfer.transferJobs.list",
	//   "parameterOrder": [
	//     "filter"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Required. A list of query parameters specified as JSON text in the form of: `{\"projectId\":\"my_project_id\", \"jobNames\":[\"jobid1\",\"jobid2\",...], \"jobStatuses\":[\"status1\",\"status2\",...]}` Since `jobNames` and `jobStatuses` support multiple values, their values must be specified with array notation. `projectId` is required. `jobNames` and `jobStatuses` are optional. The valid values for `jobStatuses` are case-insensitive: ENABLED, DISABLED, and DELETED.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The list page size. The max allowed value is 256.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/transferJobs",
	//   "response": {
	//     "$ref": "ListTransferJobsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TransferJobsListCall) Pages(ctx context.Context, f func(*ListTransferJobsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "storagetransfer.transferJobs.patch":

type TransferJobsPatchCall struct {
	s                        *Service
	jobName                  string
	updatetransferjobrequest *UpdateTransferJobRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// Patch: Updates a transfer job. Updating a job's transfer spec does
// not affect transfer operations that are running already. Updating a
// job's schedule is not allowed. **Note:** The job's status field can
// be modified using this RPC (for example, to set a job's status to
// DELETED, DISABLED, or ENABLED).
func (r *TransferJobsService) Patch(jobName string, updatetransferjobrequest *UpdateTransferJobRequest) *TransferJobsPatchCall {
	c := &TransferJobsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.jobName = jobName
	c.updatetransferjobrequest = updatetransferjobrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferJobsPatchCall) Fields(s ...googleapi.Field) *TransferJobsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferJobsPatchCall) Context(ctx context.Context) *TransferJobsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferJobsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferJobsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.updatetransferjobrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+jobName}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"jobName": c.jobName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferJobs.patch" call.
// Exactly one of *TransferJob or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TransferJob.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TransferJobsPatchCall) Do(opts ...googleapi.CallOption) (*TransferJob, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TransferJob{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a transfer job. Updating a job's transfer spec does not affect transfer operations that are running already. Updating a job's schedule is not allowed. **Note:** The job's status field can be modified using this RPC (for example, to set a job's status to DELETED, DISABLED, or ENABLED).",
	//   "flatPath": "v1/transferJobs/{transferJobsId}",
	//   "httpMethod": "PATCH",
	//   "id": "storagetransfer.transferJobs.patch",
	//   "parameterOrder": [
	//     "jobName"
	//   ],
	//   "parameters": {
	//     "jobName": {
	//       "description": "Required. The name of job to update.",
	//       "location": "path",
	//       "pattern": "^transferJobs/.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+jobName}",
	//   "request": {
	//     "$ref": "UpdateTransferJobRequest"
	//   },
	//   "response": {
	//     "$ref": "TransferJob"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "storagetransfer.transferOperations.cancel":

type TransferOperationsCancelCall struct {
	s                      *Service
	name                   string
	canceloperationrequest *CancelOperationRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Cancel: Cancels a transfer. Use the transferOperations.get method to
// check if the cancellation succeeded or if the operation completed
// despite the `cancel` request. When you cancel an operation, the
// currently running transfer is interrupted. For recurring transfer
// jobs, the next instance of the transfer job will still run. For
// example, if your job is configured to run every day at 1pm and you
// cancel Monday's operation at 1:05pm, Monday's transfer will stop.
// However, a transfer job will still be attempted on Tuesday. This
// applies only to currently running operations. If an operation is not
// currently running, `cancel` does nothing. *Caution:* Canceling a
// transfer job can leave your data in an unknown state. We recommend
// that you restore the state at both the destination and the source
// after the `cancel` request completes so that your data is in a
// consistent state. When you cancel a job, the next job computes a
// delta of files and may repair any inconsistent state. For instance,
// if you run a job every day, and today's job found 10 new files and
// transferred five files before you canceled the job, tomorrow's
// transfer operation will compute a new delta with the five files that
// were not copied today plus any new files discovered tomorrow.
func (r *TransferOperationsService) Cancel(name string, canceloperationrequest *CancelOperationRequest) *TransferOperationsCancelCall {
	c := &TransferOperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.canceloperationrequest = canceloperationrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferOperationsCancelCall) Fields(s ...googleapi.Field) *TransferOperationsCancelCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferOperationsCancelCall) Context(ctx context.Context) *TransferOperationsCancelCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferOperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferOperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.canceloperationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferOperations.cancel" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *TransferOperationsCancelCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Cancels a transfer. Use the transferOperations.get method to check if the cancellation succeeded or if the operation completed despite the `cancel` request. When you cancel an operation, the currently running transfer is interrupted. For recurring transfer jobs, the next instance of the transfer job will still run. For example, if your job is configured to run every day at 1pm and you cancel Monday's operation at 1:05pm, Monday's transfer will stop. However, a transfer job will still be attempted on Tuesday. This applies only to currently running operations. If an operation is not currently running, `cancel` does nothing. *Caution:* Canceling a transfer job can leave your data in an unknown state. We recommend that you restore the state at both the destination and the source after the `cancel` request completes so that your data is in a consistent state. When you cancel a job, the next job computes a delta of files and may repair any inconsistent state. For instance, if you run a job every day, and today's job found 10 new files and transferred five files before you canceled the job, tomorrow's transfer operation will compute a new delta with the five files that were not copied today plus any new files discovered tomorrow.",
	//   "flatPath": "v1/transferOperations/{transferOperationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "storagetransfer.transferOperations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^transferOperations/.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:cancel",
	//   "request": {
	//     "$ref": "CancelOperationRequest"
	//   },
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "storagetransfer.transferOperations.get":

type TransferOperationsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the latest state of a long-running operation. Clients can
// use this method to poll the operation result at intervals as
// recommended by the API service.
func (r *TransferOperationsService) Get(name string) *TransferOperationsGetCall {
	c := &TransferOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferOperationsGetCall) Fields(s ...googleapi.Field) *TransferOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TransferOperationsGetCall) IfNoneMatch(entityTag string) *TransferOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferOperationsGetCall) Context(ctx context.Context) *TransferOperationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferOperations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *TransferOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest state of a long-running operation. Clients can use this method to poll the operation result at intervals as recommended by the API service.",
	//   "flatPath": "v1/transferOperations/{transferOperationsId}",
	//   "httpMethod": "GET",
	//   "id": "storagetransfer.transferOperations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^transferOperations/.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "storagetransfer.transferOperations.list":

type TransferOperationsListCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists transfer operations.
func (r *TransferOperationsService) List(name string, filter string) *TransferOperationsListCall {
	c := &TransferOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The list page size.
// The max allowed value is 256.
func (c *TransferOperationsListCall) PageSize(pageSize int64) *TransferOperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The list page
// token.
func (c *TransferOperationsListCall) PageToken(pageToken string) *TransferOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferOperationsListCall) Fields(s ...googleapi.Field) *TransferOperationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TransferOperationsListCall) IfNoneMatch(entityTag string) *TransferOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferOperationsListCall) Context(ctx context.Context) *TransferOperationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferOperations.list" call.
// Exactly one of *ListOperationsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TransferOperationsListCall) Do(opts ...googleapi.CallOption) (*ListOperationsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListOperationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists transfer operations.",
	//   "flatPath": "v1/transferOperations",
	//   "httpMethod": "GET",
	//   "id": "storagetransfer.transferOperations.list",
	//   "parameterOrder": [
	//     "name",
	//     "filter"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Required. A list of query parameters specified as JSON text in the form of: `{\"projectId\":\"my_project_id\", \"jobNames\":[\"jobid1\",\"jobid2\",...], \"operationNames\":[\"opid1\",\"opid2\",...], \"transferStatuses\":[\"status1\",\"status2\",...]}` Since `jobNames`, `operationNames`, and `transferStatuses` support multiple values, they must be specified with array notation. `projectId` is required. `jobNames`, `operationNames`, and `transferStatuses` are optional. The valid values for `transferStatuses` are case-insensitive: IN_PROGRESS, PAUSED, SUCCESS, FAILED, and ABORTED.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The value `transferOperations`.",
	//       "location": "path",
	//       "pattern": "^transferOperations$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The list page size. The max allowed value is 256.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "ListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *TransferOperationsListCall) Pages(ctx context.Context, f func(*ListOperationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "storagetransfer.transferOperations.pause":

type TransferOperationsPauseCall struct {
	s                             *Service
	name                          string
	pausetransferoperationrequest *PauseTransferOperationRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Pause: Pauses a transfer operation.
func (r *TransferOperationsService) Pause(name string, pausetransferoperationrequest *PauseTransferOperationRequest) *TransferOperationsPauseCall {
	c := &TransferOperationsPauseCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.pausetransferoperationrequest = pausetransferoperationrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferOperationsPauseCall) Fields(s ...googleapi.Field) *TransferOperationsPauseCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferOperationsPauseCall) Context(ctx context.Context) *TransferOperationsPauseCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferOperationsPauseCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferOperationsPauseCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.pausetransferoperationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:pause")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferOperations.pause" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *TransferOperationsPauseCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Pauses a transfer operation.",
	//   "flatPath": "v1/transferOperations/{transferOperationsId}:pause",
	//   "httpMethod": "POST",
	//   "id": "storagetransfer.transferOperations.pause",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the transfer operation.",
	//       "location": "path",
	//       "pattern": "^transferOperations/.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:pause",
	//   "request": {
	//     "$ref": "PauseTransferOperationRequest"
	//   },
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "storagetransfer.transferOperations.resume":

type TransferOperationsResumeCall struct {
	s                              *Service
	name                           string
	resumetransferoperationrequest *ResumeTransferOperationRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Resume: Resumes a transfer operation that is paused.
func (r *TransferOperationsService) Resume(name string, resumetransferoperationrequest *ResumeTransferOperationRequest) *TransferOperationsResumeCall {
	c := &TransferOperationsResumeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.resumetransferoperationrequest = resumetransferoperationrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TransferOperationsResumeCall) Fields(s ...googleapi.Field) *TransferOperationsResumeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TransferOperationsResumeCall) Context(ctx context.Context) *TransferOperationsResumeCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TransferOperationsResumeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TransferOperationsResumeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.resumetransferoperationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:resume")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "storagetransfer.transferOperations.resume" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *TransferOperationsResumeCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Resumes a transfer operation that is paused.",
	//   "flatPath": "v1/transferOperations/{transferOperationsId}:resume",
	//   "httpMethod": "POST",
	//   "id": "storagetransfer.transferOperations.resume",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the transfer operation.",
	//       "location": "path",
	//       "pattern": "^transferOperations/.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:resume",
	//   "request": {
	//     "$ref": "ResumeTransferOperationRequest"
	//   },
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
