// 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 cloudbuild provides access to the Cloud Build API.
//
// For product documentation, see: https://cloud.google.com/cloud-build/docs/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/cloudbuild/v1alpha1"
//   ...
//   ctx := context.Background()
//   cloudbuildService, err := cloudbuild.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:
//
//   cloudbuildService, err := cloudbuild.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, ...)
//   cloudbuildService, err := cloudbuild.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package cloudbuild // import "google.golang.org/api/cloudbuild/v1alpha1"

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 = "cloudbuild:v1alpha1"
const apiName = "cloudbuild"
const apiVersion = "v1alpha1"
const basePath = "https://cloudbuild.googleapis.com/"
const mtlsBasePath = "https://cloudbuild.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.Projects = NewProjectsService(s)
	return s, nil
}

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

	Projects *ProjectsService
}

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

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Locations = NewProjectsLocationsService(s)
	rs.WorkerPools = NewProjectsWorkerPoolsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Locations *ProjectsLocationsService

	WorkerPools *ProjectsWorkerPoolsService
}

func NewProjectsLocationsService(s *Service) *ProjectsLocationsService {
	rs := &ProjectsLocationsService{s: s}
	rs.Operations = NewProjectsLocationsOperationsService(s)
	return rs
}

type ProjectsLocationsService struct {
	s *Service

	Operations *ProjectsLocationsOperationsService
}

func NewProjectsLocationsOperationsService(s *Service) *ProjectsLocationsOperationsService {
	rs := &ProjectsLocationsOperationsService{s: s}
	return rs
}

type ProjectsLocationsOperationsService struct {
	s *Service
}

func NewProjectsWorkerPoolsService(s *Service) *ProjectsWorkerPoolsService {
	rs := &ProjectsWorkerPoolsService{s: s}
	return rs
}

type ProjectsWorkerPoolsService struct {
	s *Service
}

// ArtifactObjects: Files in the workspace to upload to Cloud Storage
// upon successful
// completion of all build steps.
type ArtifactObjects struct {
	// Location: Cloud Storage bucket and optional object path, in the
	// form
	// "gs://bucket/path/to/somewhere/". (see [Bucket
	// Name
	// Requirements](https://cloud.google.com/storage/docs/bucket-naming
	// #requirements)).
	//
	// Files in the workspace matching any path pattern will be uploaded
	// to
	// Cloud Storage with this location as a prefix.
	Location string `json:"location,omitempty"`

	// Paths: Path globs used to match files in the build's workspace.
	Paths []string `json:"paths,omitempty"`

	// Timing: Output only. Stores timing information for pushing all
	// artifact objects.
	Timing *TimeSpan `json:"timing,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Location") 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. "Location") 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 *ArtifactObjects) MarshalJSON() ([]byte, error) {
	type NoMethod ArtifactObjects
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ArtifactResult: An artifact that was uploaded during a build. This
// is a single record in the artifact manifest JSON file.
type ArtifactResult struct {
	// FileHash: The file hash of the artifact.
	FileHash []*FileHashes `json:"fileHash,omitempty"`

	// Location: The path of an artifact in a Google Cloud Storage bucket,
	// with the
	// generation number. For
	// example,
	// `gs://mybucket/path/to/output.jar#generation`.
	Location string `json:"location,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FileHash") 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. "FileHash") 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 *ArtifactResult) MarshalJSON() ([]byte, error) {
	type NoMethod ArtifactResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Artifacts: Artifacts produced by a build that should be uploaded
// upon
// successful completion of all build steps.
type Artifacts struct {
	// Images: A list of images to be pushed upon the successful completion
	// of all build
	// steps.
	//
	// The images will be pushed using the builder service account's
	// credentials.
	//
	// The digests of the pushed images will be stored in the Build
	// resource's
	// results field.
	//
	// If any of the images fail to be pushed, the build is marked FAILURE.
	Images []string `json:"images,omitempty"`

	// Objects: A list of objects to be uploaded to Cloud Storage upon
	// successful
	// completion of all build steps.
	//
	// Files in the workspace matching specified paths globs will be
	// uploaded to
	// the specified Cloud Storage location using the builder service
	// account's
	// credentials.
	//
	// The location and generation of the uploaded objects will be stored in
	// the
	// Build resource's results field.
	//
	// If any objects fail to be pushed, the build is marked FAILURE.
	Objects *ArtifactObjects `json:"objects,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Images") 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. "Images") 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 *Artifacts) MarshalJSON() ([]byte, error) {
	type NoMethod Artifacts
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Build: A build resource in the Cloud Build API.
//
// At a high level, a `Build` describes where to find source code, how
// to build
// it (for example, the builder image to run on the source), and where
// to store
// the built artifacts.
//
// Fields can include the following variables, which will be expanded
// when the
// build is created:
//
// - $PROJECT_ID: the project ID of the build.
// - $BUILD_ID: the autogenerated ID of the build.
// - $REPO_NAME: the source repository name specified by RepoSource.
// - $BRANCH_NAME: the branch name specified by RepoSource.
// - $TAG_NAME: the tag name specified by RepoSource.
// - $REVISION_ID or $COMMIT_SHA: the commit SHA specified by RepoSource
// or
//   resolved from the specified branch or tag.
// - $SHORT_SHA: first 7 characters of $REVISION_ID or $COMMIT_SHA.
type Build struct {
	// Artifacts: Artifacts produced by the build that should be uploaded
	// upon
	// successful completion of all build steps.
	Artifacts *Artifacts `json:"artifacts,omitempty"`

	// BuildTriggerId: Output only. The ID of the `BuildTrigger` that
	// triggered this build, if it
	// was triggered automatically.
	BuildTriggerId string `json:"buildTriggerId,omitempty"`

	// CreateTime: Output only. Time at which the request to create the
	// build was received.
	CreateTime string `json:"createTime,omitempty"`

	// FinishTime: Output only. Time at which execution of the build was
	// finished.
	//
	// The difference between finish_time and start_time is the duration of
	// the
	// build's execution.
	FinishTime string `json:"finishTime,omitempty"`

	// Id: Output only. Unique identifier of the build.
	Id string `json:"id,omitempty"`

	// Images: A list of images to be pushed upon the successful completion
	// of all build
	// steps.
	//
	// The images are pushed using the builder service account's
	// credentials.
	//
	// The digests of the pushed images will be stored in the `Build`
	// resource's
	// results field.
	//
	// If any of the images fail to be pushed, the build status is
	// marked
	// `FAILURE`.
	Images []string `json:"images,omitempty"`

	// LogUrl: Output only. URL to logs for this build in Google Cloud
	// Console.
	LogUrl string `json:"logUrl,omitempty"`

	// LogsBucket: Google Cloud Storage bucket where logs should be written
	// (see
	// [Bucket
	// Name
	// Requirements](https://cloud.google.com/storage/docs/bucket-naming
	// #requirements)).
	// Logs file names will be of the format
	// `${logs_bucket}/log-${build_id}.txt`.
	LogsBucket string `json:"logsBucket,omitempty"`

	// Options: Special options for this build.
	Options *BuildOptions `json:"options,omitempty"`

	// ProjectId: Output only. ID of the project.
	ProjectId string `json:"projectId,omitempty"`

	// QueueTtl: TTL in queue for this build. If provided and the build is
	// enqueued longer
	// than this value, the build will expire and the build status will
	// be
	// `EXPIRED`.
	//
	// The TTL starts ticking from create_time.
	QueueTtl string `json:"queueTtl,omitempty"`

	// Results: Output only. Results of the build.
	Results *Results `json:"results,omitempty"`

	// Secrets: Secrets to decrypt using Cloud Key Management Service.
	Secrets []*Secret `json:"secrets,omitempty"`

	// Source: The location of the source files to build.
	Source *Source `json:"source,omitempty"`

	// SourceProvenance: Output only. A permanent fixed identifier for
	// source.
	SourceProvenance *SourceProvenance `json:"sourceProvenance,omitempty"`

	// StartTime: Output only. Time at which execution of the build was
	// started.
	StartTime string `json:"startTime,omitempty"`

	// Status: Output only. Status of the build.
	//
	// Possible values:
	//   "STATUS_UNKNOWN" - Status of the build is unknown.
	//   "QUEUED" - Build or step is queued; work has not yet begun.
	//   "WORKING" - Build or step is being executed.
	//   "SUCCESS" - Build or step finished successfully.
	//   "FAILURE" - Build or step failed to complete successfully.
	//   "INTERNAL_ERROR" - Build or step failed due to an internal cause.
	//   "TIMEOUT" - Build or step took longer than was allowed.
	//   "CANCELLED" - Build or step was canceled by a user.
	//   "EXPIRED" - Build was enqueued for longer than the value of
	// `queue_ttl`.
	Status string `json:"status,omitempty"`

	// StatusDetail: Output only. Customer-readable message about the
	// current status.
	StatusDetail string `json:"statusDetail,omitempty"`

	// Steps: Required. The operations to be performed on the workspace.
	Steps []*BuildStep `json:"steps,omitempty"`

	// Substitutions: Substitutions data for `Build` resource.
	Substitutions map[string]string `json:"substitutions,omitempty"`

	// Tags: Tags for annotation of a `Build`. These are not docker tags.
	Tags []string `json:"tags,omitempty"`

	// Timeout: Amount of time that this build should be allowed to run, to
	// second
	// granularity. If this amount of time elapses, work on the build will
	// cease
	// and the build status will be `TIMEOUT`.
	//
	// `timeout` starts ticking from `startTime`.
	//
	// Default time is ten minutes.
	Timeout string `json:"timeout,omitempty"`

	// Timing: Output only. Stores timing information for phases of the
	// build. Valid keys
	// are:
	//
	// * BUILD: time to execute all build steps
	// * PUSH: time to push all specified images.
	// * FETCHSOURCE: time to fetch source.
	//
	// If the build does not specify source or images,
	// these keys will not be included.
	Timing map[string]TimeSpan `json:"timing,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Artifacts") 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. "Artifacts") 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 *Build) MarshalJSON() ([]byte, error) {
	type NoMethod Build
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildOperationMetadata: Metadata for build operations.
type BuildOperationMetadata struct {
	// Build: The build that the operation is tracking.
	Build *Build `json:"build,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Build") 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. "Build") 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 *BuildOperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod BuildOperationMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildOptions: Optional arguments to enable specific features of
