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

// Code generated file. DO NOT EDIT.

// Package 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"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

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

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

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

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

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

	// OutputNodeProperties: List of required supported NodeProperty
	// keys. In order to ensure that equivalent `Action`s always hash to the
	// same
	// value, the supported node properties MUST be lexicographically sorted
	// by name.
	// Sorting of strings is done by code point, equivalently, by the UTF-8
	// bytes.
	//
	// The interpretation of these properties is server-dependent. If a
	// property is
	// not recognized by the server, the server will return an
	// `INVALID_ARGUMENT`
	// error.
	OutputNodeProperties []string `json:"outputNodeProperties,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` or `output_paths` 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 as listed in `output_files` of
	// the Command was found in `output_directories`, 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.
	//
	// DEPRECATED as of v2.1. Servers that wish to be compatible with v2.0
	// API
	// should still populate this field in addition to `output_symlinks`.
	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` or
	// `output_paths`
	// 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 as listed in
	// `output_files` of
	// the Command 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.
	//
	// DEPRECATED as of v2.1. Servers that wish to be compatible with v2.0
	// API
	// should still populate this field in addition to `output_symlinks`.
	OutputFileSymlinks []*BuildBazelRemoteExecutionV2OutputSymlink `json:"outputFileSymlinks,omitempty"`

	// OutputFiles: The output files of the action. For each output file
	// requested in the
	// `output_files` or `output_paths` 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 (`output_symlinks` field after
	// v2.1).
	//
	// If an output listed in `output_files` 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"`

	// OutputSymlinks: New in v2.1: this field will only be populated if the
	// command
	// `output_paths` field was used, and not the pre v2.1 `output_files`
	// or
	// `output_directories` fields.
	// The output paths of the action that are symbolic links to other
	// paths. Those
	// may be links to other outputs, or inputs, or even absolute
	// paths
	// outside of the working directory, if the server
	// supports
	// SymlinkAbsolutePathStrategy.ALLOWED.
	// A single entry for each output requested in `output_paths`
	// field of the Action, if the corresponding path existed after
	// the action completed and was a symbolic link.
	//
	// If the action does not produce a 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.
	OutputSymlinks []*BuildBazelRemoteExecutionV2OutputSymlink `json:"outputSymlinks,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.
	//
	// DEPRECATED since 2.1: Use `output_paths` instead.
	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.
	//
	// DEPRECATED since v2.1: Use `output_paths` instead.
	OutputFiles []string `json:"outputFiles,omitempty"`

	// OutputPaths: A list of the output paths that the client expects to
	// retrieve from the
	// action. Only the listed paths will be returned to the client as
	// output.
	// The type of the output (file or directory) is not specified, and will
	// be
	// determined by the server after action execution. If the resulting
	// path is
	// a file, it will be returned in an
	// OutputFile) typed field.
	// If the path is a directory, the entire directory structure will be
	// returned
	// as a Tree message digest, see
	// OutputDirectory)
	// 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 deduplicated and sorted lexicographically by code point
	// (or,
	// equivalently, by UTF-8 bytes).
	//
	// Directories leading up to the output paths are created by the worker
	// prior
	// to execution, even if they are not explicitly part of the input
	// root.
	//
	// New in v2.1: this field supersedes the DEPRECATED `output_files`
	// and
	// `output_directories` fields. If `output_paths` is used,
	// `output_files` and
	// `output_directories` will be ignored!
	OutputPaths []string `json:"outputPaths,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.
//
// 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.
// * The NodeProperties of files,
//   directories, and symlinks must be sorted in lexicographical order
// by
//   property name.
//
// 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
//       },
//       node_properties: [
//         {
//           "name": "MTime",
//           "value": "2017-01-15T01:30:15.01Z"
//         }
//       ]
//     }
//   ],
//   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"`

	// NodeProperties: The node properties of the Directory.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,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"`

	// NodeProperties: The node properties of the FileNode.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,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)
}

