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

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

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	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 = "remotebuildexecution:v1"
const apiName = "remotebuildexecution"
const apiVersion = "v1"
const basePath = "https://remotebuildexecution.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.Media = NewMediaService(s)
	s.Operations = NewOperationsService(s)
	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

	Media *MediaService

	Operations *OperationsService

	Projects *ProjectsService
}

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

func NewMediaService(s *Service) *MediaService {
	rs := &MediaService{s: s}
	return rs
}

type MediaService struct {
	s *Service
}

func NewOperationsService(s *Service) *OperationsService {
	rs := &OperationsService{s: s}
	return rs
}

type OperationsService struct {
	s *Service
}

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Operations = NewProjectsOperationsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Operations *ProjectsOperationsService
}

func NewProjectsOperationsService(s *Service) *ProjectsOperationsService {
	rs := &ProjectsOperationsService{s: s}
	return rs
}

type ProjectsOperationsService struct {
	s *Service
}

// BuildBazelRemoteExecutionV2Action: An `Action` captures all the
// information about an execution which is required
// to reproduce it.
//
// `Action`s are the core component of the [Execution] service. A
// single
// `Action` represents a repeatable action that can be performed by
// the
// execution service. `Action`s can be succinctly identified by the
// digest of
// their wire format encoding and, once an `Action` has been executed,
// will be
// cached in the action cache. Future requests can then use the cached
// result
// rather than needing to run afresh.
//
// When a server completes execution of an
// Action, it MAY choose to
// cache the result in
// the ActionCache unless
// `do_not_cache` is `true`. Clients SHOULD expect the server to do so.
// By
// default, future calls to
// Execute the same
// `Action` will also serve their results from the cache. Clients must
// take care
// to understand the caching behaviour. Ideally, all `Action`s will
// be
// reproducible so that serving a result from cache is always desirable
// and
// correct.
type BuildBazelRemoteExecutionV2Action struct {
	// CommandDigest: The digest of the Command
	// to run, which MUST be present in the
	// ContentAddressableStorage.
	CommandDigest *BuildBazelRemoteExecutionV2Digest `json:"commandDigest,omitempty"`

	// DoNotCache: If true, then the `Action`'s result cannot be cached, and
	// in-flight
	// requests for the same `Action` may not be merged.
	DoNotCache bool `json:"doNotCache,omitempty"`

	// InputRootDigest: The digest of the root
	// Directory for the input
	// files. The files in the directory tree are available in the
	// correct
	// location on the build machine before the command is executed. The
	// root
	// directory, as well as every subdirectory and content blob referred
	// to, MUST
	// be in the
	// ContentAddressableStorage.
	InputRootDigest *BuildBazelRemoteExecutionV2Digest `json:"inputRootDigest,omitempty"`

	// Timeout: A timeout after which the execution should be killed. If the
	// timeout is
	// absent, then the client is specifying that the execution should
	// continue
	// as long as the server will let it. The server SHOULD impose a timeout
	// if
	// the client does not specify one, however, if the client does specify
	// a
	// timeout that is longer than the server's maximum timeout, the server
	// MUST
	// reject the request.
	//
	// The timeout is a part of the
	// Action message, and
	// therefore two `Actions` with different timeouts are different, even
	// if they
	// are otherwise identical. This is because, if they were not, running
	// an
	// `Action` with a lower timeout than is required might result in a
	// cache hit
	// from an execution run with a longer timeout, hiding the fact that
	// the
	// timeout is too short. By encoding it directly in the `Action`, a
	// lower
	// timeout will result in a cache miss and the execution timeout will
	// fail
	// immediately, rather than whenever the cache entry gets evicted.
	Timeout string `json:"timeout,omitempty"`

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

// BuildBazelRemoteExecutionV2ActionResult: An ActionResult represents
// the result of an
// Action being run.
type BuildBazelRemoteExecutionV2ActionResult struct {
	// ExecutionMetadata: The details of the execution that originally
	// produced this result.
	ExecutionMetadata *BuildBazelRemoteExecutionV2ExecutedActionMetadata `json:"executionMetadata,omitempty"`

	// ExitCode: The exit code of the command.
	ExitCode int64 `json:"exitCode,omitempty"`

	// OutputDirectories: The output directories of the action. For each
	// output directory requested
	// in the `output_directories` field of the Action, if the
	// corresponding
	// directory existed after the action completed, a single entry will
	// be
	// present in the output list, which will contain the digest of a
	// Tree message containing the
	// directory tree, and the path equal exactly to the corresponding
	// Action
	// output_directories member.
	//
	// As an example, suppose the Action had an output directory `a/b/dir`
	// and the
	// execution produced the following contents in `a/b/dir`: a file named
	// `bar`
	// and a directory named `foo` with an executable file named `baz`.
	// Then,
	// output_directory will contain (hashes shortened for
	// readability):
	//
	// ```json
	// // OutputDirectory proto:
	// {
	//   path: "a/b/dir"
	//   tree_digest: {
	//     hash: "4a73bc9d03...",
	//     size: 55
	//   }
	// }
	// // Tree proto with hash "4a73bc9d03..." and size 55:
	// {
	//   root: {
	//     files: [
	//       {
	//         name: "bar",
	//         digest: {
	//           hash: "4a73bc9d03...",
	//           size: 65534
	//         }
	//       }
	//     ],
	//     directories: [
	//       {
	//         name: "foo",
	//         digest: {
	//           hash: "4cf2eda940...",
	//           size: 43
	//         }
	//       }
	//     ]
	//   }
	//   children : {
	//     // (Directory proto with hash "4cf2eda940..." and size 43)
	//     files: [
	//       {
	//         name: "baz",
	//         digest: {
	//           hash: "b2c941073e...",
	//           size: 1294,
	//         },
	//         is_executable: true
	//       }
	//     ]
	//   }
	// }
	// ```
	// If an output of the same name was found, but was not a directory,
	// the
	// server will return a FAILED_PRECONDITION.
	OutputDirectories []*BuildBazelRemoteExecutionV2OutputDirectory `json:"outputDirectories,omitempty"`

	// OutputDirectorySymlinks: The output directories of the action that
	// are symbolic links to other
	// directories. Those may be links to other output directories, or
	// input
	// directories, or even absolute paths outside of the working
	// directory,
	// if the server supports
	// SymlinkAbsolutePathStrategy.ALLOWED.
	// For each output directory requested in the `output_directories` field
	// of
	// the Action, if the directory existed after the action completed,
	// a
	// single entry will be present either in this field, or in
	// the
	// `output_directories` field, if the directory was not a symbolic
	// link.
	//
	// If an output of the same name was found, but was a symbolic link to a
	// file
	// instead of a directory, the server will return a
	// FAILED_PRECONDITION.
	// If the action does not produce the requested output, then that
	// output
	// will be omitted from the list. The server is free to arrange the
	// output
	// list as desired; clients MUST NOT assume that the output list is
	// sorted.
	OutputDirectorySymlinks []*BuildBazelRemoteExecutionV2OutputSymlink `json:"outputDirectorySymlinks,omitempty"`

	// OutputFileSymlinks: The output files of the action that are symbolic
	// links to other files. Those
	// may be links to other output files, or input files, or even absolute
	// paths
	// outside of the working directory, if the server
	// supports
	// SymlinkAbsolutePathStrategy.ALLOWED.
	// For each output file requested in the `output_files` field of the
	// Action,
	// if the corresponding file existed after
	// the action completed, a single entry will be present either in this
	// field,
	// or in the `output_files` field, if the file was not a symbolic
	// link.
	//
	// If an output symbolic link of the same name was found, but its
	// target
	// type was not a regular file, the server will return a
	// FAILED_PRECONDITION.
	// If the action does not produce the requested output, then that
	// output
	// will be omitted from the list. The server is free to arrange the
	// output
	// list as desired; clients MUST NOT assume that the output list is
	// sorted.
	OutputFileSymlinks []*BuildBazelRemoteExecutionV2OutputSymlink `json:"outputFileSymlinks,omitempty"`

	// OutputFiles: The output files of the action. For each output file
	// requested in the
	// `output_files` field of the Action, if the corresponding file existed
	// after
	// the action completed, a single entry will be present either in this
	// field,
	// or the `output_file_symlinks` field if the file was a symbolic link
	// to
	// another file.
	//
	// If an output of the same name was found, but was a directory
	// rather
	// than a regular file, the server will return a FAILED_PRECONDITION.
	// If the action does not produce the requested output, then that
	// output
	// will be omitted from the list. The server is free to arrange the
	// output
	// list as desired; clients MUST NOT assume that the output list is
	// sorted.
	OutputFiles []*BuildBazelRemoteExecutionV2OutputFile `json:"outputFiles,omitempty"`

	// StderrDigest: The digest for a blob containing the standard error of
	// the action, which
	// can be retrieved from the
	// ContentAddressableStorage.
	StderrDigest *BuildBazelRemoteExecutionV2Digest `json:"stderrDigest,omitempty"`

	// StderrRaw: The standard error buffer of the action. The server SHOULD
	// NOT inline
	// stderr unless requested by the client in
	// the
	// GetActionResultRequest
	// message. The server MAY omit inlining, even if requested, and MUST do
	// so if inlining
	// would cause the response to exceed message size limits.
	StderrRaw string `json:"stderrRaw,omitempty"`

	// StdoutDigest: The digest for a blob containing the standard output of
	// the action, which
	// can be retrieved from the
	// ContentAddressableStorage.
	StdoutDigest *BuildBazelRemoteExecutionV2Digest `json:"stdoutDigest,omitempty"`

	// StdoutRaw: The standard output buffer of the action. The server
	// SHOULD NOT inline
	// stdout unless requested by the client in
	// the
	// GetActionResultRequest
	// message. The server MAY omit inlining, even if requested, and MUST do
	// so if inlining
	// would cause the response to exceed message size limits.
	StdoutRaw string `json:"stdoutRaw,omitempty"`

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

// BuildBazelRemoteExecutionV2Command: A `Command` is the actual command
// executed by a worker running an
// Action and specifications of its
// environment.
//
// Except as otherwise required, the environment (such as which
// system
// libraries or binaries are available, and what filesystems are mounted
// where)
// is defined by and specific to the implementation of the remote
// execution API.
type BuildBazelRemoteExecutionV2Command struct {
	// Arguments: The arguments to the command. The first argument must be
	// the path to the
	// executable, which must be either a relative path, in which case it
	// is
	// evaluated with respect to the input root, or an absolute path.
	Arguments []string `json:"arguments,omitempty"`

	// EnvironmentVariables: The environment variables to set when running
	// the program. The worker may
	// provide its own default environment variables; these defaults can
	// be
	// overridden using this field. Additional variables can also be
	// specified.
	//
	// In order to ensure that equivalent
	// Commands always hash to the same
	// value, the environment variables MUST be lexicographically sorted by
	// name.
	// Sorting of strings is done by code point, equivalently, by the UTF-8
	// bytes.
	EnvironmentVariables []*BuildBazelRemoteExecutionV2CommandEnvironmentVariable `json:"environmentVariables,omitempty"`

	// OutputDirectories: A list of the output directories that the client
	// expects to retrieve from
	// the action. Only the listed directories will be returned (an
	// entire
	// directory structure will be returned as a
	// Tree message digest, see
	// OutputDirectory), as
	// well as files listed in `output_files`. Other files or directories
	// that
	// may be created during command execution are discarded.
	//
	// The paths are relative to the working directory of the action
	// execution.
	// The paths are specified using a single forward slash (`/`) as a
	// path
	// separator, even if the execution platform natively uses a
	// different
	// separator. The path MUST NOT include a trailing slash, nor a leading
	// slash,
	// being a relative path. The special value of empty string is
	// allowed,
	// although not recommended, and can be used to capture the entire
	// working
	// directory tree, including inputs.
	//
	// In order to ensure consistent hashing of the same Action, the output
	// paths
	// MUST be sorted lexicographically by code point (or, equivalently, by
	// UTF-8
	// bytes).
	//
	// An output directory cannot be duplicated or have the same path as any
	// of
	// the listed output files. An output directory is allowed to be a
	// parent of
	// another output directory.
	//
	// Directories leading up to the output directories (but not the
	// output
	// directories themselves) are created by the worker prior to execution,
	// even
	// if they are not explicitly part of the input root.
	OutputDirectories []string `json:"outputDirectories,omitempty"`

	// OutputFiles: A list of the output files that the client expects to
	// retrieve from the
	// action. Only the listed files, as well as directories listed
	// in
	// `output_directories`, will be returned to the client as output.
	// Other files or directories that may be created during command
	// execution
	// are discarded.
	//
	// The paths are relative to the working directory of the action
	// execution.
	// The paths are specified using a single forward slash (`/`) as a
	// path
	// separator, even if the execution platform natively uses a
	// different
	// separator. The path MUST NOT include a trailing slash, nor a leading
	// slash,
	// being a relative path.
	//
	// In order to ensure consistent hashing of the same Action, the output
	// paths
	// MUST be sorted lexicographically by code point (or, equivalently, by
	// UTF-8
	// bytes).
	//
	// An output file cannot be duplicated, be a parent of another output
	// file, or
	// have the same path as any of the listed output
	// directories.
	//
	// Directories leading up to the output files are created by the worker
	// prior
	// to execution, even if they are not explicitly part of the input root.
	OutputFiles []string `json:"outputFiles,omitempty"`

	// Platform: The platform requirements for the execution environment.
	// The server MAY
	// choose to execute the action on any worker satisfying the
	// requirements, so
	// the client SHOULD ensure that running the action on any such worker
	// will
	// have the same result.
	// A detailed lexicon for this can be found in the accompanying
	// platform.md.
	Platform *BuildBazelRemoteExecutionV2Platform `json:"platform,omitempty"`

	// WorkingDirectory: The working directory, relative to the input root,
	// for the command to run
	// in. It must be a directory which exists in the input tree. If it is
	// left
	// empty, then the action is run in the input root.
	WorkingDirectory string `json:"workingDirectory,omitempty"`

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

// BuildBazelRemoteExecutionV2CommandEnvironmentVariable: An
// `EnvironmentVariable` is one variable to set in the running
// program's
// environment.
type BuildBazelRemoteExecutionV2CommandEnvironmentVariable struct {
	// Name: The variable name.
	Name string `json:"name,omitempty"`

	// Value: The variable value.
	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 *BuildBazelRemoteExecutionV2CommandEnvironmentVariable) MarshalJSON() ([]byte, error) {
	type NoMethod BuildBazelRemoteExecutionV2CommandEnvironmentVariable
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildBazelRemoteExecutionV2Digest: A content digest. A digest for a
// given blob consists of the size of the blob
// and its hash. The hash algorithm to use is defined by the server, but
// servers
// SHOULD use SHA-256.
//
// The size is considered to be an integral part of the digest and
// cannot be
// separated. That is, even if the `hash` field is correctly specified
// but
// `size_bytes` is not, the server MUST reject the request.
//
// The reason for including the size in the digest is as follows: in a
// great
// many cases, the server needs to know the size of the blob it is about
// to work
// with prior to starting an operation with it, such as flattening
// Merkle tree
// structures or streaming it to a worker. Technically, the server
// could
// implement a separate metadata store, but this results in a
// significantly more
// complicated implementation as opposed to having the client specify
// the size
// up-front (or storing the size along with the digest in every message
// where
// digests are embedded). This does mean that the API leaks some
// implementation
// details of (what we consider to be) a reasonable server
// implementation, but
// we consider this to be a worthwhile tradeoff.
//
// When a `Digest` is used to refer to a proto message, it always refers
// to the
// message in binary encoded form. To ensure consistent hashing, clients
// and
// servers MUST ensure that they serialize messages according to the
// following
// rules, even if there are alternate valid encodings for the same
// message:
//
// * Fields are serialized in tag order.
// * There are no unknown fields.
// * There are no duplicate fields.
// * Fields are serialized according to the default semantics for their
// type.
//
// Most protocol buffer implementations will always follow these rules
// when
// serializing, but care should be taken to avoid shortcuts. For
// instance,
// concatenating two messages to merge them may produce duplicate
// fields.
type BuildBazelRemoteExecutionV2Digest struct {
	// Hash: The hash. In the case of SHA-256, it will always be a lowercase
	// hex string
	// exactly 64 characters long.
	Hash string `json:"hash,omitempty"`

	// SizeBytes: The size of the blob, in bytes.
	SizeBytes int64 `json:"sizeBytes,omitempty,string"`

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

// BuildBazelRemoteExecutionV2Directory: A `Directory` represents a
// directory node in a file tree, containing zero or
// more children FileNodes,
// DirectoryNodes and
// SymlinkNodes.
// Each `Node` contains its name in the directory, either the digest of
// its
// content (either a file blob or a `Directory` proto) or a symlink
// target, as
// well as possibly some metadata about the file or directory.
//
// In order to ensure that two equivalent directory trees hash to the
// same
// value, the following restrictions MUST be obeyed when constructing
// a
// a `Directory`:
//
// * Every child in the directory must have a path of exactly one
// segment.
//   Multiple levels of directory hierarchy may not be collapsed.
// * Each child in the directory must have a unique path segment (file
// name).
//   Note that while the API itself is case-sensitive, the environment
// where
//   the Action is executed may or may not be case-sensitive. That is,
// it is
//   legal to call the API with a Directory that has both "Foo" and
// "foo" as
//   children, but the Action may be rejected by the remote system upon
//   execution.
// * The files, directories and symlinks in the directory must each be
// sorted
//   in lexicographical order by path. The path strings must be sorted
// by code
//   point, equivalently, by UTF-8 bytes.
//
// A `Directory` that obeys the restrictions is said to be in canonical
// form.
//
// As an example, the following could be used for a file named `bar` and
// a
// directory named `foo` with an executable file named `baz` (hashes
// shortened
// for readability):
//
// ```json
// // (Directory proto)
// {
//   files: [
//     {
//       name: "bar",
//       digest: {
//         hash: "4a73bc9d03...",
//         size: 65534
//       }
//     }
//   ],
//   directories: [
//     {
//       name: "foo",
//       digest: {
//         hash: "4cf2eda940...",
//         size: 43
//       }
//     }
//   ]
// }
//
// // (Directory proto with hash "4cf2eda940..." and size 43)
// {
//   files: [
//     {
//       name: "baz",
//       digest: {
//         hash: "b2c941073e...",
//         size: 1294,
//       },
//       is_executable: true
//     }
//   ]
// }
// ```
type BuildBazelRemoteExecutionV2Directory struct {
	// Directories: The subdirectories in the directory.
	Directories []*BuildBazelRemoteExecutionV2DirectoryNode `json:"directories,omitempty"`

	// Files: The files in the directory.
	Files []*BuildBazelRemoteExecutionV2FileNode `json:"files,omitempty"`

	// Symlinks: The symlinks in the directory.
	Symlinks []*BuildBazelRemoteExecutionV2SymlinkNode `json:"symlinks,omitempty"`

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

// BuildBazelRemoteExecutionV2DirectoryNode: A `DirectoryNode`
// represents a child of a
// Directory which is itself
// a `Directory` and its associated metadata.
type BuildBazelRemoteExecutionV2DirectoryNode struct {
	// Digest: The digest of the
	// Directory object
	// represented. See Digest
	// for information about how to take the digest of a proto message.
	Digest *BuildBazelRemoteExecutionV2Digest `json:"digest,omitempty"`

	// Name: The name of the directory.
	Name string `json:"name,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 *BuildBazelRemoteExecutionV2DirectoryNode) MarshalJSON() ([]byte, error) {
	type NoMethod BuildBazelRemoteExecutionV2DirectoryNode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildBazelRemoteExecutionV2ExecuteOperationMetadata: Metadata about
// an ongoing
// execution, which
// will be contained in the metadata
// field of the
// Operation.
type BuildBazelRemoteExecutionV2ExecuteOperationMetadata struct {
	// ActionDigest: The digest of the Action
	// being executed.
	ActionDigest *BuildBazelRemoteExecutionV2Digest `json:"actionDigest,omitempty"`

	// Stage: The current stage of execution.
	//
	// Possible values:
	//   "UNKNOWN" - Invalid value.
	//   "CACHE_CHECK" - Checking the result against the cache.
	//   "QUEUED" - Currently idle, awaiting a free machine to execute.
	//   "EXECUTING" - Currently being executed by a worker.
	//   "COMPLETED" - Finished execution.
	Stage string `json:"stage,omitempty"`

	// StderrStreamName: If set, the client can use this name
	// with
	// ByteStream.Read to stream the
	// standard error.
	StderrStreamName string `json:"stderrStreamName,omitempty"`

	// StdoutStreamName: If set, the client can use this name
	// with
	// ByteStream.Read to stream the
	// standard output.
	StdoutStreamName string `json:"stdoutStreamName,omitempty"`

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

// BuildBazelRemoteExecutionV2ExecuteResponse: The response message
// for
// Execution.Execute,
// which will be contained in the response
// field of the
// Operation.
type BuildBazelRemoteExecutionV2ExecuteResponse struct {
	// CachedResult: True if the result was served from cache, false if it
	// was executed.
	CachedResult bool `json:"cachedResult,omitempty"`

	// Message: Freeform informational message with details on the execution
	// of the action
	// that may be displayed to the user upon failure or when requested
	// explicitly.
	Message string `json:"message,omitempty"`

	// Result: The result of the action.
	Result *BuildBazelRemoteExecutionV2ActionResult `json:"result,omitempty"`

	// ServerLogs: An optional list of additional log outputs the server
	// wishes to provide. A
	// server can use this to return execution-specific logs however it
	// wishes.
	// This is intended primarily to make it easier for users to debug
	// issues that
	// may be outside of the actual job execution, such as by identifying
	// the
	// worker executing the action or by providing logs from the worker's
	// setup
	// phase. The keys SHOULD be human readable so that a client can display
	// them
	// to a user.
	ServerLogs map[string]BuildBazelRemoteExecutionV2LogFile `json:"serverLogs,omitempty"`

	// Status: If the status has a code other than `OK`, it indicates that
	// the action did
	// not finish execution. For example, if the operation times out
	// during
	// execution, the status will have a `DEADLINE_EXCEEDED` code. Servers
	// MUST
	// use this field for errors in execution, rather than the error field
	// on the
	// `Operation` object.
	//
	// If the status code is other than `OK`, then the result MUST NOT be
	// cached.
	// For an error status, the `result` field is optional; the server
	// may
	// populate the output-, stdout-, and stderr-related fields if it has
	// any
	// information available, such as the stdout and stderr of a timed-out
	// action.
	Status *GoogleRpcStatus `json:"status,omitempty"`

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

// BuildBazelRemoteExecutionV2ExecutedActionMetadata:
// ExecutedActionMetadata contains details about a completed execution.
type BuildBazelRemoteExecutionV2ExecutedActionMetadata struct {
	// ExecutionCompletedTimestamp: When the worker completed executing the
	// action command.
	ExecutionCompletedTimestamp string `json:"executionCompletedTimestamp,omitempty"`

	// ExecutionStartTimestamp: When the worker started executing the action
	// command.
	ExecutionStartTimestamp string `json:"executionStartTimestamp,omitempty"`

	// InputFetchCompletedTimestamp: When the worker finished fetching
	// action inputs.
	InputFetchCompletedTimestamp string `json:"inputFetchCompletedTimestamp,omitempty"`

	// InputFetchStartTimestamp: When the worker started fetching action
	// inputs.
	InputFetchStartTimestamp string `json:"inputFetchStartTimestamp,omitempty"`

	// OutputUploadCompletedTimestamp: When the worker finished uploading
	// action outputs.
	OutputUploadCompletedTimestamp string `json:"outputUploadCompletedTimestamp,omitempty"`

	// OutputUploadStartTimestamp: When the worker started uploading action
	// outputs.
	OutputUploadStartTimestamp string `json:"outputUploadStartTimestamp,omitempty"`

	// QueuedTimestamp: When was the action added to the queue.
	QueuedTimestamp string `json:"queuedTimestamp,omitempty"`

	// Worker: The name of the worker which ran the execution.
	Worker string `json:"worker,omitempty"`

	// WorkerCompletedTimestamp: When the worker completed the action,
	// including all stages.
	WorkerCompletedTimestamp string `json:"workerCompletedTimestamp,omitempty"`

	// WorkerStartTimestamp: When the worker received the action.
	WorkerStartTimestamp string `json:"workerStartTimestamp,omitempty"`

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

// BuildBazelRemoteExecutionV2FileNode: A `FileNode` represents a single
// file and associated metadata.
type BuildBazelRemoteExecutionV2FileNode struct {
	// Digest: The digest of the file's content.
	Digest *BuildBazelRemoteExecutionV2Digest `json:"digest,omitempty"`

	// IsExecutable: True if file is executable, false otherwise.
	IsExecutable bool `json:"isExecutable,omitempty"`

	// Name: The name of the file.
	Name string `json:"name,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 *BuildBazelRemoteExecutionV2FileNode) MarshalJSON() ([]byte, error) {
	type NoMethod BuildBazelRemoteExecutionV2FileNode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildBazelRemoteExecutionV2LogFile: A `LogFile` is a log stored in
// the CAS.
type BuildBazelRemoteExecutionV2LogFile struct {
	// Digest: The digest of the log contents.
	Digest *BuildBazelRemoteExecutionV2Digest `json:"digest,omitempty"`

	// HumanReadable: This is a hint as to the purpose of the log, and is
	// set to true if the log
	// is human-readable text that can be usefully displayed to a user, and
	// false
	// otherwise. For instance, if a command-line client wishes to print
	// the
	// server logs to the terminal for a failed action, this allows it to
	// avoid
	// displaying a binary file.
	HumanReadable bool `json:"humanReadable,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 *BuildBazelRemoteExecutionV2LogFile) MarshalJSON() ([]byte, error) {
	type NoMethod BuildBazelRemoteExecutionV2LogFile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildBazelRemoteExecutionV2OutputDirectory: An `OutputDirectory` is
// the output in an `ActionResult` corresponding to a
// directory's full contents rather than a single file.
type BuildBazelRemoteExecutionV2OutputDirectory struct {
	// Path: The full path of the directory relative to the working
	// directory. The path
	// separator is a forward slash `/`. Since this is a relative path, it
	// MUST
	// NOT begin with a leading forward slash. The empty string value is
	// allowed,
	// and it denotes the entire working directory.
	Path string `json:"path,omitempty"`

	// TreeDigest: The digest of the encoded
	// Tree proto containing the
	// directory's contents.
	TreeDigest *BuildBazelRemoteExecutionV2Digest `json:"treeDigest,omitempty"`

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

// BuildBazelRemoteExecutionV2OutputFile: An `OutputFile` is similar to
// a
// FileNode, but it is used as an
// output in an `ActionResult`. It allows a full file path rather
// than
// only a name.
type BuildBazelRemoteExecutionV2OutputFile struct {
	// Contents: The contents of the file if inlining was requested. The
	// server SHOULD NOT inline
	// file contents unless requested by the client in
	// the
	// GetActionResultRequest
	// message. The server MAY omit inlining, even if requested, and MUST do
	// so if inlining
	// would cause the response to exceed message size limits.
	Contents string `json:"contents,omitempty"`

	// Digest: The digest of the file's content.
	Digest *BuildBazelRemoteExecutionV2Digest `json:"digest,omitempty"`

	// IsExecutable: True if file is executable, false otherwise.
	IsExecutable bool `json:"isExecutable,omitempty"`

	// Path: The full path of the file relative to the working directory,
	// including the
	// filename. The path separator is a forward slash `/`. Since this is
	// a
	// relative path, it MUST NOT begin with a leading forward slash.
	Path string `json:"path,omitempty"`

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

// BuildBazelRemoteExecutionV2OutputSymlink: An `OutputSymlink` is
// similar to a
// Symlink, but it is used as an
// output in an `ActionResult`.
//
// `OutputSymlink` is binary-compatible with `SymlinkNode`.
type BuildBazelRemoteExecutionV2OutputSymlink struct {
	// Path: The full path of the symlink relative to the working directory,
	// including the
	// filename. The path separator is a forward slash `/`. Since this is
	// a
	// relative path, it MUST NOT begin with a leading forward slash.
	Path string `json:"path,omitempty"`

	// Target: The target path of the symlink. The path separator is a
	// forward slash `/`.
	// The target path can be relative to the parent directory of the
	// symlink or
	// it can be an absolute path starting with `/`. Support for absolute
	// paths
	// can be checked using the Capabilities
	// API. The canonical form forbids the substrings `/./` and `//` in the
	// target
	// path. `..` components are allowed anywhere in the target path.
	Target string `json:"target,omitempty"`

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

// BuildBazelRemoteExecutionV2Platform: A `Platform` is a set of
// requirements, such as hardware, operating system, or
// compiler toolchain, for an
// Action's execution
// environment. A `Platform` is represented as a series of key-value
// pairs
// representing the properties that are required of the platform.
type BuildBazelRemoteExecutionV2Platform struct {
	// Properties: The properties that make up this platform. In order to
	// ensure that
	// equivalent `Platform`s always hash to the same value, the properties
	// MUST
	// be lexicographically sorted by name, and then by value. Sorting of
	// strings
	// is done by code point, equivalently, by the UTF-8 bytes.
	Properties []*BuildBazelRemoteExecutionV2PlatformProperty `json:"properties,omitempty"`

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

// BuildBazelRemoteExecutionV2PlatformProperty: A single property for
// the environment. The server is responsible for
// specifying the property `name`s that it accepts. If an unknown `name`
// is
// provided in the requirements for an
// Action, the server SHOULD
// reject the execution request. If permitted by the server, the same
// `name`
// may occur multiple times.
//
// The server is also responsible for specifying the interpretation
// of
// property `value`s. For instance, a property describing how much RAM
// must be
// available may be interpreted as allowing a worker with 16GB to
// fulfill a
// request for 8GB, while a property describing the OS environment on
// which
// the action must be performed may require an exact match with the
// worker's
// OS.
//
// The server MAY use the `value` of one or more properties to determine
// how
// it sets up the execution environment, such as by making specific
// system
// files available to the worker.
type BuildBazelRemoteExecutionV2PlatformProperty struct {
	// Name: The property name.
	Name string `json:"name,omitempty"`

	// Value: The property value.
	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 *BuildBazelRemoteExecutionV2PlatformProperty) MarshalJSON() ([]byte, error) {
	type NoMethod BuildBazelRemoteExecutionV2PlatformProperty
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildBazelRemoteExecutionV2RequestMetadata: An optional Metadata to
// attach to any RPC request to tell the server about an
// external context of the request. The server may use this for logging
// or other
// purposes. To use it, the client attaches the header to the call using
// the
// canonical proto serialization:
//
// * name: `build.bazel.remote.execution.v2.requestmetadata-bin`
// * contents: the base64 encoded binary `RequestMetadata`
// message.
// Note: the gRPC library serializes binary headers encoded in base 64
// by
// default
// (https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#reques
// ts).
// Therefore, if the gRPC library is used to pass/retrieve
// this
// metadata, the user may ignore the base64 encoding and assume it is
// simply
// serialized as a binary message.
type BuildBazelRemoteExecutionV2RequestMetadata struct {
	// ActionId: An identifier that ties multiple requests to the same
	// action.
	// For example, multiple requests to the CAS, Action Cache, and
	// Execution
	// API are used in order to compile foo.cc.
	ActionId string `json:"actionId,omitempty"`

	// CorrelatedInvocationsId: An identifier to tie multiple tool
	// invocations together. For example,
	// runs of foo_test, bar_test and baz_test on a post-submit of a given
	// patch.
	CorrelatedInvocationsId string `json:"correlatedInvocationsId,omitempty"`

	// ToolDetails: The details for the tool invoking the requests.
	ToolDetails *BuildBazelRemoteExecutionV2ToolDetails `json:"toolDetails,omitempty"`

	// ToolInvocationId: An identifier that ties multiple actions together
	// to a final result.
	// For example, multiple actions are required to build and run foo_test.
	ToolInvocationId string `json:"toolInvocationId,omitempty"`

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

// BuildBazelRemoteExecutionV2SymlinkNode: A `SymlinkNode` represents a
// symbolic link.
type BuildBazelRemoteExecutionV2SymlinkNode struct {
	// Name: The name of the symlink.
	Name string `json:"name,omitempty"`

	// Target: The target path of the symlink. The path separator is a
	// forward slash `/`.
	// The target path can be relative to the parent directory of the
	// symlink or
	// it can be an absolute path starting with `/`. Support for absolute
	// paths
	// can be checked using the Capabilities
	// API. The canonical form forbids the substrings `/./` and `//` in the
	// target
	// path. `..` components are allowed anywhere in the target path.
	Target string `json:"target,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 *BuildBazelRemoteExecutionV2SymlinkNode) MarshalJSON() ([]byte, error) {
	type NoMethod BuildBazelRemoteExecutionV2SymlinkNode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BuildBazelRemoteExecutionV2ToolDetails: Details for the tool used to
// call the API.
type BuildBazelRemoteExecutionV2ToolDetails struct {
	// ToolName: Name of the tool, e.g. bazel.
	ToolName string `json:"toolName,omitempty"`

	// ToolVersion: Version of the tool used for the request, e.g. 5.0.3.
	ToolVersion string `json:"toolVersion,omitempty"`

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

// BuildBazelRemoteExecutionV2Tree: A `Tree` contains all the
// Directory protos in a
// single directory Merkle tree, compressed into one message.
type BuildBazelRemoteExecutionV2Tree struct {
	// Children: All the child directories: the directories referred to by
	// the root and,
	// recursively, all its children. In order to reconstruct the directory
	// tree,
	// the client must take the digests of each of the child directories and
	// then
	// build up a tree starting from the `root`.
	Children []*BuildBazelRemoteExecutionV2Directory `json:"children,omitempty"`

	// Root: The root directory in the tree.
	Root *BuildBazelRemoteExecutionV2Directory `json:"root,omitempty"`

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

// GoogleBytestreamMedia: Media resource.
type GoogleBytestreamMedia struct {
	// ResourceName: Name of the media resource.
	ResourceName string `json:"resourceName,omitempty"`

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

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

// GoogleDevtoolsRemotebuildbotCommandDurations: CommandDuration
// contains the various duration metrics tracked when a bot
// performs a command.
type GoogleDevtoolsRemotebuildbotCommandDurations struct {
	// DockerPrep: The time spent preparing the command to be run in a
	// Docker container
	// (includes pulling the Docker image, if necessary).
	DockerPrep string `json:"dockerPrep,omitempty"`

	// DockerPrepStartTime: The timestamp when docker prepartion begins.
	DockerPrepStartTime string `json:"dockerPrepStartTime,omitempty"`

	// Download: The time spent downloading the input files and constructing
	// the working
	// directory.
	Download string `json:"download,omitempty"`

	// DownloadStartTime: The timestamp when downloading the input files
	// begins.
	DownloadStartTime string `json:"downloadStartTime,omitempty"`

	// ExecStartTime: The timestamp when execution begins.
	ExecStartTime string `json:"execStartTime,omitempty"`

	// Execution: The time spent executing the command (i.e., doing useful
	// work).
	Execution string `json:"execution,omitempty"`

	// IsoPrepDone: The timestamp when preparation is done and bot starts
	// downloading files.
	IsoPrepDone string `json:"isoPrepDone,omitempty"`

	// Overall: The time spent completing the command, in total.
	Overall string `json:"overall,omitempty"`

	// Stdout: The time spent uploading the stdout logs.
	Stdout string `json:"stdout,omitempty"`

	// Upload: The time spent uploading the output files.
	Upload string `json:"upload,omitempty"`

	// UploadStartTime: The timestamp when uploading the output files
	// begins.
	UploadStartTime string `json:"uploadStartTime,omitempty"`

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

// GoogleDevtoolsRemotebuildbotCommandEvents: CommandEvents contains
// counters for the number of warnings and errors
// that occurred during the execution of a command.
type GoogleDevtoolsRemotebuildbotCommandEvents struct {
	// DockerCacheHit: Indicates whether we are using a cached Docker image
	// (true) or had to pull
	// the Docker image (false) for this command.
	DockerCacheHit bool `json:"dockerCacheHit,omitempty"`

	// InputCacheMiss: The input cache miss ratio.
	InputCacheMiss float64 `json:"inputCacheMiss,omitempty"`

	// NumErrors: The number of errors reported.
	NumErrors uint64 `json:"numErrors,omitempty,string"`

	// NumWarnings: The number of warnings reported.
	NumWarnings uint64 `json:"numWarnings,omitempty,string"`

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

func (s *GoogleDevtoolsRemotebuildbotCommandEvents) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleDevtoolsRemotebuildbotCommandEvents
	var s1 struct {
		InputCacheMiss gensupport.JSONFloat64 `json:"inputCacheMiss"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.InputCacheMiss = float64(s1.InputCacheMiss)
	return nil
}

// GoogleDevtoolsRemotebuildbotCommandStatus: The internal status of the
// command result.
type GoogleDevtoolsRemotebuildbotCommandStatus struct {
	// Code: The status code.
	//
	// Possible values:
	//   "OK" - The command succeeded.
	//   "INVALID_ARGUMENT" - The command input was invalid.
	//   "DEADLINE_EXCEEDED" - The command had passed its expiry time while
	// it was still running.
	//   "NOT_FOUND" - The resources requested by the command were not
	// found.
	//   "PERMISSION_DENIED" - The command failed due to permission errors.
	//   "INTERNAL" - The command failed because of some invariants expected
	// by the underlying
	// system have been broken. This usually indicates a bug wit the system.
	//   "ABORTED" - The command was aborted.
	//   "CLEANUP_ERROR" - The bot failed to do the cleanup, e.g. unable to
	// delete the command
	// working directory or the command process.
	//   "DOWNLOAD_INPUTS_ERROR" - The bot failed to download the inputs.
	//   "UNKNOWN" - Unknown error.
	//   "UPLOAD_OUTPUTS_ERROR" - The bot failed to upload the outputs.
	//   "DOCKER_LOGIN_ERROR" - The bot failed to login to docker.
	//   "DOCKER_IMAGE_PULL_ERROR" - The bot failed to pull docker image.
	//   "DOCKER_IMAGE_EXIST_ERROR" - The bot failed to check docker images.
	//   "DUPLICATE_INPUTS" - The inputs contain duplicate files.
	//   "DOCKER_IMAGE_PERMISSION_DENIED" - The bot doesn't have the
	// permissions to pull docker images.
	//   "DOCKER_IMAGE_NOT_FOUND" - The docker image cannot be found.
	//   "WORKING_DIR_NOT_FOUND" - Working directory is not found.
	//   "WORKING_DIR_NOT_IN_BASE_DIR" - Working directory is not under the
	// base directory
	//   "DOCKER_UNAVAILABLE" - There are issues with docker
	// service/runtime.
	Code string `json:"code,omitempty"`

	// Message: The error message.
	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 *GoogleDevtoolsRemotebuildbotCommandStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildbotCommandStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemotebuildbotResourceUsage: ResourceUsage is the
// system resource usage of the host machine.
type GoogleDevtoolsRemotebuildbotResourceUsage struct {
	CpuUsedPercent float64 `json:"cpuUsedPercent,omitempty"`

	DiskUsage *GoogleDevtoolsRemotebuildbotResourceUsageStat `json:"diskUsage,omitempty"`

	MemoryUsage *GoogleDevtoolsRemotebuildbotResourceUsageStat `json:"memoryUsage,omitempty"`

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

func (s *GoogleDevtoolsRemotebuildbotResourceUsage) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleDevtoolsRemotebuildbotResourceUsage
	var s1 struct {
		CpuUsedPercent gensupport.JSONFloat64 `json:"cpuUsedPercent"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.CpuUsedPercent = float64(s1.CpuUsedPercent)
	return nil
}

type GoogleDevtoolsRemotebuildbotResourceUsageStat struct {
	Total uint64 `json:"total,omitempty,string"`

	Used uint64 `json:"used,omitempty,string"`

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaAcceleratorConfig:
// AcceleratorConfig defines the accelerator cards to attach to the VM.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaAcceleratorConfig struct {
	// AcceleratorCount: The number of guest accelerator cards exposed to
	// each VM.
	AcceleratorCount int64 `json:"acceleratorCount,omitempty,string"`

	// AcceleratorType: The type of accelerator to attach to each VM, e.g.
	// "nvidia-tesla-k80" for
	// nVidia Tesla K80.
	AcceleratorType string `json:"acceleratorType,omitempty"`

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateInstanceRequest:
// The request used for `CreateInstance`.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateInstanceRequest struct {
	// Instance: Specifies the instance to create.
	// The name in the instance, if specified in the instance, is ignored.
	Instance *GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance `json:"instance,omitempty"`

	// InstanceId: ID of the created instance.
	// A valid `instance_id` must:
	// be 6-50 characters long,
	// contain only lowercase letters, digits, hyphens and
	// underscores,
	// start with a lowercase letter, and
	// end with a lowercase letter or a digit.
	InstanceId string `json:"instanceId,omitempty"`

	// Parent: Resource name of the project containing the instance.
	// Format: `projects/[PROJECT_ID]`.
	Parent string `json:"parent,omitempty"`

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateWorkerPoolRequest:
//  The request used for `CreateWorkerPool`.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateWorkerPoolRequest struct {
	// Parent: Resource name of the instance in which to create the new
	// worker pool.
	// Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
	Parent string `json:"parent,omitempty"`

	// PoolId: ID of the created worker pool.
	// A valid pool ID must:
	// be 6-50 characters long,
	// contain only lowercase letters, digits, hyphens and
	// underscores,
	// start with a lowercase letter, and
	// end with a lowercase letter or a digit.
	PoolId string `json:"poolId,omitempty"`

	// WorkerPool: Specifies the worker pool to create.
	// The name in the worker pool, if specified, is ignored.
	WorkerPool *GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool `json:"workerPool,omitempty"`

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteInstanceRequest:
// The request used for `DeleteInstance`.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteInstanceRequest struct {
	// Name: Name of the instance to delete.
	// Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
	Name string `json:"name,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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteInstanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteInstanceRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteWorkerPoolRequest:
//  The request used for DeleteWorkerPool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteWorkerPoolRequest struct {
	// Name: Name of the worker pool to
	// delete.
	// Format:
	// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/workerp
	// ools/[POOL_ID]`.
	Name string `json:"name,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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteWorkerPoolRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteWorkerPoolRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetInstanceRequest: The
// request used for `GetInstance`.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetInstanceRequest struct {
	// Name: Name of the instance to retrieve.
	// Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
	Name string `json:"name,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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetInstanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetInstanceRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetWorkerPoolRequest:
// The request used for GetWorkerPool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetWorkerPoolRequest struct {
	// Name: Name of the worker pool to
	// retrieve.
	// Format:
	// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/worke
	// rpools/[POOL_ID]`.
	Name string `json:"name,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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetWorkerPoolRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetWorkerPoolRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance: Instance
// conceptually encapsulates all Remote Build Execution resources
// for remote builds.
// An instance consists of storage and compute resources (for
// example,
// `ContentAddressableStorage`, `ActionCache`, `WorkerPools`) used
// for
// running remote builds.
// All Remote Build Execution API calls are scoped to an instance.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance struct {
	// Location: The location is a GCP region. Currently only `us-central1`
	// is supported.
	Location string `json:"location,omitempty"`

	// LoggingEnabled: Output only. Whether stack driver logging is enabled
	// for the instance.
	LoggingEnabled bool `json:"loggingEnabled,omitempty"`

	// Name: Output only. Instance resource name formatted
	// as:
	// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
	// Name should not be populated when creating an instance since it is
	// provided
	// in the `instance_id` field.
	Name string `json:"name,omitempty"`

	// State: Output only. State of the instance.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Not a valid state, but the default value of
	// the enum.
	//   "CREATING" - The instance is in state `CREATING` once
	// `CreateInstance` is called and
	// before the instance is ready for use.
	//   "RUNNING" - The instance is in state `RUNNING` when it is ready for
	// use.
	//   "INACTIVE" - An `INACTIVE` instance indicates that there is a
	// problem that needs to be
	// fixed. Such instances cannot be used for execution and instances
	// that
	// remain in this state for a significant period of time will be
	// removed
	// permanently.
	State string `json:"state,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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleDevtoolsRemotebuildexecutionAdminV1alphaListInstancesRequest struct {
	// Parent: Resource name of the project.
	// Format: `projects/[PROJECT_ID]`.
	Parent string `json:"parent,omitempty"`

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

type GoogleDevtoolsRemotebuildexecutionAdminV1alphaListInstancesResponse struct {
	// Instances: The list of instances in a given project.
	Instances []*GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance `json:"instances,omitempty"`

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

type GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsRequest struct {
	// Filter: Optional. A filter expression that filters resources listed
	// in
	// the response. The expression must specify the field name, a
	// comparison
	// operator, and the value that you want to use for filtering. The
	// value
	// must be a string, a number, or a boolean. String values
	// are
	// case-insensitive.
	// The comparison operator must be either `:`, `=`, `!=`, `>`, `>=`,
	// `<=` or
	// `<`.
	// The `:` operator can be used with string fields to match
	// substrings.
	// For non-string fields it is equivalent to the `=` operator.
	// The `:*` comparison can be used to test  whether a key has been
	// defined.
	//
	// You can also filter on nested fields.
	//
	// To filter on multiple expressions, you can separate expression
	// using
	// `AND` and `OR` operators, using parentheses to specify precedence.
	// If
	// neither operator is specified, `AND` is assumed.
	//
	// Examples:
	//
	// Include only pools with more than 100 reserved
	// workers:
	// `(worker_count > 100) (worker_config.reserved = true)`
	//
	// Include only pools with a certain label or machines of the
	// n1-standard
	// family:
	// `worker_config.labels.key1 : * OR worker_config.machine_type:
	// n1-standard`
	Filter string `json:"filter,omitempty"`

	// Parent: Resource name of the instance.
	// Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
	Parent string `json:"parent,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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsResponse struct {
	// WorkerPools: The list of worker pools in a given instance.
	WorkerPools []*GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool `json:"workerPools,omitempty"`

	// 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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateInstanceRequest:
// The request used for `UpdateInstance`.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateInstanceRequest struct {
	// LoggingEnabled: Whether to enable Stackdriver logging for this
	// instance.
	LoggingEnabled bool `json:"loggingEnabled,omitempty"`

	// Name: Name of the instance to update.
	// Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
	Name string `json:"name,omitempty"`

	// UpdateMask: The fields to update.
	UpdateMask string `json:"updateMask,omitempty"`

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateWorkerPoolRequest:
//  The request used for UpdateWorkerPool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateWorkerPoolRequest struct {
	// UpdateMask: The update mask applies to worker_pool. For the
	// `FieldMask`
	// definition,
	// see
	// https://developers.google.com/protocol-buffers/docs/re
	// ference/google.protobuf#fieldmask
	// If an empty update_mask is provided, only the non-default valued
	// field in
	// the worker pool field will be updated. Note that in order to update a
	// field
	// to the default value (zero, false, empty string) an explicit
	// update_mask
	// must be provided.
	UpdateMask string `json:"updateMask,omitempty"`

	// WorkerPool: Specifies the worker pool to update.
	WorkerPool *GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool `json:"workerPool,omitempty"`

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerConfig: Defines
// the configuration to be used for a creating workers in
// the worker pool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerConfig struct {
	// Accelerator: The accelerator card attached to each VM.
	Accelerator *GoogleDevtoolsRemotebuildexecutionAdminV1alphaAcceleratorConfig `json:"accelerator,omitempty"`

	// DiskSizeGb: Required. Size of the disk attached to the worker, in
	// GB.
	// See https://cloud.google.com/compute/docs/disks/
	DiskSizeGb int64 `json:"diskSizeGb,omitempty,string"`

	// DiskType: Required. Disk Type to use for the worker.
	// See
	// [Storage
	// options](https://cloud.google.com/compute/docs/disks/#introdu
	// ction).
	// Currently only `pd-standard` is supported.
	DiskType string `json:"diskType,omitempty"`

	// Labels: Labels associated with the workers.
	// Label keys and values can be no longer than 63 characters, can only
	// contain
	// lowercase letters, numeric characters, underscores and
	// dashes.
	// International letters are permitted. Label keys must start with a
	// letter.
	// Label values are optional.
	// There can not be more than 64 labels per resource.
	Labels map[string]string `json:"labels,omitempty"`

	// MachineType: Required. Machine type of the worker, such as
	// `n1-standard-2`.
	// See https://cloud.google.com/compute/docs/machine-types for a list
	// of
	// supported machine types. Note that `f1-micro` and `g1-small` are not
	// yet
	// supported.
	MachineType string `json:"machineType,omitempty"`

	// MinCpuPlatform: Minimum CPU platform to use when creating the
	// worker.
	// See [CPU
	// Platforms](https://cloud.google.com/compute/docs/cpu-platforms).
	MinCpuPlatform string `json:"minCpuPlatform,omitempty"`

	// NetworkAccess: Determines the type of network access granted to
	// workers. Possible values:
	//
	// - "public": Workers can connect to the public internet.
	// - "private": Workers can only connect to Google APIs and services.
	// - "restricted-private": Workers can only connect to Google APIs that
	// are
	//   reachable through `restricted.googleapis.com` (`199.36.153.4/30`).
	NetworkAccess string `json:"networkAccess,omitempty"`

	// Reserved: Determines whether the worker is reserved (equivalent to a
	// Compute Engine
	// on-demand VM and therefore won't be preempted).
	// See [Preemptible VMs](https://cloud.google.com/preemptible-vms/) for
	// more
	// details.
	Reserved bool `json:"reserved,omitempty"`

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool: A worker
// pool resource in the Remote Build Execution API.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool struct {
	// Name: WorkerPool resource name formatted
	// as:
	// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/workerpools/[POOL_I
	// D]`.
	// name should not be populated when creating a worker pool since it
	// is
	// provided in the `poolId` field.
	Name string `json:"name,omitempty"`

	// State: Output only. State of the worker pool.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Not a valid state, but the default value of
	// the enum.
	//   "CREATING" - The worker pool is in state `CREATING` once
	// `CreateWorkerPool` is called
	// and before all requested workers are ready.
	//   "RUNNING" - The worker pool is in state `RUNNING` when all its
	// workers are ready for
	// use.
	//   "UPDATING" - The worker pool is in state `UPDATING` once
	// `UpdateWorkerPool` is called
	// and before the new configuration has all the requested workers ready
	// for
	// use, and no older configuration has any workers. At that point the
	// state
	// transitions to `RUNNING`.
	//   "DELETING" - The worker pool is in state `DELETING` once the
	// `Delete` method is called
	// and before the deletion completes.
	//   "INACTIVE" - The worker pool is in state `INACTIVE` when the
	// instance hosting the
	// worker pool in not running.
	State string `json:"state,omitempty"`

	// WorkerConfig: Specifies the properties, such as machine type and disk
	// size, used for
	// creating workers in a worker pool.
	WorkerConfig *GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerConfig `json:"workerConfig,omitempty"`

	// WorkerCount: The desired number of workers in the worker pool. Must
	// be a value between
	// 0 and 1000.
	WorkerCount int64 `json:"workerCount,omitempty,string"`

	// 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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteworkersV1test2AdminTemp: AdminTemp is a
// prelimiary set of administration tasks. It's called "Temp"
// because we do not yet know the best way to represent admin tasks;
// it's
// possible that this will be entirely replaced in later versions of
// this API.
// If this message proves to be sufficient, it will be renamed in the
// alpha or
// beta release of this API.
//
// This message (suitably marshalled into a protobuf.Any) can be used as
// the
// inline_assignment field in a lease; the lease assignment field should
// simply
// be "admin" in these cases.
//
// This message is heavily based on Swarming administration tasks from
// the LUCI
// project (http://github.com/luci/luci-py/appengine/swarming).
type GoogleDevtoolsRemoteworkersV1test2AdminTemp struct {
	// Arg: The argument to the admin action; see `Command` for semantics.
	Arg string `json:"arg,omitempty"`

	// Command: The admin action; see `Command` for legal values.
	//
	// Possible values:
	//   "UNSPECIFIED" - Illegal value.
	//   "BOT_UPDATE" - Download and run a new version of the bot. `arg`
	// will be a resource
	// accessible via `ByteStream.Read` to obtain the new bot code.
	//   "BOT_RESTART" - Restart the bot without downloading a new version.
	// `arg` will be a
	// message to log.
	//   "BOT_TERMINATE" - Shut down the bot. `arg` will be a task resource
	// name (similar to those
	// in tasks.proto) that the bot can use to tell the server that it
	// is
	// terminating.
	//   "HOST_RESTART" - Restart the host computer. `arg` will be a message
	// to log.
	Command string `json:"command,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2Blob: Describes a blob of binary
// content with its digest.
type GoogleDevtoolsRemoteworkersV1test2Blob struct {
	// Contents: The contents of the blob.
	Contents string `json:"contents,omitempty"`

	// Digest: The digest of the blob. This should be verified by the
	// receiver.
	Digest *GoogleDevtoolsRemoteworkersV1test2Digest `json:"digest,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2CommandOutputs: DEPRECATED - use
// CommandResult instead.
// Describes the actual outputs from the task.
type GoogleDevtoolsRemoteworkersV1test2CommandOutputs struct {
	// ExitCode: exit_code is only fully reliable if the status' code is OK.
	// If the task
	// exceeded its deadline or was cancelled, the process may still produce
	// an
	// exit code as it is cancelled, and this will be populated, but a
	// successful
	// (zero) is unlikely to be correct unless the status code is OK.
	ExitCode int64 `json:"exitCode,omitempty"`

	// Outputs: The output files. The blob referenced by the digest should
	// contain
	// one of the following (implementation-dependent):
	//    * A marshalled DirectoryMetadata of the returned filesystem
	//    * A LUCI-style .isolated file
	Outputs *GoogleDevtoolsRemoteworkersV1test2Digest `json:"outputs,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2CommandOverhead: DEPRECATED - use
// CommandResult instead.
// Can be used as part of CompleteRequest.metadata, or are part of a
// more
// sophisticated message.
type GoogleDevtoolsRemoteworkersV1test2CommandOverhead struct {
	// Duration: The elapsed time between calling Accept and Complete. The
	// server will also
	// have its own idea of what this should be, but this excludes the
	// overhead of
	// the RPCs and the bot response time.
	Duration string `json:"duration,omitempty"`

	// Overhead: The amount of time *not* spent executing the command
	// (ie
	// uploading/downloading files).
	Overhead string `json:"overhead,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2CommandResult: All information
// about the execution of a command, suitable for providing as
// the Bots interface's `Lease.result` field.
type GoogleDevtoolsRemoteworkersV1test2CommandResult struct {
	// Duration: The elapsed time between calling Accept and Complete. The
	// server will also
	// have its own idea of what this should be, but this excludes the
	// overhead of
	// the RPCs and the bot response time.
	Duration string `json:"duration,omitempty"`

	// ExitCode: The exit code of the process. An exit code of "0" should
	// only be trusted if
	// `status` has a code of OK (otherwise it may simply be unset).
	ExitCode int64 `json:"exitCode,omitempty"`

	// Metadata: Implementation-dependent metadata about the task. Both
	// servers and bots
	// may define messages which can be encoded here; bots are free to
	// provide
	// metadata in multiple formats, and servers are free to choose one or
	// more
	// of the values to process and ignore others. In particular, it is
	// *not*
	// considered an error for the bot to provide the server with a field
	// that it
	// doesn't know about.
	Metadata []googleapi.RawMessage `json:"metadata,omitempty"`

	// Outputs: The output files. The blob referenced by the digest should
	// contain
	// one of the following (implementation-dependent):
	//    * A marshalled DirectoryMetadata of the returned filesystem
	//    * A LUCI-style .isolated file
	Outputs *GoogleDevtoolsRemoteworkersV1test2Digest `json:"outputs,omitempty"`

	// Overhead: The amount of time *not* spent executing the command
	// (ie
	// uploading/downloading files).
	Overhead string `json:"overhead,omitempty"`

	// Status: An overall status for the command. For example, if the
	// command timed out,
	// this might have a code of DEADLINE_EXCEEDED; if it was killed by the
	// OS for
	// memory exhaustion, it might have a code of RESOURCE_EXHAUSTED.
	Status *GoogleRpcStatus `json:"status,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2CommandTask: Describes a
// shell-style task to execute, suitable for providing as the
// Bots
// interface's `Lease.payload` field.
type GoogleDevtoolsRemoteworkersV1test2CommandTask struct {
	// ExpectedOutputs: The expected outputs from the task.
	ExpectedOutputs *GoogleDevtoolsRemoteworkersV1test2CommandTaskOutputs `json:"expectedOutputs,omitempty"`

	// Inputs: The inputs to the task.
	Inputs *GoogleDevtoolsRemoteworkersV1test2CommandTaskInputs `json:"inputs,omitempty"`

	// Timeouts: The timeouts of this task.
	Timeouts *GoogleDevtoolsRemoteworkersV1test2CommandTaskTimeouts `json:"timeouts,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2CommandTaskInputs: Describes the
// inputs to a shell-style task.
type GoogleDevtoolsRemoteworkersV1test2CommandTaskInputs struct {
	// Arguments: The command itself to run (e.g., argv).
	//
	// This field should be passed directly to the underlying operating
	// system,
	// and so it must be sensible to that operating system. For example,
	// on
	// Windows, the first argument might be "C:\Windows\System32\ping.exe"
	// -
	// that is, using drive letters and backslashes. A command for a
	// *nix
	// system, on the other hand, would use forward slashes.
	//
	// All other fields in the RWAPI must consistently use forward
	// slashes,
	// since those fields may be interpretted by both the service and the
	// bot.
	Arguments []string `json:"arguments,omitempty"`

	// EnvironmentVariables: All environment variables required by the task.
	EnvironmentVariables []*GoogleDevtoolsRemoteworkersV1test2CommandTaskInputsEnvironmentVariable `json:"environmentVariables,omitempty"`

	// Files: The input filesystem to be set up prior to the task beginning.
	// The
	// contents should be a repeated set of FileMetadata messages though
	// other
	// formats are allowed if better for the implementation (eg, a
	// LUCI-style
	// .isolated file).
	//
	// This field is repeated since implementations might want to cache
	// the
	// metadata, in which case it may be useful to break up portions of
	// the
	// filesystem that change frequently (eg, specific input files) from
	// those
	// that don't (eg, standard header files).
	Files []*GoogleDevtoolsRemoteworkersV1test2Digest `json:"files,omitempty"`

	// InlineBlobs: Inline contents for blobs expected to be needed by the
	// bot to execute the
	// task. For example, contents of entries in `files` or blobs that
	// are
	// indirectly referenced by an entry there.
	//
	// The bot should check against this list before downloading required
	// task
	// inputs to reduce the number of communications between itself and
	// the
	// remote CAS server.
	InlineBlobs []*GoogleDevtoolsRemoteworkersV1test2Blob `json:"inlineBlobs,omitempty"`

	// WorkingDirectory: Directory from which a command is executed. It is a
	// relative directory
	// with respect to the bot's working directory (i.e., "./"). If it
	// is
	// non-empty, then it must exist under "./". Otherwise, "./" will be
	// used.
	WorkingDirectory string `json:"workingDirectory,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2CommandTaskInputsEnvironmentVariable
// : An environment variable required by this task.
type GoogleDevtoolsRemoteworkersV1test2CommandTaskInputsEnvironmentVariable struct {
	// Name: The envvar name.
	Name string `json:"name,omitempty"`

	// Value: The envvar value.
	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 *GoogleDevtoolsRemoteworkersV1test2CommandTaskInputsEnvironmentVariable) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteworkersV1test2CommandTaskInputsEnvironmentVariable
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteworkersV1test2CommandTaskOutputs: Describes the
// expected outputs of the command.
type GoogleDevtoolsRemoteworkersV1test2CommandTaskOutputs struct {
	// Directories: A list of expected directories, relative to the
	// execution root. All paths
	// MUST be delimited by forward slashes.
	Directories []string `json:"directories,omitempty"`

	// Files: A list of expected files, relative to the execution root. All
	// paths
	// MUST be delimited by forward slashes.
	Files []string `json:"files,omitempty"`

	// StderrDestination: The destination to which any stderr should be
	// sent. The method by which
	// the bot should send the stream contents to that destination is
	// not
	// defined in this API. As examples, the destination could be a
	// file
	// referenced in the `files` field in this message, or it could be a
	// URI
	// that must be written via the ByteStream API.
	StderrDestination string `json:"stderrDestination,omitempty"`

	// StdoutDestination: The destination to which any stdout should be
	// sent. The method by which
	// the bot should send the stream contents to that destination is
	// not
	// defined in this API. As examples, the destination could be a
	// file
	// referenced in the `files` field in this message, or it could be a
	// URI
	// that must be written via the ByteStream API.
	StdoutDestination string `json:"stdoutDestination,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2CommandTaskTimeouts: Describes the
// timeouts associated with this task.
type GoogleDevtoolsRemoteworkersV1test2CommandTaskTimeouts struct {
	// Execution: This specifies the maximum time that the task can run,
	// excluding the
	// time required to download inputs or upload outputs. That is, the
	// worker
	// will terminate the task if it runs longer than this.
	Execution string `json:"execution,omitempty"`

	// Idle: This specifies the maximum amount of time the task can be idle
	// - that is,
	// go without generating some output in either stdout or stderr. If
	// the
	// process is silent for more than the specified time, the worker
	// will
	// terminate the task.
	Idle string `json:"idle,omitempty"`

	// Shutdown: If the execution or IO timeouts are exceeded, the worker
	// will try to
	// gracefully terminate the task and return any existing logs.
	// However,
	// tasks may be hard-frozen in which case this process will fail.
	// This
	// timeout specifies how long to wait for a terminated task to shut
	// down
	// gracefully (e.g. via SIGTERM) before we bring down the hammer
	// (e.g.
	// SIGKILL on *nix, CTRL_BREAK_EVENT on Windows).
	Shutdown string `json:"shutdown,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2Digest: The CommandTask and
// CommandResult messages assume the existence of a service
// that can serve blobs of content, identified by a hash and size known
// as a
// "digest." The method by which these blobs may be retrieved is not
// specified
// here, but a model implementation is in the Remote Execution
// API's
// "ContentAddressibleStorage" interface.
//
// In the context of the RWAPI, a Digest will virtually always refer to
// the
// contents of a file or a directory. The latter is represented by
// the
// byte-encoded Directory message.
type GoogleDevtoolsRemoteworkersV1test2Digest struct {
	// Hash: A string-encoded hash (eg "1a2b3c", not the byte array [0x1a,
	// 0x2b, 0x3c])
	// using an implementation-defined hash algorithm (eg SHA-256).
	Hash string `json:"hash,omitempty"`

	// SizeBytes: The size of the contents. While this is not strictly
	// required as part of an
	// identifier (after all, any given hash will have exactly one
	// canonical
	// size), it's useful in almost all cases when one might want to send
	// or
	// retrieve blobs of content and is included here for this reason.
	SizeBytes int64 `json:"sizeBytes,omitempty,string"`

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

// GoogleDevtoolsRemoteworkersV1test2Directory: The contents of a
// directory. Similar to the equivalent message in the Remote
// Execution API.
type GoogleDevtoolsRemoteworkersV1test2Directory struct {
	// Directories: Any subdirectories
	Directories []*GoogleDevtoolsRemoteworkersV1test2DirectoryMetadata `json:"directories,omitempty"`

	// Files: The files in this directory
	Files []*GoogleDevtoolsRemoteworkersV1test2FileMetadata `json:"files,omitempty"`

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

// GoogleDevtoolsRemoteworkersV1test2DirectoryMetadata: The metadata for
// a directory. Similar to the equivalent message in the
// Remote
// Execution API.
type GoogleDevtoolsRemoteworkersV1test2DirectoryMetadata struct {
	// Digest: A pointer to the contents of the directory, in the form of a
	// marshalled
	// Directory message.
	Digest *GoogleDevtoolsRemoteworkersV1test2Digest `json:"digest,omitempty"`

	// Path: The path of the directory, as in FileMetadata.path.
	Path string `json:"path,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 *GoogleDevtoolsRemoteworkersV1test2DirectoryMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteworkersV1test2DirectoryMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteworkersV1test2FileMetadata: The metadata for a
// file. Similar to the equivalent message in the Remote
// Execution API.
type GoogleDevtoolsRemoteworkersV1test2FileMetadata struct {
	// Contents: If the file is small enough, its contents may also or
	// alternatively be
	// listed here.
	Contents string `json:"contents,omitempty"`

	// Digest: A pointer to the contents of the file. The method by which a
	// client
	// retrieves the contents from a CAS system is not defined here.
	Digest *GoogleDevtoolsRemoteworkersV1test2Digest `json:"digest,omitempty"`

	// IsExecutable: Properties of the file
	IsExecutable bool `json:"isExecutable,omitempty"`

	// Path: The path of this file. If this message is part of
	// the
	// CommandOutputs.outputs fields, the path is relative to the execution
	// root
	// and must correspond to an entry in CommandTask.outputs.files. If
	// this
	// message is part of a Directory message, then the path is relative to
	// the
	// root of that directory. All paths MUST be delimited by forward
	// slashes.
	Path string `json:"path,omitempty"`

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

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

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

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

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

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

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

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

// GoogleLongrunningOperation: This resource represents a long-running
// operation that is the result of a
// network API call.
type GoogleLongrunningOperation 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 *GoogleRpcStatus `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 *GoogleLongrunningOperation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleLongrunningOperation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleProtobufEmpty: 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 GoogleProtobufEmpty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// GoogleRpcStatus: 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 GoogleRpcStatus 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 *GoogleRpcStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleRpcStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "remotebuildexecution.media.download":

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

// Download: Downloads media. Download is supported
// on the URI `/v1/media/{+name}?alt=media`.
func (r *MediaService) Download(resourceName string) *MediaDownloadCall {
	c := &MediaDownloadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	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 *MediaDownloadCall) Fields(s ...googleapi.Field) *MediaDownloadCall {
	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 *MediaDownloadCall) IfNoneMatch(entityTag string) *MediaDownloadCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do and Download
// methods. Any pending HTTP request will be aborted if the provided
// context is canceled.
func (c *MediaDownloadCall) Context(ctx context.Context) *MediaDownloadCall {
	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 *MediaDownloadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MediaDownloadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191211")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/media/{+resourceName}")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Download fetches the API endpoint's "media" value, instead of the normal
// API response value. If the returned error is nil, the Response is guaranteed to
// have a 2xx status code. Callers must close the Response.Body as usual.
func (c *MediaDownloadCall) Download(opts ...googleapi.CallOption) (*http.Response, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("media")
	if err != nil {
		return nil, err
	}
	if err := googleapi.CheckMediaResponse(res); err != nil {
		res.Body.Close()
		return nil, err
	}
	return res, nil
}

// Do executes the "remotebuildexecution.media.download" call.
// Exactly one of *GoogleBytestreamMedia or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleBytestreamMedia.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 *MediaDownloadCall) Do(opts ...googleapi.CallOption) (*GoogleBytestreamMedia, 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 := &GoogleBytestreamMedia{
		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": "Downloads media. Download is supported\non the URI `/v1/media/{+name}?alt=media`.",
	//   "flatPath": "v1/media/{mediaId}",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.media.download",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Name of the media that is being downloaded.  See\nReadRequest.resource_name.",
	//       "location": "path",
	//       "pattern": "^.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/media/{+resourceName}",
	//   "response": {
	//     "$ref": "GoogleBytestreamMedia"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ],
	//   "supportsMediaDownload": true
	// }

}

// method id "remotebuildexecution.media.upload":

type MediaUploadCall struct {
	s                     *Service
	resourceName          string
	googlebytestreammedia *GoogleBytestreamMedia
	urlParams_            gensupport.URLParams
	mediaInfo_            *gensupport.MediaInfo
	ctx_                  context.Context
	header_               http.Header
}

// Upload: Uploads media. Upload is supported on
// the URI `/upload/v1/media/{+name}`.
func (r *MediaService) Upload(resourceName string, googlebytestreammedia *GoogleBytestreamMedia) *MediaUploadCall {
	c := &MediaUploadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	c.googlebytestreammedia = googlebytestreammedia
	return c
}

// Media specifies the media to upload in one or more chunks. The chunk
// size may be controlled by supplying a MediaOption generated by
// googleapi.ChunkSize. The chunk size defaults to
// googleapi.DefaultUploadChunkSize.The Content-Type header used in the
// upload request will be determined by sniffing the contents of r,
// unless a MediaOption generated by googleapi.ContentType is
// supplied.
// At most one of Media and ResumableMedia may be set.
func (c *MediaUploadCall) Media(r io.Reader, options ...googleapi.MediaOption) *MediaUploadCall {
	c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options)
	return c
}

// ResumableMedia specifies the media to upload in chunks and can be
// canceled with ctx.
//
// Deprecated: use Media instead.
//
// At most one of Media and ResumableMedia may be set. mediaType
// identifies the MIME media type of the upload, such as "image/png". If
// mediaType is "", it will be auto-detected. The provided ctx will
// supersede any context previously provided to the Context method.
func (c *MediaUploadCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *MediaUploadCall {
	c.ctx_ = ctx
	c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType)
	return c
}

// ProgressUpdater provides a callback function that will be called
// after every chunk. It should be a low-latency function in order to
// not slow down the upload operation. This should only be called when
// using ResumableMedia (as opposed to Media).
func (c *MediaUploadCall) ProgressUpdater(pu googleapi.ProgressUpdater) *MediaUploadCall {
	c.mediaInfo_.SetProgressUpdater(pu)
	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 *MediaUploadCall) Fields(s ...googleapi.Field) *MediaUploadCall {
	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.
// This context will supersede any context previously provided to the
// ResumableMedia method.
func (c *MediaUploadCall) Context(ctx context.Context) *MediaUploadCall {
	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 *MediaUploadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MediaUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191211")
	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.googlebytestreammedia)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/media/{+resourceName}")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/v1/media/{+resourceName}")
		c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())
	}
	if body == nil {
		body = new(bytes.Buffer)
		reqHeaders.Set("Content-Type", "application/json")
	}
	body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)
	defer cleanup()
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	req.GetBody = getBody
	googleapi.Expand(req.URL, map[string]string{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.media.upload" call.
// Exactly one of *GoogleBytestreamMedia or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleBytestreamMedia.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 *MediaUploadCall) Do(opts ...googleapi.CallOption) (*GoogleBytestreamMedia, 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
	}
	rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))
	if rx != nil {
		rx.Client = c.s.client
		rx.UserAgent = c.s.userAgent()
		ctx := c.ctx_
		if ctx == nil {
			ctx = context.TODO()
		}
		res, err = rx.Upload(ctx)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		if err := googleapi.CheckResponse(res); err != nil {
			return nil, err
		}
	}
	ret := &GoogleBytestreamMedia{
		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": "Uploads media. Upload is supported on\nthe URI `/upload/v1/media/{+name}`.",
	//   "flatPath": "v1/media/{mediaId}",
	//   "httpMethod": "POST",
	//   "id": "remotebuildexecution.media.upload",
	//   "mediaUpload": {
	//     "accept": [
	//       "*/*"
	//     ],
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/v1/media/{+resourceName}"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Name of the media that is being downloaded.  See\nReadRequest.resource_name.",
	//       "location": "path",
	//       "pattern": "^.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/media/{+resourceName}",
	//   "request": {
	//     "$ref": "GoogleBytestreamMedia"
	//   },
	//   "response": {
	//     "$ref": "GoogleBytestreamMedia"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "remotebuildexecution.operations.cancel":

type OperationsCancelCall struct {
	s                                       *Service
	name                                    string
	googlelongrunningcanceloperationrequest *GoogleLongrunningCancelOperationRequest
	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 *OperationsService) Cancel(name string, googlelongrunningcanceloperationrequest *GoogleLongrunningCancelOperationRequest) *OperationsCancelCall {
	c := &OperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlelongrunningcanceloperationrequest = googlelongrunningcanceloperationrequest
	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 *OperationsCancelCall) Fields(s ...googleapi.Field) *OperationsCancelCall {
	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 *OperationsCancelCall) Context(ctx context.Context) *OperationsCancelCall {
	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 *OperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191211")
	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.googlelongrunningcanceloperationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.operations.cancel" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OperationsCancelCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "v1/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "remotebuildexecution.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^operations/.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:cancel",
	//   "request": {
	//     "$ref": "GoogleLongrunningCancelOperationRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.operations.delete":

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

// Delete: Deletes a long-running operation. This method indicates that
// the client is
// no longer interested in the operation result. It does not cancel
// the
// operation. If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.
func (r *OperationsService) Delete(name string) *OperationsDeleteCall {
	c := &OperationsDeleteCall{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 *OperationsDeleteCall) Fields(s ...googleapi.Field) *OperationsDeleteCall {
	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 *OperationsDeleteCall) Context(ctx context.Context) *OperationsDeleteCall {
	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 *OperationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191211")
	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, "v1/{+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 "remotebuildexecution.operations.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *OperationsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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 long-running operation. This method indicates that the client is\nno longer interested in the operation result. It does not cancel the\noperation. If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.",
	//   "flatPath": "v1/operations/{operationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "remotebuildexecution.operations.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be deleted.",
	//       "location": "path",
	//       "pattern": "^operations/.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.operations.list":

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

// List: Lists operations that match the specified filter in the
// request. If the
// server doesn't support this method, it returns
// `UNIMPLEMENTED`.
//
// NOTE: the `name` binding allows API services to override the
// binding
// to use different resource name schemes, such as `users/*/operations`.
// To
// override the binding, API services can add a binding such
// as
// "/v1/{name=users/*}/operations" to their service configuration.
// For backwards compatibility, the default name includes the
// operations
// collection id, however overriding users must ensure the name
// binding
// is the parent resource, without the operations collection id.
func (r *OperationsService) List(name string) *OperationsListCall {
	c := &OperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list
// filter.
func (c *OperationsListCall) Filter(filter string) *OperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list
// page size.
func (c *OperationsListCall) PageSize(pageSize int64) *OperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OperationsListCall) Fields(s ...googleapi.Field) *OperationsListCall {
	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 *OperationsListCall) IfNoneMatch(entityTag string) *OperationsListCall {
	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 *OperationsListCall) Context(ctx context.Context) *OperationsListCall {
	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 *OperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "remotebuildexecution.operations.list" call.
// Exactly one of *GoogleLongrunningListOperationsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleLongrunningListOperationsResponse.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 *OperationsListCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningListOperationsResponse, 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 := &GoogleLongrunningListOperationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists operations that match the specified filter in the request. If the\nserver doesn't support this method, it returns `UNIMPLEMENTED`.\n\nNOTE: the `name` binding allows API services to override the binding\nto use different resource name schemes, such as `users/*/operations`. To\noverride the binding, API services can add a binding such as\n`\"/v1/{name=users/*}/operations\"` to their service configuration.\nFor backwards compatibility, the default name includes the operations\ncollection id, however overriding users must ensure the name binding\nis the parent resource, without the operations collection id.",
	//   "flatPath": "v1/operations",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.operations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "path",
	//       "pattern": "^operations$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The standard list page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

// method id "remotebuildexecution.projects.operations.get":

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

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

// Do executes the "remotebuildexecution.projects.operations.get" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsOperationsGetCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "v1/projects/{projectsId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.projects.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
