// Copyright 2019 Google Inc. All rights reserved.
// 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.
//
// See https://cloud.google.com/remote-build-execution/docs/
//
// Usage example:
//
//   import "google.golang.org/api/remotebuildexecution/v1"
//   ...
//   remotebuildexecutionService, err := remotebuildexecution.New(oauthHttpClient)
package remotebuildexecution // import "google.golang.org/api/remotebuildexecution/v1"

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

	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
)

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

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)
	s.V1 = NewV1Service(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

	V1 *V1Service
}

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
}

func NewV1Service(s *Service) *V1Service {
	rs := &V1Service{s: s}
	return rs
}

type V1Service 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.
	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
	//       }
	//     ]
	//   }
	// }
	// ```
	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 file 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 the action does not produce the requested output, or produces
	// a
	// file where a directory is expected or vice versa, 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 the action does not produce the requested output, or produces
	// a
	// directory where a regular file is expected or vice versa, 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 in the output_file_symlinks field, if the file was a symbolic link
	// to
	// another file.
	//
	// If the action does not produce the requested output, or produces
	// a
	// directory where a regular file is expected or vice versa, 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.
	// See `stderr_raw` for when this will be set.
	StderrDigest *BuildBazelRemoteExecutionV2Digest `json:"stderrDigest,omitempty"`

	// StderrRaw: The standard error buffer of the action. The server will
	// determine, based
	// on the size of the buffer, whether to return it in raw form or to
	// return
	// a digest in `stderr_digest` that points to the buffer. If neither is
	// set,
	// then the buffer is empty. The client SHOULD NOT assume it will get
	// one of
	// the raw buffer or a digest on any given request and should be
	// prepared to
	// handle either.
	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.
	// See `stdout_raw` for when this will be set.
	StdoutDigest *BuildBazelRemoteExecutionV2Digest `json:"stdoutDigest,omitempty"`

	// StdoutRaw: The standard output buffer of the action. The server will
	// determine, based
	// on the size of the buffer, whether to return it in raw form or to
	// return
	// a digest in `stdout_digest` that points to the buffer. If neither is
	// set,
	// then the buffer is empty. The client SHOULD NOT assume it will get
	// one of
	// the raw buffer or a digest on any given request and should be
	// prepared to
	// handle either.
	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 `Command`s 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 contents of the indicated directories
	// (recursively
	// including the contents of their subdirectories) will be
	// returned, as well as files listed in `output_files`. Other files 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, be a parent of another
	// output
	// directory, be a parent of a listed output file, or have the same path
	// as
	// any of the listed output files.
	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 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, be
	// a child of a listed output directory, or have the same path as any of
	// the
	// listed output directories.
	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.
	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).
//   - 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"`

	// Possible values:
	//   "UNKNOWN"
	//   "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"`

	// 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.
//
// `OutputFile` is binary-compatible with `FileNode`.
type BuildBazelRemoteExecutionV2OutputFile 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"`

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

	// Download: The time spent downloading the input files and constructing
	// the working
	// directory.
	Download string `json:"download,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"`

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

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

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

	// 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 {
	// 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. "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 *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/reference/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 {
	// 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/#introduction).
	// C
	// urrently only `pd-standard` is supported.
	DiskType string `json:"diskType,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.
	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"`

	// Reserved: Output only. `reserved=true` means the worker is reserved
	// and won't be
	// preempted.
	Reserved bool `json:"reserved,omitempty"`

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

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

func (s *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)
}