// BuildBazelRemoteExecutionV2NodeProperty: A single property for
// FileNodes,
// DirectoryNodes, and
// SymlinkNodes. The server is
// responsible for specifying the property `name`s that it accepts.
// If
// permitted by the server, the same `name` may occur multiple times.
type BuildBazelRemoteExecutionV2NodeProperty 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 *BuildBazelRemoteExecutionV2NodeProperty) MarshalJSON() ([]byte, error) {
	type NoMethod BuildBazelRemoteExecutionV2NodeProperty
	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"`

	// NodeProperties: The supported node properties of the OutputFile, if
	// requested by the Action.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,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 {
	// NodeProperties: The supported node properties of the OutputSymlink,
	// if requested by the
	// Action.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,omitempty"`

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

	// NodeProperties: The node properties of the SymlinkNode.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,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 preparation 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.
	//   "FAILED_PRECONDITION" - The command failed because the system is
	// not in a state required for the
	// command, e.g. the command inputs cannot be found on the server.
	//   "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.
	//   "UPLOAD_OUTPUTS_BYTES_LIMIT_EXCEEDED" - The bot tried to upload
	// files having a total size that is too large.
	//   "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.
	//   "NO_CUDA_CAPABLE_DEVICE" - The command failed with "no cuda-capable
	// device is detected" error.
	//   "REMOTE_CAS_DOWNLOAD_ERROR" - The bot encountered errors from
	// remote CAS when downloading blobs.
	//   "REMOTE_CAS_UPLOAD_ERROR" - The bot encountered errors from remote
	// CAS when uploading blobs.
	//   "LOCAL_CASPROXY_NOT_RUNNING" - The local casproxy is not running.
	//   "DOCKER_CREATE_CONTAINER_ERROR" - The bot couldn't start the
	// container.
	//   "DOCKER_INVALID_ULIMIT" - The docker ulimit is not valid.
	//   "DOCKER_UNKNOWN_RUNTIME" - The docker runtime is unknown.
	//   "DOCKER_UNKNOWN_CAPABILITY" - The docker capability is unknown.
	//   "DOCKER_UNKNOWN_ERROR" - The command failed with unknown docker
	// errors.
	//   "DOCKER_CREATE_COMPUTE_SYSTEM_ERROR" - Docker failed to run
	// containers with CreateComputeSystem error.
	//   "DOCKER_PREPARELAYER_ERROR" - Docker failed to run containers with
	// hcsshim::PrepareLayer error.
	//   "DOCKER_INCOMPATIBLE_OS_ERROR" - Docker incompatible operating
	// system error.
	//   "DOCKER_CREATE_RUNTIME_FILE_NOT_FOUND" - Docker failed to create
	// OCI runtime because of file not found.
	//   "DOCKER_CREATE_RUNTIME_PERMISSION_DENIED" - Docker failed to create
	// OCI runtime because of permission denied.
	//   "DOCKER_CREATE_PROCESS_FILE_NOT_FOUND" - Docker failed to create
	// process because of file not found.
	//   "DOCKER_CREATE_COMPUTE_SYSTEM_INCORRECT_PARAMETER_ERROR" - Docker
	// failed to run containers with CreateComputeSystem error that
	// involves an incorrect parameter (more specific version
	// of
	// DOCKER_CREATE_COMPUTE_SYSTEM_ERROR that is user-caused).
	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)
}

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaAutoscale: Autoscale
// defines the autoscaling policy of a worker pool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaAutoscale struct {
	// MaxSize: The maximal number of workers. Must be equal to or greater
	// than min_size.
	MaxSize int64 `json:"maxSize,omitempty,string"`

	// MinSize: The minimal number of workers. Must be greater than 0.
	MinSize int64 `json:"minSize,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "MaxSize") 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. "MaxSize") 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 *GoogleDevtoolsRemotebuildexecutionAdminV1alphaAutoscale) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaAutoscale
	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 {
	// Instance: Specifies the instance to update.
	Instance *GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance `json:"instance,omitempty"`

	// LoggingEnabled: Deprecated, use instance.logging_enabled
	// instead.
	// Whether to enable Stackdriver logging for this instance.
	LoggingEnabled bool `json:"loggingEnabled,omitempty"`

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

	// UpdateMask: The update mask applies to instance. For the `FieldMask`
	// definition,
	// see
	// https://developers.google.com/protocol-buffers/docs/reference/goog
	// le.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"`

	// 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 *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` and `pd-ssd` are 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"`

	// MaxConcurrentActions: The maximum number of actions a worker can
	// execute concurrently.
	MaxConcurrentActions int64 `json:"maxConcurrentActions,omitempty,string"`

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

	// VmImage: The name of the image used by each VM.
	VmImage string `json:"vmImage,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 {
	// Autoscale: The autoscale policy to apply on a pool.
	Autoscale *GoogleDevtoolsRemotebuildexecutionAdminV1alphaAutoscale `json:"autoscale,omitempty"`

	// Channel: Channel specifies the release channel of the pool.
	Channel string `json:"channel,omitempty"`

	// 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 15000.
	WorkerCount int64 `json:"workerCount,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Autoscale") 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. "Autoscale") 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/"+gensupport.GoVersion()+" gdcl/20200725")
	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/"+gensupport.GoVersion()+" gdcl/20200725")
	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/"+gensupport.GoVersion()+" gdcl/20200725")
	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/"+gensupport.GoVersion()+" gdcl/20200725")
	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/"+gensupport.GoVersion()+" gdcl/20200725")
	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/"+gensupport.GoVersion()+" gdcl/20200725")
	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"
	//   ]
	// }

}