// builds.
type BuildOptions struct {
	// DiskSizeGb: Requested disk size for the VM that runs the build. Note
	// that this is *NOT*
	// "disk free"; some of the space will be used by the operating system
	// and
	// build utilities. Also note that this is the minimum disk size that
	// will be
	// allocated for the build -- the build may run with a larger disk
	// than
	// requested. At present, the maximum disk size is 1000GB; builds that
	// request
	// more than the maximum are rejected with an error.
	DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"`

	// DynamicSubstitutions: Option to specify whether or not to apply bash
	// style string
	// operations to the substitutions.
	//
	// NOTE: this is always enabled for triggered builds and cannot
	// be
	// overridden in the build configuration file.
	DynamicSubstitutions bool `json:"dynamicSubstitutions,omitempty"`

	// Env: A list of global environment variable definitions that will
	// exist for all
	// build steps in this build. If a variable is defined in both globally
	// and in
	// a build step, the variable will use the build step value.
	//
	// The elements are of the form "KEY=VALUE" for the environment variable
	// "KEY"
	// being given the value "VALUE".
	Env []string `json:"env,omitempty"`

	// LogStreamingOption: Option to define build log streaming behavior to
	// Google Cloud
	// Storage.
	//
	// Possible values:
	//   "STREAM_DEFAULT" - Service may automatically determine build log
	// streaming behavior.
	//   "STREAM_ON" - Build logs should be streamed to Google Cloud
	// Storage.
	//   "STREAM_OFF" - Build logs should not be streamed to Google Cloud
	// Storage; they will be
	// written when the build is completed.
	LogStreamingOption string `json:"logStreamingOption,omitempty"`

	// Logging: Option to specify the logging mode, which determines if and
	// where build
	// logs are stored.
	//
	// Possible values:
	//   "LOGGING_UNSPECIFIED" - The service determines the logging mode.
	// The default is `LEGACY`. Do not
	// rely on the default logging behavior as it may change in the future.
	//   "LEGACY" - Cloud Logging (Stackdriver) and Cloud Storage logging
	// are enabled.
	//   "GCS_ONLY" - Only Cloud Storage logging is enabled.
	//   "STACKDRIVER_ONLY" - Only Cloud Logging (Stackdriver) is enabled.
	// Note that logs for both the
	// Cloud Console UI and Cloud SDK are based on Cloud Storage logs,
	// so
	// neither will provide logs if this option is chosen.
	//   "NONE" - Turn off all logging. No build logs will be captured.
	Logging string `json:"logging,omitempty"`

	// MachineType: Compute Engine machine type on which to run the build.
	//
	// Possible values:
	//   "UNSPECIFIED" - Standard machine type.
	//   "N1_HIGHCPU_8" - Highcpu machine with 8 CPUs.
	//   "N1_HIGHCPU_32" - Highcpu machine with 32 CPUs.
	MachineType string `json:"machineType,omitempty"`

	// RequestedVerifyOption: Requested verifiability options.
	//
	// Possible values:
	//   "NOT_VERIFIED" - Not a verifiable build. (default)
	//   "VERIFIED" - Verified build.
	RequestedVerifyOption string `json:"requestedVerifyOption,omitempty"`

	// SecretEnv: A list of global environment variables, which are
	// encrypted using a Cloud
	// Key Management Service crypto key. These values must be specified in
	// the
	// build's `Secret`. These variables will be available to all build
	// steps
	// in this build.
	SecretEnv []string `json:"secretEnv,omitempty"`

	// SourceProvenanceHash: Requested hash for SourceProvenance.
	//
	// Possible values:
	//   "NONE" - No hash requested.
	//   "SHA256" - Use a sha256 hash.
	//   "MD5" - Use a md5 hash.
	SourceProvenanceHash []string `json:"sourceProvenanceHash,omitempty"`

	// SubstitutionOption: Option to specify behavior when there is an error
	// in the substitution
	// checks.
	//
	// NOTE: this is always set to ALLOW_LOOSE for triggered builds and
	// cannot
	// be overridden in the build configuration file.
	//
	// Possible values:
	//   "MUST_MATCH" - Fails the build if error in substitutions checks,
	// like missing
	// a substitution in the template or in the map.
	//   "ALLOW_LOOSE" - Do not fail the build if error in substitutions
	// checks.
	SubstitutionOption string `json:"substitutionOption,omitempty"`

	// Volumes: Global list of volumes to mount for ALL build steps
	//
	// Each volume is created as an empty volume prior to starting the
	// build
	// process. Upon completion of the build, volumes and their contents
	// are
	// discarded. Global volume names and paths cannot conflict with the
	// volumes
	// defined a build step.
	//
	// Using a global volume in a build with only one step is not valid
	// as
	// it is indicative of a build request with an incorrect configuration.
	Volumes []*Volume `json:"volumes,omitempty"`

	// WorkerPool: Option to specify a `WorkerPool` for the build.
	// Format: projects/{project}/workerPools/{workerPool}
	//
	// This field is experimental.
	WorkerPool string `json:"workerPool,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DiskSizeGb") 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. "DiskSizeGb") 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 *BuildOptions) MarshalJSON() ([]byte, error) {
	type NoMethod BuildOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildStep: A step in the build pipeline.
type BuildStep struct {
	// Args: A list of arguments that will be presented to the step when it
	// is started.
	//
	// If the image used to run the step's container has an entrypoint, the
	// `args`
	// are used as arguments to that entrypoint. If the image does not
	// define
	// an entrypoint, the first element in args is used as the
	// entrypoint,
	// and the remainder will be used as arguments.
	Args []string `json:"args,omitempty"`

	// Dir: Working directory to use when running this step's container.
	//
	// If this value is a relative path, it is relative to the build's
	// working
	// directory. If this value is absolute, it may be outside the build's
	// working
	// directory, in which case the contents of the path may not be
	// persisted
	// across build step executions, unless a `volume` for that path is
	// specified.
	//
	// If the build specifies a `RepoSource` with `dir` and a step with a
	// `dir`,
	// which specifies an absolute path, the `RepoSource` `dir` is ignored
	// for
	// the step's execution.
	Dir string `json:"dir,omitempty"`

	// Entrypoint: Entrypoint to be used instead of the build step image's
	// default entrypoint.
	// If unset, the image's default entrypoint is used.
	Entrypoint string `json:"entrypoint,omitempty"`

	// Env: A list of environment variable definitions to be used when
	// running a step.
	//
	// The elements are of the form "KEY=VALUE" for the environment variable
	// "KEY"
	// being given the value "VALUE".
	Env []string `json:"env,omitempty"`

	// Id: Unique identifier for this build step, used in `wait_for`
	// to
	// reference this build step as a dependency.
	Id string `json:"id,omitempty"`

	// Name: Required. The name of the container image that will run this
	// particular
	// build step.
	//
	// If the image is available in the host's Docker daemon's cache,
	// it
	// will be run directly. If not, the host will attempt to pull the
	// image
	// first, using the builder service account's credentials if
	// necessary.
	//
	// The Docker daemon's cache will already have the latest versions of
	// all of
	// the officially supported build
	// steps
	// ([https://github.com/GoogleCloudPlatform/cloud-builders](https:/
	// /github.com/GoogleCloudPlatform/cloud-builders)).
	// The Docker daemon will also have cached many of the layers for some
	// popular
	// images, like "ubuntu", "debian", but they will be refreshed at the
	// time you
	// attempt to use them.
	//
	// If you built an image in a previous build step, it will be stored in
	// the
	// host's Docker daemon's cache and is available to use as the name for
	// a
	// later build step.
	Name string `json:"name,omitempty"`

	// PullTiming: Output only. Stores timing information for pulling this
	// build step's
	// builder image only.
	PullTiming *TimeSpan `json:"pullTiming,omitempty"`

	// SecretEnv: A list of environment variables which are encrypted using
	// a Cloud Key
	// Management Service crypto key. These values must be specified in
	// the
	// build's `Secret`.
	SecretEnv []string `json:"secretEnv,omitempty"`

	// Status: Output only. Status of the build step. At this time, build
	// step status is
	// only updated on build completion; step status is not updated in
	// real-time
	// as the build progresses.
	//
	// Possible values:
	//   "STATUS_UNKNOWN" - Status of the build is unknown.
	//   "QUEUED" - Build or step is queued; work has not yet begun.
	//   "WORKING" - Build or step is being executed.
	//   "SUCCESS" - Build or step finished successfully.
	//   "FAILURE" - Build or step failed to complete successfully.
	//   "INTERNAL_ERROR" - Build or step failed due to an internal cause.
	//   "TIMEOUT" - Build or step took longer than was allowed.
	//   "CANCELLED" - Build or step was canceled by a user.
	//   "EXPIRED" - Build was enqueued for longer than the value of
	// `queue_ttl`.
	Status string `json:"status,omitempty"`

	// Timeout: Time limit for executing this build step. If not defined,
	// the step has no
	// time limit and will be allowed to continue to run until either it
	// completes
	// or the build itself times out.
	Timeout string `json:"timeout,omitempty"`

	// Timing: Output only. Stores timing information for executing this
	// build step.
	Timing *TimeSpan `json:"timing,omitempty"`

	// Volumes: List of volumes to mount into the build step.
	//
	// Each volume is created as an empty volume prior to execution of
	// the
	// build step. Upon completion of the build, volumes and their contents
	// are
	// discarded.
	//
	// Using a named volume in only one step is not valid as it is
	// indicative
	// of a build request with an incorrect configuration.
	Volumes []*Volume `json:"volumes,omitempty"`

	// WaitFor: The ID(s) of the step(s) that this build step depends
	// on.
	// This build step will not start until all the build steps in
	// `wait_for`
	// have completed successfully. If `wait_for` is empty, this build step
	// will
	// start when all previous build steps in the `Build.Steps` list
	// have
	// completed successfully.
	WaitFor []string `json:"waitFor,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Args") 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. "Args") 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 *BuildStep) MarshalJSON() ([]byte, error) {
	type NoMethod BuildStep
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuiltImage: An image built by the pipeline.
type BuiltImage struct {
	// Digest: Docker Registry 2.0 digest.
	Digest string `json:"digest,omitempty"`

	// Name: Name used to push the container image to Google Container
	// Registry, as
	// presented to `docker push`.
	Name string `json:"name,omitempty"`

	// PushTiming: Output only. Stores timing information for pushing the
	// specified image.
	PushTiming *TimeSpan `json:"pushTiming,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Digest") 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. "Digest") 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 *BuiltImage) MarshalJSON() ([]byte, error) {
	type NoMethod BuiltImage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// 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:"-"`
}

// FileHashes: Container message for hashes of byte content of files,
// used in
// SourceProvenance messages to verify integrity of source input to the
// build.
type FileHashes struct {
	// FileHash: Collection of file hashes.
	FileHash []*Hash `json:"fileHash,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FileHash") 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. "FileHash") 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 *FileHashes) MarshalJSON() ([]byte, error) {
	type NoMethod FileHashes
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HTTPDelivery: HTTPDelivery is the delivery configuration for an HTTP
// notification.
type HTTPDelivery struct {
	// Uri: The URI to which JSON-containing HTTP POST requests should be
	// sent.
	Uri string `json:"uri,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Uri") 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. "Uri") 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 *HTTPDelivery) MarshalJSON() ([]byte, error) {
	type NoMethod HTTPDelivery
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Hash: Container message for hash values.
type Hash struct {
	// Type: The type of hash that was performed.
	//
	// Possible values:
	//   "NONE" - No hash requested.
	//   "SHA256" - Use a sha256 hash.
	//   "MD5" - Use a md5 hash.
	Type string `json:"type,omitempty"`

	// Value: The hash value.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Type") 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. "Type") 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 *Hash) MarshalJSON() ([]byte, error) {
	type NoMethod Hash
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListWorkerPoolsResponse: Response containing existing `WorkerPools`.
type ListWorkerPoolsResponse struct {
	// WorkerPools: `WorkerPools` for the project.
	WorkerPools []*WorkerPool `json:"workerPools,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "WorkerPools") 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. "WorkerPools") 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 *ListWorkerPoolsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListWorkerPoolsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Network: Network describes the GCP network used to create workers in.
type Network struct {
	// Network: Network on which the workers are created.
	// "default" network is used if empty.
	Network string `json:"network,omitempty"`

	// ProjectId: Project id containing the defined network and subnetwork.
	// For a peered VPC,
	// this will be the same as the project_id in which the workers are
	// created.
	// For a shared VPC, this will be the project sharing the network with
	// the
	// project_id project in which workers will be created. For custom
	// workers
	// with no VPC, this will be the same as project_id.
	ProjectId string `json:"projectId,omitempty"`

	// Subnetwork: Subnetwork on which the workers are created.
	// "default" subnetwork is used if empty.
	Subnetwork string `json:"subnetwork,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Network") 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. "Network") 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 *Network) MarshalJSON() ([]byte, error) {
	type NoMethod Network
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Notification: Notification is the container which holds the data that
// is relevant to this
// particular notification.
type Notification struct {
	// Filter: The filter string to use for notification
	// filtering.
	// Currently, this is assumed to be a CEL program.
	// See https://opensource.google/projects/cel for more.
	Filter string `json:"filter,omitempty"`

	// HttpDelivery: Configuration for HTTP delivery.
	HttpDelivery *HTTPDelivery `json:"httpDelivery,omitempty"`

	// SlackDelivery: Configuration for Slack delivery.
	SlackDelivery *SlackDelivery `json:"slackDelivery,omitempty"`

	// SmtpDelivery: Configuration for SMTP (email) delivery.
	SmtpDelivery *SMTPDelivery `json:"smtpDelivery,omitempty"`

	// StructDelivery: Escape hatch for users to supply custom delivery
	// configs.
	StructDelivery googleapi.RawMessage `json:"structDelivery,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Filter") 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. "Filter") 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 *Notification) MarshalJSON() ([]byte, error) {
	type NoMethod Notification
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotifierConfig: NotifierConfig is the top-level configuration
// message.
type NotifierConfig struct {
	// ApiVersion: The API version of this configuration format.
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The type of notifier to use (e.g. SMTPNotifier).
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata for referring to/handling/deploying this notifier.
	Metadata *NotifierMetadata `json:"metadata,omitempty"`

	// Spec: The actual configuration for this notifier.
	Spec *NotifierSpec `json:"spec,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApiVersion") 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. "ApiVersion") 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 *NotifierConfig) MarshalJSON() ([]byte, error) {
	type NoMethod NotifierConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotifierMetadata: NotifierMetadata contains the data which can be
// used to reference or describe
// this notifier.
type NotifierMetadata struct {
	// Name: The human-readable and user-given name for the notifier.
	// For example: "repo-merge-email-notifier".
	Name string `json:"name,omitempty"`

	// Notifier: The string representing the name and version of notifier to
	// deploy.
	// Expected to be of the form of "<registry-path>/<name>:<version>".
	// For example: "gcr.io/my-project/notifiers/smtp:1.2.34".
	Notifier string `json:"notifier,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *NotifierMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod NotifierMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotifierSecret: NotifierSecret is the container that maps a secret
// name (reference) to its
// Google Cloud Secret Manager resource path.
type NotifierSecret struct {
	// Name: Name is the local name of the secret, such as the verbatim
	// string
	// "my-smtp-password".
	Name string `json:"name,omitempty"`

	// Value: Value is interpreted to be a resource path for fetching the
	// actual
	// (versioned) secret data for this secret. For example, this would be
	// a
	// Google Cloud Secret Manager secret version resource path
	// like:
	// "projects/my-project/secrets/my-secret/versions/latest".
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *NotifierSecret) MarshalJSON() ([]byte, error) {
	type NoMethod NotifierSecret
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotifierSecretRef: NotifierSecretRef contains the reference to a
// secret stored in the
// corresponding NotifierSpec.
type NotifierSecretRef struct {
	// SecretRef: The value of `secret_ref` should be a `name` that is
	// registered in a
	// `Secret` in the `secrets` list of the `Spec`.
	SecretRef string `json:"secretRef,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SecretRef") 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. "SecretRef") 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 *NotifierSecretRef) MarshalJSON() ([]byte, error) {
	type NoMethod NotifierSecretRef
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotifierSpec: NotifierSpec is the configuration container for
// notifications.
type NotifierSpec struct {
	// Notification: The configuration of this particular notifier.
	Notification *Notification `json:"notification,omitempty"`

	// Secrets: Configurations for secret resources used by this particular
	// notifier.
	Secrets []*NotifierSecret `json:"secrets,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Notification") 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. "Notification") 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 *NotifierSpec) MarshalJSON() ([]byte, error) {
	type NoMethod NotifierSpec
	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: Service-specific metadata associated with the operation.
	// It typically
	// contains progress information and common metadata such as create
	// time.
	// Some services might not provide such metadata.  Any method that
	// returns a
	// long-running operation should document the metadata type, if any.
	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 be a resource name ending with
	// `operations/{unique_id}`.
	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)
}

// RepoSource: Location of the source in a Google Cloud Source
// Repository.
type RepoSource struct {
	// BranchName: Regex matching branches to build.
	//
	// The syntax of the regular expressions accepted is the syntax accepted
	// by
	// RE2 and described at https://github.com/google/re2/wiki/Syntax
	BranchName string `json:"branchName,omitempty"`

	// CommitSha: Explicit commit SHA to build.
	CommitSha string `json:"commitSha,omitempty"`

	// Dir: Directory, relative to the source root, in which to run the
	// build.
	//
	// This must be a relative path. If a step's `dir` is specified and is
	// an
	// absolute path, this value is ignored for that step's execution.
	Dir string `json:"dir,omitempty"`

	// InvertRegex: Only trigger a build if the revision regex does NOT
	// match the revision
	// regex.
	InvertRegex bool `json:"invertRegex,omitempty"`

	// ProjectId: ID of the project that owns the Cloud Source Repository.
	// If omitted, the
	// project ID requesting the build is assumed.
	ProjectId string `json:"projectId,omitempty"`

	// RepoName: Required. Name of the Cloud Source Repository.
	RepoName string `json:"repoName,omitempty"`

	// Substitutions: Substitutions to use in a triggered build.
	// Should only be used with RunBuildTrigger
	Substitutions map[string]string `json:"substitutions,omitempty"`

	// TagName: Regex matching tags to build.
	//
	// The syntax of the regular expressions accepted is the syntax accepted
	// by
	// RE2 and described at https://github.com/google/re2/wiki/Syntax
	TagName string `json:"tagName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BranchName") 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. "BranchName") 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 *RepoSource) MarshalJSON() ([]byte, error) {
	type NoMethod RepoSource
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Results: Artifacts created by the build pipeline.
type Results struct {
	// ArtifactManifest: Path to the artifact manifest. Only populated when
	// artifacts are uploaded.
	ArtifactManifest string `json:"artifactManifest,omitempty"`

	// ArtifactTiming: Time to push all non-container artifacts.
	ArtifactTiming *TimeSpan `json:"artifactTiming,omitempty"`

	// BuildStepImages: List of build step digests, in the order
	// corresponding to build step
	// indices.
	BuildStepImages []string `json:"buildStepImages,omitempty"`

	// BuildStepOutputs: List of build step outputs, produced by builder
	// images, in the order
	// corresponding to build step indices.
	//
	// [Cloud
	// Builders](https://cloud.google.com/cloud-build/docs/cloud-builders)
	// ca
	// n produce this output by writing to `$BUILDER_OUTPUT/output`.
	// Only the first 4KB of data is stored.
	BuildStepOutputs []string `json:"buildStepOutputs,omitempty"`

	// Images: Container images that were built as a part of the build.
	Images []*BuiltImage `json:"images,omitempty"`

	// NumArtifacts: Number of artifacts uploaded. Only populated when
	// artifacts are uploaded.
	NumArtifacts int64 `json:"numArtifacts,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "ArtifactManifest") 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. "ArtifactManifest") 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 *Results) MarshalJSON() ([]byte, error) {
	type NoMethod Results
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SMTPDelivery: SMTPDelivery is the delivery configuration for an SMTP
// (email) notification.
type SMTPDelivery struct {
	// FromAddress: This is the SMTP account/email that appears in the
	// `From:` of the email.
	// If empty, it is assumed to be sender.
	FromAddress string `json:"fromAddress,omitempty"`

	// Password: The SMTP sender's password.
	Password *NotifierSecretRef `json:"password,omitempty"`

	// Port: The SMTP port of the server.
	Port string `json:"port,omitempty"`

	// RecipientAddresses: This is the list of addresses to which we send
	// the email (i.e. in the `To:`
	// of the email).
	RecipientAddresses []string `json:"recipientAddresses,omitempty"`

	// SenderAddress: This is the SMTP account/email that is used to send
	// the message.
	SenderAddress string `json:"senderAddress,omitempty"`

	// Server: The address of the SMTP server.
	Server string `json:"server,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FromAddress") 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. "FromAddress") 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 *SMTPDelivery) MarshalJSON() ([]byte, error) {
	type NoMethod SMTPDelivery
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Secret: Pairs a set of secret environment variables containing
// encrypted
// values with the Cloud KMS key to use to decrypt the value.
type Secret struct {
	// KmsKeyName: Cloud KMS key name to use to decrypt these envs.
	KmsKeyName string `json:"kmsKeyName,omitempty"`

	// SecretEnv: Map of environment variable name to its encrypted
	// value.
	//
	// Secret environment variables must be unique across all of a
	// build's
	// secrets, and must be used by at least one build step. Values can be
	// at most
	// 64 KB in size. There can be at most 100 secret values across all of
	// a
	// build's secrets.
	SecretEnv map[string]string `json:"secretEnv,omitempty"`

	// ForceSendFields is a list of field names (e.g. "KmsKeyName") 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. "KmsKeyName") 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 *Secret) MarshalJSON() ([]byte, error) {
	type NoMethod Secret
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SlackDelivery: SlackDelivery is the delivery configuration for
// delivering Slack messages via
// webhooks. See Slack webhook documentation
// at:
// https://api.slack.com/messaging/webhooks.
type SlackDelivery struct {
	// WebhookUri: The secret reference for the Slack webhook URI for
	// sending messages to a
	// channel.
	WebhookUri *NotifierSecretRef `json:"webhookUri,omitempty"`

	// ForceSendFields is a list of field names (e.g. "WebhookUri") 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. "WebhookUri") 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 *SlackDelivery) MarshalJSON() ([]byte, error) {
	type NoMethod SlackDelivery
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Source: Location of the source in a supported storage service.
type Source struct {
	// RepoSource: If provided, get the source from this location in a Cloud
	// Source
	// Repository.
	RepoSource *RepoSource `json:"repoSource,omitempty"`

	// StorageSource: If provided, get the source from this location in
	// Google Cloud Storage.
	StorageSource *StorageSource `json:"storageSource,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RepoSource") 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. "RepoSource") 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 *Source) MarshalJSON() ([]byte, error) {
	type NoMethod Source
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SourceProvenance: Provenance of the source. Ways to find the original
// source, or verify that
// some source was used for this build.
type SourceProvenance struct {
	// FileHashes: Output only. Hash(es) of the build source, which can be
	// used to verify that
	// the original source integrity was maintained in the build. Note
	// that
	// `FileHashes` will only be populated if `BuildOptions` has requested
	// a
	// `SourceProvenanceHash`.
	//
	// The keys to this map are file paths used as build source and the
	// values
	// contain the hash values for those files.
	//
	// If the build source came in a single package such as a gzipped
	// tarfile
	// (`.tar.gz`), the `FileHash` will be for the single path to that file.
	FileHashes map[string]FileHashes `json:"fileHashes,omitempty"`

	// ResolvedRepoSource: A copy of the build's `source.repo_source`, if
	// exists, with any
	// revisions resolved.
	ResolvedRepoSource *RepoSource `json:"resolvedRepoSource,omitempty"`

	// ResolvedStorageSource: A copy of the build's `source.storage_source`,
	// if exists, with any
	// generations resolved.
	ResolvedStorageSource *StorageSource `json:"resolvedStorageSource,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FileHashes") 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. "FileHashes") 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 *SourceProvenance) MarshalJSON() ([]byte, error) {
	type NoMethod SourceProvenance
	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)
}