// GoogleDevtoolsRemoteexecutionV1testActionResult: An ActionResult
// represents the result of an
// Action being run.
type GoogleDevtoolsRemoteexecutionV1testActionResult struct {
	// 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
	//       }
	//     ]
	//   }
	// }
	// ```
	OutputDirectories []*GoogleDevtoolsRemoteexecutionV1testOutputDirectory `json:"outputDirectories,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 in the output
	// list.
	//
	// If the action does not produce the requested output, or produces
	// a
	// directory where a regular file is expected or vice versa, 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 []*GoogleDevtoolsRemoteexecutionV1testOutputFile `json:"outputFiles,omitempty"`

	// StderrDigest: The digest for a blob containing the standard error of
	// the action, which
	// can be retrieved from the
	// ContentAddressableStorage.
	// See `stderr_raw` for when this will be set.
	StderrDigest *GoogleDevtoolsRemoteexecutionV1testDigest `json:"stderrDigest,omitempty"`

	// StderrRaw: The standard error buffer of the action. The server will
	// determine, based
	// on the size of the buffer, whether to return it in raw form or to
	// return
	// a digest in `stderr_digest` that points to the buffer. If neither is
	// set,
	// then the buffer is empty. The client SHOULD NOT assume it will get
	// one of
	// the raw buffer or a digest on any given request and should be
	// prepared to
	// handle either.
	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.
	// See `stdout_raw` for when this will be set.
	StdoutDigest *GoogleDevtoolsRemoteexecutionV1testDigest `json:"stdoutDigest,omitempty"`

	// StdoutRaw: The standard output buffer of the action. The server will
	// determine, based
	// on the size of the buffer, whether to return it in raw form or to
	// return
	// a digest in `stdout_digest` that points to the buffer. If neither is
	// set,
	// then the buffer is empty. The client SHOULD NOT assume it will get
	// one of
	// the raw buffer or a digest on any given request and should be
	// prepared to
	// handle either.
	StdoutRaw string `json:"stdoutRaw,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 *GoogleDevtoolsRemoteexecutionV1testActionResult) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testActionResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testCommand: A `Command` is the actual
// command executed by a worker running an
// Action.
//
// 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 GoogleDevtoolsRemoteexecutionV1testCommand 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.
	//
	// The working directory will always be the input root.
	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 `Command`s 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 []*GoogleDevtoolsRemoteexecutionV1testCommandEnvironmentVariable `json:"environmentVariables,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 *GoogleDevtoolsRemoteexecutionV1testCommand) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testCommand
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testCommandEnvironmentVariable: An
// `EnvironmentVariable` is one variable to set in the running
// program's
// environment.
type GoogleDevtoolsRemoteexecutionV1testCommandEnvironmentVariable 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 *GoogleDevtoolsRemoteexecutionV1testCommandEnvironmentVariable) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testCommandEnvironmentVariable
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// GoogleDevtoolsRemoteexecutionV1testDirectory: A `Directory`
// represents a directory node in a file tree, containing zero or
// more children FileNodes
// and DirectoryNodes.
// Each `Node` contains its name in the directory, the digest of its
// content
// (either a file blob or a `Directory` proto), 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).
//   - The files and directories 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 GoogleDevtoolsRemoteexecutionV1testDirectory struct {
	// Directories: The subdirectories in the directory.
	Directories []*GoogleDevtoolsRemoteexecutionV1testDirectoryNode `json:"directories,omitempty"`

	// Files: The files in the directory.
	Files []*GoogleDevtoolsRemoteexecutionV1testFileNode `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 *GoogleDevtoolsRemoteexecutionV1testDirectory) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testDirectory
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testDirectoryNode: A `DirectoryNode`
// represents a child of a
// Directory which is itself
// a `Directory` and its associated metadata.
type GoogleDevtoolsRemoteexecutionV1testDirectoryNode struct {
	// Digest: The digest of the
	// Directory object
	// represented. See Digest
	// for information about how to take the digest of a proto message.
	Digest *GoogleDevtoolsRemoteexecutionV1testDigest `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 *GoogleDevtoolsRemoteexecutionV1testDirectoryNode) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testDirectoryNode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

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

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

	// Result: The result of the action.
	Result *GoogleDevtoolsRemoteexecutionV1testActionResult `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]GoogleDevtoolsRemoteexecutionV1testLogFile `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 *GoogleDevtoolsRemoteexecutionV1testExecuteResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testExecuteResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testFileNode: A `FileNode` represents
// a single file and associated metadata.
type GoogleDevtoolsRemoteexecutionV1testFileNode struct {
	// Digest: The digest of the file's content.
	Digest *GoogleDevtoolsRemoteexecutionV1testDigest `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 *GoogleDevtoolsRemoteexecutionV1testFileNode) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testFileNode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testLogFile: A `LogFile` is a log
