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

// Code generated file. DO NOT EDIT.

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

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

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

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

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

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

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

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

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

	Media *MediaService

	Operations *OperationsService

	Projects *ProjectsService
}

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

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

type MediaService struct {
	s *Service
}

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

type OperationsService struct {
	s *Service
}

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

type ProjectsService struct {
	s *Service

	Operations *ProjectsOperationsService
}

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

type ProjectsOperationsService struct {
	s *Service
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Name: The name of the directory.
	Name string `json:"name,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Name: The name of the file.
	Name string `json:"name,omitempty"`

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

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

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

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

	// HumanReadable: This is a hint as to the purpose of the log, and is
	// set to true if the log
	// is human-readable text that can be usefully displayed to a user, and
	// false
	// otherwise. For instance, if a command-line client wishes to print
	// the
	// server logs to the terminal for a failed action, this allows it to
	// avoid
	// displaying a binary file.
	HumanReadable bool `json:"humanReadable,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Message: The error message.
	Message string `json:"message,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteInstanceRequest:
// The request used for `DeleteInstance`.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteInstanceRequest struct {
	// Name: Name of the instance to delete.
	// Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
	Name string `json:"name,omitempty"`

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteWorkerPoolRequest:
//  The request used for DeleteWorkerPool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteWorkerPoolRequest struct {
	// Name: Name of the worker pool to
	// delete.
	// Format:
	// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/workerp
	// ools/[POOL_ID]`.
	Name string `json:"name,omitempty"`

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetInstanceRequest: The
// request used for `GetInstance`.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetInstanceRequest struct {
	// Name: Name of the instance to retrieve.
	// Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
	Name string `json:"name,omitempty"`

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetWorkerPoolRequest:
// The request used for GetWorkerPool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaGetWorkerPoolRequest struct {
	// Name: Name of the worker pool to
	// retrieve.
	// Format:
	// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/worke
	// rpools/[POOL_ID]`.
	Name string `json:"name,omitempty"`

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

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

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

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

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

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

	// State: Output only. State of the instance.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Not a valid state, but the default value of
	// the enum.
	//   "CREATING" - The instance is in state `CREATING` once
	// `CreateInstance` is called and
	// before the instance is ready for use.
	//   "RUNNING" - The instance is in state `RUNNING` when it is ready for
	// use.
	//   "INACTIVE" - An `INACTIVE` instance indicates that there is a
	// problem that needs to be
	// fixed. Such instances cannot be used for execution and instances
	// that
	// remain in this state for a significant period of time will be
	// removed
	// permanently.
	State string `json:"state,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Path: The path of the directory, as in FileMetadata.path.
	Path string `json:"path,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Metadata: Service-specific metadata associated with the operation.
	// It typically
	// contains progress information and common metadata such as create
	// time.
	// Some services might not provide such metadata.  Any method that
	// returns a
	// long-running operation should document the metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that
	// originally returns it. If you use the default HTTP mapping,
	// the
	// `name` should be a resource name ending with
	// `operations/{unique_id}`.
	Name string `json:"name,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Download: Downloads media. Download is supported
// on the URI `/v1/media/{+name}?alt=media`.
func (r *MediaService) Download(resourceName string) *MediaDownloadCall {
	c := &MediaDownloadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	return c
}

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

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

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

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

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

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

// Do executes the "remotebuildexecution.media.download" call.
// Exactly one of *GoogleBytestreamMedia or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleBytestreamMedia.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MediaDownloadCall) Do(opts ...googleapi.CallOption) (*GoogleBytestreamMedia, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleBytestreamMedia{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Downloads media. Download is supported\non the URI `/v1/media/{+name}?alt=media`.",
	//   "flatPath": "v1/media/{mediaId}",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.media.download",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Name of the media that is being downloaded.  See\nReadRequest.resource_name.",
	//       "location": "path",
	//       "pattern": "^.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/media/{+resourceName}",
	//   "response": {
	//     "$ref": "GoogleBytestreamMedia"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ],
	//   "supportsMediaDownload": true
	// }

}

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

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

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

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

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

// ProgressUpdater provides a callback function that will be called
// after every chunk. It should be a low-latency function in order to
// not slow down the upload operation. This should only be called when
// using ResumableMedia (as opposed to Media).
func (c *MediaUploadCall) ProgressUpdater(pu googleapi.ProgressUpdater) *MediaUploadCall {
	c.mediaInfo_.SetProgressUpdater(pu)
	return c
}

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

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

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

func (c *MediaUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191031")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlebytestreammedia)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/media/{+resourceName}")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/v1/media/{+resourceName}")
		c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())
	}
	if body == nil {
		body = new(bytes.Buffer)
		reqHeaders.Set("Content-Type", "application/json")
	}
	body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)
	defer cleanup()
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	req.GetBody = getBody
	googleapi.Expand(req.URL, map[string]string{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.media.upload" call.
// Exactly one of *GoogleBytestreamMedia or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleBytestreamMedia.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MediaUploadCall) Do(opts ...googleapi.CallOption) (*GoogleBytestreamMedia, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))
	if rx != nil {
		rx.Client = c.s.client
		rx.UserAgent = c.s.userAgent()
		ctx := c.ctx_
		if ctx == nil {
			ctx = context.TODO()
		}
		res, err = rx.Upload(ctx)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		if err := googleapi.CheckResponse(res); err != nil {
			return nil, err
		}
	}
	ret := &GoogleBytestreamMedia{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Uploads media. Upload is supported on\nthe URI `/upload/v1/media/{+name}`.",
	//   "flatPath": "v1/media/{mediaId}",
	//   "httpMethod": "POST",
	//   "id": "remotebuildexecution.media.upload",
	//   "mediaUpload": {
	//     "accept": [
	//       "*/*"
	//     ],
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/v1/media/{+resourceName}"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Name of the media that is being downloaded.  See\nReadRequest.resource_name.",
	//       "location": "path",
	//       "pattern": "^.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/media/{+resourceName}",
	//   "request": {
	//     "$ref": "GoogleBytestreamMedia"
	//   },
	//   "response": {
	//     "$ref": "GoogleBytestreamMedia"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

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

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

// Cancel: Starts asynchronous cancellation on a long-running operation.
//  The server
// makes a best effort to cancel the operation, but success is
// not
// guaranteed.  If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.  Clients can
// use
// Operations.GetOperation or
// other methods to check whether the cancellation succeeded or whether
// the
// operation completed despite cancellation. On successful
// cancellation,
// the operation is not deleted; instead, it becomes an operation
// with
// an Operation.error value with a google.rpc.Status.code of
// 1,
// corresponding to `Code.CANCELLED`.
func (r *OperationsService) Cancel(name string, googlelongrunningcanceloperationrequest *GoogleLongrunningCancelOperationRequest) *OperationsCancelCall {
	c := &OperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlelongrunningcanceloperationrequest = googlelongrunningcanceloperationrequest
	return c
}

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

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

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

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

// Do executes the "remotebuildexecution.operations.cancel" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OperationsCancelCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Starts asynchronous cancellation on a long-running operation.  The server\nmakes a best effort to cancel the operation, but success is not\nguaranteed.  If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.  Clients can use\nOperations.GetOperation or\nother methods to check whether the cancellation succeeded or whether the\noperation completed despite cancellation. On successful cancellation,\nthe operation is not deleted; instead, it becomes an operation with\nan Operation.error value with a google.rpc.Status.code of 1,\ncorresponding to `Code.CANCELLED`.",
	//   "flatPath": "v1/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "remotebuildexecution.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^operations/.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:cancel",
	//   "request": {
	//     "$ref": "GoogleLongrunningCancelOperationRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// Delete: Deletes a long-running operation. This method indicates that
// the client is
// no longer interested in the operation result. It does not cancel
// the
// operation. If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.
func (r *OperationsService) Delete(name string) *OperationsDeleteCall {
	c := &OperationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

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

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

// Do executes the "remotebuildexecution.operations.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OperationsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a long-running operation. This method indicates that the client is\nno longer interested in the operation result. It does not cancel the\noperation. If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.",
	//   "flatPath": "v1/operations/{operationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "remotebuildexecution.operations.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be deleted.",
	//       "location": "path",
	//       "pattern": "^operations/.+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

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

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

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

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

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

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

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

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

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

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

}

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

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

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

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

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

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

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

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

func (c *ProjectsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191031")
	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"
	//   ]
	// }

}