// StorageSource: Location of the source in an archive file in Google
// Cloud Storage.
type StorageSource struct {
	// Bucket: Google Cloud Storage bucket containing the source
	// (see
	// [Bucket
	// Name
	// Requirements](https://cloud.google.com/storage/docs/bucket-naming
	// #requirements)).
	Bucket string `json:"bucket,omitempty"`

	// Generation: Google Cloud Storage generation for the object. If the
	// generation is
	// omitted, the latest generation will be used.
	Generation int64 `json:"generation,omitempty,string"`

	// Object: Google Cloud Storage object containing the source.
	//
	// This object must be a gzipped archive file (`.tar.gz`) containing
	// source to
	// build.
	Object string `json:"object,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bucket") 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. "Bucket") 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 *StorageSource) MarshalJSON() ([]byte, error) {
	type NoMethod StorageSource
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TimeSpan: Start and end times for a build execution phase.
type TimeSpan struct {
	// EndTime: End of time span.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: Start of time span.
	StartTime string `json:"startTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndTime") 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. "EndTime") 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 *TimeSpan) MarshalJSON() ([]byte, error) {
	type NoMethod TimeSpan
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Volume: Volume describes a Docker container volume which is mounted
// into build steps
// in order to persist files across build step execution.
type Volume struct {
	// Name: Name of the volume to mount.
	//
	// Volume names must be unique per build step and must be valid names
	// for
	// Docker volumes. Each named volume must be used by at least two build
	// steps.
	Name string `json:"name,omitempty"`

	// Path: Path at which to mount the volume.
	//
	// Paths must be absolute and cannot conflict with other volume paths on
	// the
	// same build step or with certain reserved volume paths.
	Path string `json:"path,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *Volume) MarshalJSON() ([]byte, error) {
	type NoMethod Volume
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WorkerConfig: WorkerConfig defines the configuration to be used for a
// creating workers in
// the pool.
type WorkerConfig struct {
	// DiskSizeGb: Size of the disk attached to the worker, in GB.
	// See https://cloud.google.com/compute/docs/disks/
	// If `0` is specified, Cloud Build will use a standard disk
	// size.
	// `disk_size` is overridden if you specify a different disk size
	// in
	// `build_options`. In this case, a VM with a disk size specified in
	// the
	// `build_options` will be created on demand at build time. For
	// more
	// information
	// see
	// https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/pr
	// ojects.builds#buildoptions
	DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"`

	// MachineType: Machine Type of the worker, such as n1-standard-1.
	// See https://cloud.google.com/compute/docs/machine-types.
	// If left blank, Cloud Build will use a standard unspecified machine
	// to
	// create the worker pool.
	// `machine_type` is overridden if you specify a different machine type
	// in
	// `build_options`. In this case, the VM specified in the
	// `build_options`
	// will be created on demand at build time. For more information
	// see
	// https://cloud.google.com/cloud-build/docs/speeding-up-builds#using
	// _custom_virtual_machine_sizes
	MachineType string `json:"machineType,omitempty"`

	// Network: The network definition used to create the worker.
	// If this section is left empty, the workers will be created
	// in
	// WorkerPool.project_id on the default network.
	Network *Network `json:"network,omitempty"`

	// Tag: The tag applied to the worker, and the same tag used by the
	// firewall rule.
	// It is used to identify the Cloud Build workers among other VMs.
	// The default value for tag is `worker`.
	Tag string `json:"tag,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DiskSizeGb") 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. "DiskSizeGb") 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 *WorkerConfig) MarshalJSON() ([]byte, error) {
	type NoMethod WorkerConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WorkerPool: Configuration for a WorkerPool to run the
// builds.
//
// Workers are machines that Cloud Build uses to run your builds. By
// default,
// all workers run in a project owned by Cloud Build. To have full
// control over
// the workers that execute your builds -- such as enabling them to
// access
// private resources on your private network -- you can request Cloud
// Build to
// run the workers in your own project by creating a custom workers
// pool.
type WorkerPool struct {
	// CreateTime: Output only. Time at which the request to create the
	// `WorkerPool` was
	// received.
	CreateTime string `json:"createTime,omitempty"`

	// DeleteTime: Output only. Time at which the request to delete the
	// `WorkerPool` was
	// received.
	DeleteTime string `json:"deleteTime,omitempty"`

	// Name: User-defined name of the `WorkerPool`.
	Name string `json:"name,omitempty"`

	// ProjectId: The project ID of the GCP project for which the
	// `WorkerPool` is created.
	ProjectId string `json:"projectId,omitempty"`

	// Regions: List of regions to create the `WorkerPool`. Regions can't be
	// empty.
	// If Cloud Build adds a new GCP region in the future, the
	// existing
	// `WorkerPool` will not be enabled in the new region automatically;
	// you must add the new region to the `regions` field to enable
	// the
	// `WorkerPool` in that region.
	//
	// Possible values:
	//   "REGION_UNSPECIFIED" - no region
	//   "us-central1" - us-central1 region
	//   "us-west1" - us-west1 region
	//   "us-east1" - us-east1 region
	//   "us-east4" - us-east4 region
	Regions []string `json:"regions,omitempty"`

	// ServiceAccountEmail: Output only. The service account used to manage
	// the `WorkerPool`. The
	// service account must have the Compute Instance Admin (Beta)
	// permission at
	// the project level.
	ServiceAccountEmail string `json:"serviceAccountEmail,omitempty"`

	// Status: Output only. WorkerPool Status.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Status of the `WorkerPool` is unknown.
	//   "CREATING" - `WorkerPool` is being created.
	//   "RUNNING" - `WorkerPool` is running.
	//   "DELETING" - `WorkerPool` is being deleted: cancelling builds and
	// draining workers.
	//   "DELETED" - `WorkerPool` is deleted.
	Status string `json:"status,omitempty"`

	// UpdateTime: Output only. Time at which the request to update the
	// `WorkerPool` was
	// received.
	UpdateTime string `json:"updateTime,omitempty"`

	// WorkerConfig: Configuration to be used for a creating workers in the
	// `WorkerPool`.
	WorkerConfig *WorkerConfig `json:"workerConfig,omitempty"`

	// WorkerCount: Total number of workers to be created across all
	// requested regions.
	WorkerCount int64 `json:"workerCount,omitempty,string"`

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

	// ForceSendFields is a list of field names (e.g. "CreateTime") 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. "CreateTime") 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 *WorkerPool) MarshalJSON() ([]byte, error) {
	type NoMethod WorkerPool
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "cloudbuild.projects.locations.operations.cancel":

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

// Cancel: Starts asynchronous cancellation on a long-running operation.
//  The server
// makes a best effort to cancel the operation, but success is
// not
// guaranteed.  If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.  Clients can
// use
// Operations.GetOperation or
// other methods to check whether the cancellation succeeded or whether
// the
// operation completed despite cancellation. On successful
// cancellation,
// the operation is not deleted; instead, it becomes an operation
// with
// an Operation.error value with a google.rpc.Status.code of
// 1,
// corresponding to `Code.CANCELLED`.
func (r *ProjectsLocationsOperationsService) Cancel(name string, canceloperationrequest *CancelOperationRequest) *ProjectsLocationsOperationsCancelCall {
	c := &ProjectsLocationsOperationsCancelCall{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 *ProjectsLocationsOperationsCancelCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsCancelCall {
	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 *ProjectsLocationsOperationsCancelCall) Context(ctx context.Context) *ProjectsLocationsOperationsCancelCall {
	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 *ProjectsLocationsOperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	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, "v1alpha1/{+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 "cloudbuild.projects.locations.operations.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 *ProjectsLocationsOperationsCancelCall) 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": "Starts asynchronous cancellation on a long-running operation.  The server\nmakes a best effort to cancel the operation, but success is not\nguaranteed.  If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.  Clients can use\nOperations.GetOperation or\nother methods to check whether the cancellation succeeded or whether the\noperation completed despite cancellation. On successful cancellation,\nthe operation is not deleted; instead, it becomes an operation with\nan Operation.error value with a google.rpc.Status.code of 1,\ncorresponding to `Code.CANCELLED`.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "cloudbuild.projects.locations.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}:cancel",
	//   "request": {
	//     "$ref": "CancelOperationRequest"
	//   },
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudbuild.projects.locations.operations.get":

type ProjectsLocationsOperationsGetCall 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 *ProjectsLocationsOperationsService) Get(name string) *ProjectsLocationsOperationsGetCall {
	c := &ProjectsLocationsOperationsGetCall{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 *ProjectsLocationsOperationsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsGetCall {
	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 *ProjectsLocationsOperationsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsOperationsGetCall {
	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 *ProjectsLocationsOperationsGetCall) Context(ctx context.Context) *ProjectsLocationsOperationsGetCall {
	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 *ProjectsLocationsOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	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, "v1alpha1/{+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 "cloudbuild.projects.locations.operations.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 *ProjectsLocationsOperationsGetCall) 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\nmethod to poll the operation result at intervals as recommended by the API\nservice.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudbuild.projects.locations.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudbuild.projects.workerPools.create":

type ProjectsWorkerPoolsCreateCall struct {
	s          *Service
	parent     string
	workerpool *WorkerPool
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a `WorkerPool` to run the builds, and returns the new
// worker pool.
func (r *ProjectsWorkerPoolsService) Create(parent string, workerpool *WorkerPool) *ProjectsWorkerPoolsCreateCall {
	c := &ProjectsWorkerPoolsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.workerpool = workerpool
	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 *ProjectsWorkerPoolsCreateCall) Fields(s ...googleapi.Field) *ProjectsWorkerPoolsCreateCall {
	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 *ProjectsWorkerPoolsCreateCall) Context(ctx context.Context) *ProjectsWorkerPoolsCreateCall {
	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 *ProjectsWorkerPoolsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsWorkerPoolsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	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.workerpool)
	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, "v1alpha1/{+parent}/workerPools")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudbuild.projects.workerPools.create" call.
// Exactly one of *WorkerPool or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *WorkerPool.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 *ProjectsWorkerPoolsCreateCall) Do(opts ...googleapi.CallOption) (*WorkerPool, 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 := &WorkerPool{
		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 `WorkerPool` to run the builds, and returns the new worker pool.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/workerPools",
	//   "httpMethod": "POST",
	//   "id": "cloudbuild.projects.workerPools.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "ID of the parent project.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/workerPools",
	//   "request": {
	//     "$ref": "WorkerPool"
	//   },
	//   "response": {
	//     "$ref": "WorkerPool"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudbuild.projects.workerPools.delete":

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

// Delete: Deletes a `WorkerPool` by its project ID and WorkerPool name.
func (r *ProjectsWorkerPoolsService) Delete(name string) *ProjectsWorkerPoolsDeleteCall {
	c := &ProjectsWorkerPoolsDeleteCall{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 *ProjectsWorkerPoolsDeleteCall) Fields(s ...googleapi.Field) *ProjectsWorkerPoolsDeleteCall {
	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 *ProjectsWorkerPoolsDeleteCall) Context(ctx context.Context) *ProjectsWorkerPoolsDeleteCall {
	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 *ProjectsWorkerPoolsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsWorkerPoolsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", 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 "cloudbuild.projects.workerPools.delete" 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 *ProjectsWorkerPoolsDeleteCall) 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": "Deletes a `WorkerPool` by its project ID and WorkerPool name.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/workerPools/{workerPoolsId}",
	//   "httpMethod": "DELETE",
	//   "id": "cloudbuild.projects.workerPools.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The field will contain name of the resource requested, for example:\n\"projects/project-1/workerPools/workerpool-name\"",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/workerPools/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudbuild.projects.workerPools.get":

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

// Get: Returns information about a `WorkerPool`.
func (r *ProjectsWorkerPoolsService) Get(name string) *ProjectsWorkerPoolsGetCall {
	c := &ProjectsWorkerPoolsGetCall{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 *ProjectsWorkerPoolsGetCall) Fields(s ...googleapi.Field) *ProjectsWorkerPoolsGetCall {
	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 *ProjectsWorkerPoolsGetCall) IfNoneMatch(entityTag string) *ProjectsWorkerPoolsGetCall {
	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 *ProjectsWorkerPoolsGetCall) Context(ctx context.Context) *ProjectsWorkerPoolsGetCall {
	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 *ProjectsWorkerPoolsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsWorkerPoolsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	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, "v1alpha1/{+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 "cloudbuild.projects.workerPools.get" call.
// Exactly one of *WorkerPool or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *WorkerPool.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 *ProjectsWorkerPoolsGetCall) Do(opts ...googleapi.CallOption) (*WorkerPool, 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 := &WorkerPool{
		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 information about a `WorkerPool`.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/workerPools/{workerPoolsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudbuild.projects.workerPools.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The field will contain name of the resource requested, for example:\n\"projects/project-1/workerPools/workerpool-name\"",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/workerPools/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "WorkerPool"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudbuild.projects.workerPools.list":

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

// List: List project's `WorkerPool`s.
func (r *ProjectsWorkerPoolsService) List(parent string) *ProjectsWorkerPoolsListCall {
	c := &ProjectsWorkerPoolsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *ProjectsWorkerPoolsListCall) Fields(s ...googleapi.Field) *ProjectsWorkerPoolsListCall {
	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 *ProjectsWorkerPoolsListCall) IfNoneMatch(entityTag string) *ProjectsWorkerPoolsListCall {
	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 *ProjectsWorkerPoolsListCall) Context(ctx context.Context) *ProjectsWorkerPoolsListCall {
	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 *ProjectsWorkerPoolsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsWorkerPoolsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	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, "v1alpha1/{+parent}/workerPools")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudbuild.projects.workerPools.list" call.
// Exactly one of *ListWorkerPoolsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListWorkerPoolsResponse.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 *ProjectsWorkerPoolsListCall) Do(opts ...googleapi.CallOption) (*ListWorkerPoolsResponse, 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 := &ListWorkerPoolsResponse{
		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": "List project's `WorkerPool`s.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/workerPools",
	//   "httpMethod": "GET",
	//   "id": "cloudbuild.projects.workerPools.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "ID of the parent project.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/workerPools",
	//   "response": {
	//     "$ref": "ListWorkerPoolsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "cloudbuild.projects.workerPools.patch":

type ProjectsWorkerPoolsPatchCall struct {
	s          *Service
	name       string
	workerpool *WorkerPool
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Update a `WorkerPool`.
func (r *ProjectsWorkerPoolsService) Patch(name string, workerpool *WorkerPool) *ProjectsWorkerPoolsPatchCall {
	c := &ProjectsWorkerPoolsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.workerpool = workerpool
	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 *ProjectsWorkerPoolsPatchCall) Fields(s ...googleapi.Field) *ProjectsWorkerPoolsPatchCall {
	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 *ProjectsWorkerPoolsPatchCall) Context(ctx context.Context) *ProjectsWorkerPoolsPatchCall {
	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 *ProjectsWorkerPoolsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsWorkerPoolsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	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.workerpool)
	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, "v1alpha1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudbuild.projects.workerPools.patch" call.
// Exactly one of *WorkerPool or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *WorkerPool.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 *ProjectsWorkerPoolsPatchCall) Do(opts ...googleapi.CallOption) (*WorkerPool, 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 := &WorkerPool{
		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": "Update a `WorkerPool`.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/workerPools/{workerPoolsId}",
	//   "httpMethod": "PATCH",
	//   "id": "cloudbuild.projects.workerPools.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The field will contain name of the resource requested, for example:\n\"projects/project-1/workerPools/workerpool-name\"",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/workerPools/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "request": {
	//     "$ref": "WorkerPool"
	//   },
	//   "response": {
	//     "$ref": "WorkerPool"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