// stored in the CAS.
type GoogleDevtoolsRemoteexecutionV1testLogFile struct {
	// Digest: The digest of the log contents.
	Digest *GoogleDevtoolsRemoteexecutionV1testDigest `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 *GoogleDevtoolsRemoteexecutionV1testLogFile) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testLogFile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testOutputDirectory: An
// `OutputDirectory` is the output in an `ActionResult` corresponding to
// a
// directory's full contents rather than a single file.
type GoogleDevtoolsRemoteexecutionV1testOutputDirectory struct {
	// Digest: DEPRECATED: This field is deprecated and should no longer be
	// used.
	Digest *GoogleDevtoolsRemoteexecutionV1testDigest `json:"digest,omitempty"`

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

// GoogleDevtoolsRemoteexecutionV1testOutputFile: An `OutputFile` is
// similar to a
// FileNode, but it is
// tailored for output as part of an `ActionResult`. It allows a full
// file path
// rather than only a name, and allows the server to include content
// inline.
//
// `OutputFile` is binary-compatible with `FileNode`.
type GoogleDevtoolsRemoteexecutionV1testOutputFile struct {
	// Content: The raw content of the file.
	//
	// This field may be used by the server to provide the content of a
	// file
	// inline in an
	// ActionResult and
	// avoid requiring that the client make a separate call
	// to
	// [ContentAddressableStorage.GetBlob] to retrieve it.
	//
	// The client SHOULD NOT assume that it will get raw content with any
	// request,
	// and always be prepared to retrieve it via `digest`.
	Content string `json:"content,omitempty"`

	// Digest: The digest of the file's content.
	Digest *GoogleDevtoolsRemoteexecutionV1testDigest `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 input root, 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. "Content") 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. "Content") 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 *GoogleDevtoolsRemoteexecutionV1testOutputFile) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testOutputFile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testRequestMetadata: 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:
// google.devtools.remoteexecution.v1test.requestmetadata-bin
// contents: the base64 encoded binary RequestMetadata message.
type GoogleDevtoolsRemoteexecutionV1testRequestMetadata 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 *GoogleDevtoolsRemoteexecutionV1testToolDetails `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 *GoogleDevtoolsRemoteexecutionV1testRequestMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testRequestMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testToolDetails: Details for the tool
// used to call the API.
type GoogleDevtoolsRemoteexecutionV1testToolDetails 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 *GoogleDevtoolsRemoteexecutionV1testToolDetails) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testToolDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleDevtoolsRemoteexecutionV1testTree: A `Tree` contains all
// the
// Directory protos in a
// single directory Merkle tree, compressed into one message.
type GoogleDevtoolsRemoteexecutionV1testTree 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 []*GoogleDevtoolsRemoteexecutionV1testDirectory `json:"children,omitempty"`

	// Root: The root directory in the tree.
	Root *GoogleDevtoolsRemoteexecutionV1testDirectory `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 *GoogleDevtoolsRemoteexecutionV1testTree) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemoteexecutionV1testTree
	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"`

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

	// Statistics: Implementation-dependent statistics about the task. Both
	// servers and bots
	// may define messages which can be encoded here; bots are free to
	// provide
	// statistics 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.
	Statistics []googleapi.RawMessage `json:"statistics,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"`

	// 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 have the format of `operations/some/unique/name`.
	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). The error model is designed to
// be:
//
// - Simple to use and understand for most users
// - Flexible enough to meet unexpected needs
//
// # Overview
//
// The `Status` message contains three pieces of data: error code, error
// message,
// and error details. The error code should be an enum value
// of
// google.rpc.Code, but it may accept additional error codes if needed.
// The
// error message should be a developer-facing English message that
// helps
// developers *understand* and *resolve* the error. If a localized
// user-facing
// error message is needed, put the localized message in the error
// details or
// localize it in the client. The optional error details may contain
// arbitrary
// information about the error. There is a predefined set of error
// detail types
// in the package `google.rpc` that can be used for common error
// conditions.
//
// # Language mapping
//
// The `Status` message is the logical representation of the error
// model, but it
// is not necessarily the actual wire format. When the `Status` message
// is
// exposed in different client libraries and different wire protocols,
// it can be
// mapped differently. For example, it will likely be mapped to some
// exceptions
// in Java, but more likely mapped to some error codes in C.
//
// # Other uses
//
// The error model and the `Status` message can be used in a variety
// of
// environments, either with or without APIs, to provide a
// consistent developer experience across different
// environments.
//
// Example uses of this error model include:
//
// - Partial errors. If a service needs to return partial errors to the
// client,
//     it may embed the `Status` in the normal response to indicate the
// partial
//     errors.
//
// - Workflow errors. A typical workflow has multiple steps. Each step
// may
//     have a `Status` message for error reporting.
//
// - Batch operations. If a client uses batch request and batch
// response, the
//     `Status` message should be used directly inside batch response,
// one for
//     each error sub-response.
//
// - Asynchronous operations. If an API call embeds asynchronous
// operation
//     results in its response, the status of those operations should
// be
//     represented directly using the `Status` message.
//
// - Logging. If some API errors are stored in logs, the message
// `Status` could
//     be used directly after any stripping needed for security/privacy
// reasons.
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)
}

