// Copyright 2019 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"
	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

const apiId = "cloudbuild:v1alpha1"
const apiName = "cloudbuild"
const apiVersion = "v1alpha1"
const basePath = "https://cloudbuild.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...)
	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.WorkerPools = NewProjectsWorkerPoolsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	WorkerPools *ProjectsWorkerPoolsService
}

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"`

	// 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.
	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`.
	//
	// 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"`

	// 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 where
	// the 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" - Stackdriver logging and Cloud Storage logging are
	// enabled.
	//   "GCS_ONLY" - Only Cloud Storage logging is enabled.
	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.
	//
	// 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. User
	// specifies the pool
	// with the format "[WORKERPOOL_PROJECT_ID]/[WORKERPOOL_NAME]".
	// This is an experimental field.
	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.
	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)
}

// 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)
}

// 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)
}

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

	// 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)
}

// 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)
}

// 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)
}

// 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 deleting: 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.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.
//
// This API is experimental.
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/1.13.4 gdcl/20191114")
	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.\n\nThis API is experimental.",
	//   "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.
//
// This API is experimental.
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/1.13.4 gdcl/20191114")
	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.\n\nThis API is experimental.",
	//   "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`.
//
// This API is experimental.
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/1.13.4 gdcl/20191114")
	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`.\n\nThis API is experimental.",
	//   "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.
//
// This API is experimental.
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/1.13.4 gdcl/20191114")
	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.\n\nThis API is experimental.",
	//   "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`.
//
// This API is experimental.
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/1.13.4 gdcl/20191114")
	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`.\n\nThis API is experimental.",
	//   "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"
	//   ]
	// }

}