// GoogleWatcherV1Change: A Change indicates the most recent state of an
// element.
type GoogleWatcherV1Change struct {
	// Continued: If true, this Change is followed by more Changes that are
	// in the same group
	// as this Change.
	Continued bool `json:"continued,omitempty"`

	// Data: The actual change data. This field is present only when
	// `state() == EXISTS`
	// or `state() == ERROR`. Please see google.protobuf.Any about how to
	// use
	// the Any type.
	Data googleapi.RawMessage `json:"data,omitempty"`

	// Element: Name of the element, interpreted relative to the entity's
	// actual
	// name. "" refers to the entity itself. The element name is a
	// valid
	// UTF-8 string.
	Element string `json:"element,omitempty"`

	// ResumeMarker: If present, provides a compact representation of all
	// the messages that have
	// been received by the caller for the given entity, e.g., it could be
	// a
	// sequence number or a multi-part timestamp/version vector. This marker
	// can
	// be provided in the Request message, allowing the caller to resume the
	// stream
	// watching at a specific point without fetching the initial state.
	ResumeMarker string `json:"resumeMarker,omitempty"`

	// State: The state of the `element`.
	//
	// Possible values:
	//   "EXISTS" - The element exists and its full value is included in
	// data.
	//   "DOES_NOT_EXIST" - The element does not exist.
	//   "INITIAL_STATE_SKIPPED" - Element may or may not exist. Used only
	// for initial state delivery when
	// the client is not interested in fetching the initial state. See
	// the
	// "Initial State" section above.
	//   "ERROR" - The element may exist, but some error has occurred. More
	// information is
	// available in the data field - the value is a serialized Status
	// proto (from google.rpc.Status)
	State string `json:"state,omitempty"`

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

// GoogleWatcherV1ChangeBatch: A batch of Change messages.
type GoogleWatcherV1ChangeBatch struct {
	// Changes: A list of Change messages.
	Changes []*GoogleWatcherV1Change `json:"changes,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Changes") 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. "Changes") 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 *GoogleWatcherV1ChangeBatch) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleWatcherV1ChangeBatch
	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)
	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)
	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 = strings.Replace(urls, "https://www.googleapis.com/", "https://www.googleapis.com/upload/", 1)
		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
	gensupport.SetGetBody(req, 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)
	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)
	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)
	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)
	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"
	//   ]
	// }

}

// method id "remotebuildexecution.watch":

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

// Watch: Start a streaming RPC to get watch information from the
// server.
func (r *V1Service) Watch() *V1WatchCall {
	c := &V1WatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// ResumeMarker sets the optional parameter "resumeMarker": The
// `resume_marker` specifies how much of the existing underlying state
// is
// delivered to the client when the watch request is received by
// the
// system. The client can set this marker in one of the following ways
// to get
// different semantics:
//
// *   Parameter is not specified or has the value "".
//     Semantics: Fetch initial state.
//     The client wants the entity's initial state to be delivered. See
// the
//     description in "Initial State".
//
// *   Parameter is set to the string "now" (UTF-8 encoding).
//     Semantics: Fetch new changes only.
//     The client just wants to get the changes received by the system
// after
//     the watch point. The system may deliver changes from before the
// watch
//     point as well.
//
// *   Parameter is set to a value received in an earlier
//     `Change.resume_marker` field while watching the same entity.
//     Semantics: Resume from a specific point.
//     The client wants to receive the changes from a specific point;
// this
//     value must correspond to a value received in the
// `Change.resume_marker`
//     field. The system may deliver changes from before the
// `resume_marker`
//     as well. If the system cannot resume the stream from this point
// (e.g.,
//     if it is too far behind in the stream), it can raise the
//     `FAILED_PRECONDITION` error.
//
// An implementation MUST support an unspecified parameter and the
// empty string "" marker (initial state fetching) and the "now"
// marker.
// It need not support resuming from a specific point.
func (c *V1WatchCall) ResumeMarker(resumeMarker string) *V1WatchCall {
	c.urlParams_.Set("resumeMarker", resumeMarker)
	return c
}

// Target sets the optional parameter "target": The `target` value
// **must** be a valid URL path pointing to an entity
// to watch. Note that the service name **must** be
// removed from the target field (e.g., the target field must
// say
// "/foo/bar", not "myservice.googleapis.com/foo/bar"). A client is
// also allowed to pass system-specific parameters in the URL that
// are only obeyed by some implementations. Some parameters will
// be
// implementation-specific. However, some have predefined meaning
// and are listed here:
//
//  * recursive = true|false [default=false]
//    If set to true, indicates that the client wants to watch all
// elements
//    of entities in the subtree rooted at the entity's name in
// `target`. For
//    descendants that are not the immediate children of the target,
// the
//    `Change.element` will contain slashes.
//
//    Note that some namespaces and entities will not support recursive
//    watching. When watching such an entity, a client must not set
// recursive
//    to true. Otherwise, it will receive an `UNIMPLEMENTED`
// error.
//
// Normal URL encoding must be used inside `target`.  For example, if a
// query
// parameter name or value, or the non-query parameter portion of
// `target`
// contains a special character, it must be %-encoded.  We recommend
// that
// clients and servers use their runtime's URL library to produce and
// consume
// target values.
func (c *V1WatchCall) Target(target string) *V1WatchCall {
	c.urlParams_.Set("target", target)
	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 *V1WatchCall) Fields(s ...googleapi.Field) *V1WatchCall {
	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 *V1WatchCall) IfNoneMatch(entityTag string) *V1WatchCall {
	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 *V1WatchCall) Context(ctx context.Context) *V1WatchCall {
	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 *V1WatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1WatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	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:watch")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.watch" call.
// Exactly one of *GoogleWatcherV1ChangeBatch or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleWatcherV1ChangeBatch.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 *V1WatchCall) Do(opts ...googleapi.CallOption) (*GoogleWatcherV1ChangeBatch, 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 := &GoogleWatcherV1ChangeBatch{
		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": "Start a streaming RPC to get watch information from the server.",
	//   "flatPath": "v1:watch",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.watch",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "resumeMarker": {
	//       "description": "The `resume_marker` specifies how much of the existing underlying state is\ndelivered to the client when the watch request is received by the\nsystem. The client can set this marker in one of the following ways to get\ndifferent semantics:\n\n*   Parameter is not specified or has the value \"\".\n    Semantics: Fetch initial state.\n    The client wants the entity's initial state to be delivered. See the\n    description in \"Initial State\".\n\n*   Parameter is set to the string \"now\" (UTF-8 encoding).\n    Semantics: Fetch new changes only.\n    The client just wants to get the changes received by the system after\n    the watch point. The system may deliver changes from before the watch\n    point as well.\n\n*   Parameter is set to a value received in an earlier\n    `Change.resume_marker` field while watching the same entity.\n    Semantics: Resume from a specific point.\n    The client wants to receive the changes from a specific point; this\n    value must correspond to a value received in the `Change.resume_marker`\n    field. The system may deliver changes from before the `resume_marker`\n    as well. If the system cannot resume the stream from this point (e.g.,\n    if it is too far behind in the stream), it can raise the\n    `FAILED_PRECONDITION` error.\n\nAn implementation MUST support an unspecified parameter and the\nempty string \"\" marker (initial state fetching) and the \"now\" marker.\nIt need not support resuming from a specific point.",
	//       "format": "byte",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "target": {
	//       "description": "The `target` value **must** be a valid URL path pointing to an entity\nto watch. Note that the service name **must** be\nremoved from the target field (e.g., the target field must say\n\"/foo/bar\", not \"myservice.googleapis.com/foo/bar\"). A client is\nalso allowed to pass system-specific parameters in the URL that\nare only obeyed by some implementations. Some parameters will be\nimplementation-specific. However, some have predefined meaning\nand are listed here:\n\n * recursive = true|false [default=false]\n   If set to true, indicates that the client wants to watch all elements\n   of entities in the subtree rooted at the entity's name in `target`. For\n   descendants that are not the immediate children of the target, the\n   `Change.element` will contain slashes.\n\n   Note that some namespaces and entities will not support recursive\n   watching. When watching such an entity, a client must not set recursive\n   to true. Otherwise, it will receive an `UNIMPLEMENTED` error.\n\nNormal URL encoding must be used inside `target`.  For example, if a query\nparameter name or value, or the non-query parameter portion of `target`\ncontains a special character, it must be %-encoded.  We recommend that\nclients and servers use their runtime's URL library to produce and consume\ntarget values.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1:watch",
	//   "response": {
	//     "$ref": "GoogleWatcherV1ChangeBatch"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
