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

// Code generated file. DO NOT EDIT.

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

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

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

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

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

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

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

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

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

	Projects *ProjectsService
}

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

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

type ProjectsService struct {
	s *Service

	Instances *ProjectsInstancesService

	Operations *ProjectsOperationsService
}

func NewProjectsInstancesService(s *Service) *ProjectsInstancesService {
	rs := &ProjectsInstancesService{s: s}
	rs.Workerpools = NewProjectsInstancesWorkerpoolsService(s)
	return rs
}

type ProjectsInstancesService struct {
	s *Service

	Workerpools *ProjectsInstancesWorkerpoolsService
}

func NewProjectsInstancesWorkerpoolsService(s *Service) *ProjectsInstancesWorkerpoolsService {
	rs := &ProjectsInstancesWorkerpoolsService{s: s}
	return rs
}

type ProjectsInstancesWorkerpoolsService struct {
	s *Service
}

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

type ProjectsOperationsService struct {
	s *Service
}

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

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

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

	// OutputNodeProperties: List of required supported NodeProperty keys.
	// In order to ensure that equivalent `Action`s always hash to the same
	// value, the supported node properties MUST be lexicographically sorted
	// by name. Sorting of strings is done by code point, equivalently, by
	// the UTF-8 bytes. The interpretation of these properties is
	// server-dependent. If a property is not recognized by the server, the
	// server will return an `INVALID_ARGUMENT` error.
	OutputNodeProperties []string `json:"outputNodeProperties,omitempty"`

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

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

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

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

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

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

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

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

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

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

	// OutputSymlinks: New in v2.1: this field will only be populated if the
	// command `output_paths` field was used, and not the pre v2.1
	// `output_files` or `output_directories` fields. The output paths of
	// the action that are symbolic links to other paths. Those may be links
	// to other outputs, or inputs, or even absolute paths outside of the
	// working directory, if the server supports
	// SymlinkAbsolutePathStrategy.ALLOWED. A single entry for each output
	// requested in `output_paths` field of the Action, if the corresponding
	// path existed after the action completed and was a symbolic link. If
	// the action does not produce a requested output, then that output will
	// be omitted from the list. The server is free to arrange the output
	// list as desired; clients MUST NOT assume that the output list is
	// sorted.
	OutputSymlinks []*BuildBazelRemoteExecutionV2OutputSymlink `json:"outputSymlinks,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

	// OutputPaths: A list of the output paths that the client expects to
	// retrieve from the action. Only the listed paths will be returned to
	// the client as output. The type of the output (file or directory) is
	// not specified, and will be determined by the server after action
	// execution. If the resulting path is a file, it will be returned in an
	// OutputFile) typed field. If the path is a directory, the entire
	// directory structure will be returned as a Tree message digest, see
	// OutputDirectory) Other files or directories that may be created
	// during command execution are discarded. The paths are relative to the
	// working directory of the action execution. The paths are specified
	// using a single forward slash (`/`) as a path separator, even if the
	// execution platform natively uses a different separator. The path MUST
	// NOT include a trailing slash, nor a leading slash, being a relative
	// path. In order to ensure consistent hashing of the same Action, the
	// output paths MUST be deduplicated and sorted lexicographically by
	// code point (or, equivalently, by UTF-8 bytes). Directories leading up
	// to the output paths are created by the worker prior to execution,
	// even if they are not explicitly part of the input root. New in v2.1:
	// this field supersedes the DEPRECATED `output_files` and
	// `output_directories` fields. If `output_paths` is used,
	// `output_files` and `output_directories` will be ignored!
	OutputPaths []string `json:"outputPaths,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// NodeProperties: The node properties of the Directory.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// NodeProperties: The node properties of the FileNode.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,omitempty"`

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

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

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

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

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

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

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

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

// BuildBazelRemoteExecutionV2NodeProperty: A single property for
// FileNodes, DirectoryNodes, and SymlinkNodes. The server is
// responsible for specifying the property `name`s that it accepts. If
// permitted by the server, the same `name` may occur multiple times.
type BuildBazelRemoteExecutionV2NodeProperty struct {
	// Name: The property name.
	Name string `json:"name,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

	// NodeProperties: The supported node properties of the OutputFile, if
	// requested by the Action.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,omitempty"`

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

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

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

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

// BuildBazelRemoteExecutionV2OutputSymlink: An `OutputSymlink` is
// similar to a Symlink, but it is used as an output in an
// `ActionResult`. `OutputSymlink` is binary-compatible with
// `SymlinkNode`.
type BuildBazelRemoteExecutionV2OutputSymlink struct {
	// NodeProperties: The supported node properties of the OutputSymlink,
	// if requested by the Action.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// NodeProperties: The node properties of the SymlinkNode.
	NodeProperties []*BuildBazelRemoteExecutionV2NodeProperty `json:"nodeProperties,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// GoogleDevtoolsRemotebuildbotCommandStatus: The internal status of the
// command result.
type GoogleDevtoolsRemotebuildbotCommandStatus struct {
	// Code: The status code.
	//
	// Possible values:
	//   "OK" - The command succeeded.
	//   "INVALID_ARGUMENT" - The command input was invalid.
	//   "DEADLINE_EXCEEDED" - The command had passed its expiry time while
	// it was still running.
	//   "NOT_FOUND" - The resources requested by the command were not
	// found.
	//   "PERMISSION_DENIED" - The command failed due to permission errors.
	//   "INTERNAL" - The command failed because of some invariants expected
	// by the underlying system have been broken. This usually indicates a
	// bug wit the system.
	//   "ABORTED" - The command was aborted.
	//   "FAILED_PRECONDITION" - The command failed because the system is
	// not in a state required for the command, e.g. the command inputs
	// cannot be found on the server.
	//   "CLEANUP_ERROR" - The bot failed to do the cleanup, e.g. unable to
	// delete the command working directory or the command process.
	//   "DOWNLOAD_INPUTS_ERROR" - The bot failed to download the inputs.
	//   "UNKNOWN" - Unknown error.
	//   "UPLOAD_OUTPUTS_ERROR" - The bot failed to upload the outputs.
	//   "UPLOAD_OUTPUTS_BYTES_LIMIT_EXCEEDED" - The bot tried to upload
	// files having a total size that is too large.
	//   "DOCKER_LOGIN_ERROR" - The bot failed to login to docker.
	//   "DOCKER_IMAGE_PULL_ERROR" - The bot failed to pull docker image.
	//   "DOCKER_IMAGE_EXIST_ERROR" - The bot failed to check docker images.
	//   "DUPLICATE_INPUTS" - The inputs contain duplicate files.
	//   "DOCKER_IMAGE_PERMISSION_DENIED" - The bot doesn't have the
	// permissions to pull docker images.
	//   "DOCKER_IMAGE_NOT_FOUND" - The docker image cannot be found.
	//   "WORKING_DIR_NOT_FOUND" - Working directory is not found.
	//   "WORKING_DIR_NOT_IN_BASE_DIR" - Working directory is not under the
	// base directory
	//   "DOCKER_UNAVAILABLE" - There are issues with docker
	// service/runtime.
	//   "NO_CUDA_CAPABLE_DEVICE" - The command failed with "no cuda-capable
	// device is detected" error.
	//   "REMOTE_CAS_DOWNLOAD_ERROR" - The bot encountered errors from
	// remote CAS when downloading blobs.
	//   "REMOTE_CAS_UPLOAD_ERROR" - The bot encountered errors from remote
	// CAS when uploading blobs.
	//   "LOCAL_CASPROXY_NOT_RUNNING" - The local casproxy is not running.
	//   "DOCKER_CREATE_CONTAINER_ERROR" - The bot couldn't start the
	// container.
	//   "DOCKER_INVALID_ULIMIT" - The docker ulimit is not valid.
	//   "DOCKER_UNKNOWN_RUNTIME" - The docker runtime is unknown.
	//   "DOCKER_UNKNOWN_CAPABILITY" - The docker capability is unknown.
	//   "DOCKER_UNKNOWN_ERROR" - The command failed with unknown docker
	// errors.
	//   "DOCKER_CREATE_COMPUTE_SYSTEM_ERROR" - Docker failed to run
	// containers with CreateComputeSystem error.
	//   "DOCKER_PREPARELAYER_ERROR" - Docker failed to run containers with
	// hcsshim::PrepareLayer error.
	//   "DOCKER_INCOMPATIBLE_OS_ERROR" - Docker incompatible operating
	// system error.
	//   "DOCKER_CREATE_RUNTIME_FILE_NOT_FOUND" - Docker failed to create
	// OCI runtime because of file not found.
	//   "DOCKER_CREATE_RUNTIME_PERMISSION_DENIED" - Docker failed to create
	// OCI runtime because of permission denied.
	//   "DOCKER_CREATE_PROCESS_FILE_NOT_FOUND" - Docker failed to create
	// process because of file not found.
	//   "DOCKER_CREATE_COMPUTE_SYSTEM_INCORRECT_PARAMETER_ERROR" - Docker
	// failed to run containers with CreateComputeSystem error that involves
	// an incorrect parameter (more specific version of
	// DOCKER_CREATE_COMPUTE_SYSTEM_ERROR that is user-caused).
	Code string `json:"code,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteWorkerPoolRequest:
//  The request used for DeleteWorkerPool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaDeleteWorkerPoolRequest struct {
	// Name: Name of the worker pool to delete. Format:
	// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/workerpools/[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)
}

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicy:
// FeaturePolicy defines features allowed to be used on RBE instances,
// as well as instance-wide behavior changes that take effect without
// opt-in or opt-out at usage time.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicy struct {
	// ContainerImageSources: Which container image sources are allowed.
	// Currently only RBE-supported registry (gcr.io) is allowed. One can
	// allow all repositories under a project or one specific repository
	// only. E.g. container_image_sources { policy: RESTRICTED
	// allowed_values: [ "gcr.io/project-foo",
	// "gcr.io/project-bar/repo-baz", ] } will allow any repositories under
	// "gcr.io/project-foo" plus the repository
	// "gcr.io/project-bar/repo-baz". Default (UNSPECIFIED) is equivalent to
	// any source is allowed.
	ContainerImageSources *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature `json:"containerImageSources,omitempty"`

	// DockerAddCapabilities: Whether dockerAddCapabilities can be used or
	// what capabilities are allowed.
	DockerAddCapabilities *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature `json:"dockerAddCapabilities,omitempty"`

	// DockerChrootPath: Whether dockerChrootPath can be used.
	DockerChrootPath *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature `json:"dockerChrootPath,omitempty"`

	// DockerNetwork: Whether dockerNetwork can be used or what network
	// modes are allowed. E.g. one may allow `off` value only via
	// `allowed_values`.
	DockerNetwork *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature `json:"dockerNetwork,omitempty"`

	// DockerPrivileged: Whether dockerPrivileged can be used.
	DockerPrivileged *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature `json:"dockerPrivileged,omitempty"`

	// DockerRunAsRoot: Whether dockerRunAsRoot can be used.
	DockerRunAsRoot *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature `json:"dockerRunAsRoot,omitempty"`

	// DockerRuntime: Whether dockerRuntime is allowed to be set or what
	// runtimes are allowed. Note linux_isolation takes precedence, and if
	// set, docker_runtime values may be rejected if they are incompatible
	// with the selected isolation.
	DockerRuntime *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature `json:"dockerRuntime,omitempty"`

	// DockerSiblingContainers: Whether dockerSiblingContainers can be used.
	DockerSiblingContainers *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature `json:"dockerSiblingContainers,omitempty"`

	// LinuxIsolation: linux_isolation allows overriding the docker runtime
	// used for containers started on Linux.
	//
	// Possible values:
	//   "LINUX_ISOLATION_UNSPECIFIED" - Default value. Will be using Linux
	// default runtime.
	//   "GVISOR" - Use gVisor runsc runtime.
	//   "OFF" - Use stardard Linux runtime. This has the same behaviour as
	// unspecified, but it can be used to revert back from gVisor.
	LinuxIsolation string `json:"linuxIsolation,omitempty"`

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature:
// Defines whether a feature can be used or what values are accepted.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature struct {
	// AllowedValues: A list of acceptable values. Only effective when the
	// policy is `RESTRICTED`.
	AllowedValues []string `json:"allowedValues,omitempty"`

	// Policy: The policy of the feature.
	//
	// Possible values:
	//   "POLICY_UNSPECIFIED" - Default value, if not explicitly set.
	// Equivalent to FORBIDDEN, unless otherwise documented on a specific
	// Feature.
	//   "ALLOWED" - Feature is explicitly allowed.
	//   "FORBIDDEN" - Feature is forbidden. Requests attempting to leverage
	// it will get an FailedPrecondition error, with a message like:
	// "Feature forbidden by FeaturePolicy: Feature on instance "
	//   "RESTRICTED" - Only the values specified in the `allowed_values`
	// are allowed.
	Policy string `json:"policy,omitempty"`

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

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

func (s *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicyFeature
	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]/workerpools/[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 {
	// FeaturePolicy: The policy to define whether or not RBE features can
	// be used or how they can be used.
	FeaturePolicy *GoogleDevtoolsRemotebuildexecutionAdminV1alphaFeaturePolicy `json:"featurePolicy,omitempty"`

	// Location: The location is a GCP region. Currently only `us-central1`
	// is supported.
	Location string `json:"location,omitempty"`

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

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

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

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

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

	// NullFields is a list of field names (e.g. "FeaturePolicy") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field 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"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaSoleTenancyConfig:
// SoleTenancyConfig specifies information required to host a pool on
// STNs.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaSoleTenancyConfig struct {
	// NodeType: The sole-tenant node type to host the pool's workers on.
	NodeType string `json:"nodeType,omitempty"`

	// NodesZone: Zone in which STNs are reserved.
	NodesZone string `json:"nodesZone,omitempty"`

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateInstanceRequest:
// The request used for `UpdateInstance`.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateInstanceRequest struct {
	// Instance: Specifies the instance to update.
	Instance *GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance `json:"instance,omitempty"`

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

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

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

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateWorkerPoolRequest:
//  The request used for UpdateWorkerPool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateWorkerPoolRequest struct {
	// UpdateMask: The update mask applies to worker_pool. For the
	// `FieldMask` definition, see
	// https://developers.google.com/protocol-buffers/docs/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 creating workers in the worker pool.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerConfig struct {
	// Accelerator: The accelerator card attached to each VM.
	Accelerator *GoogleDevtoolsRemotebuildexecutionAdminV1alphaAcceleratorConfig `json:"accelerator,omitempty"`

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

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

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

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

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

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

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

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

	// SoleTenancy: Sole-tenant node information for pools hosted on STNs.
	SoleTenancy *GoogleDevtoolsRemotebuildexecutionAdminV1alphaSoleTenancyConfig `json:"soleTenancy,omitempty"`

	// VmImage: The name of the image used by each VM.
	VmImage string `json:"vmImage,omitempty"`

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

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

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

// GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool: A worker
// pool resource in the Remote Build Execution API.
type GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool struct {
	// Autoscale: The autoscale policy to apply on a pool.
	Autoscale *GoogleDevtoolsRemotebuildexecutionAdminV1alphaAutoscale `json:"autoscale,omitempty"`

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

	// Name: WorkerPool resource name formatted as:
	// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/workerpools/[POOL_ID]`.
	//  name should not be populated when creating a worker pool since it is
	// provided in the `poolId` field.
	Name string `json:"name,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// method id "remotebuildexecution.projects.instances.create":

type ProjectsInstancesCreateCall struct {
	s                                                                   *Service
	parent                                                              string
	googledevtoolsremotebuildexecutionadminv1alphacreateinstancerequest *GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateInstanceRequest
	urlParams_                                                          gensupport.URLParams
	ctx_                                                                context.Context
	header_                                                             http.Header
}

// Create: Creates a new instance in the specified region. Returns a
// long running operation which contains an instance on completion.
// While the long running operation is in progress, any call to
// `GetInstance` returns an instance in state `CREATING`.
func (r *ProjectsInstancesService) Create(parent string, googledevtoolsremotebuildexecutionadminv1alphacreateinstancerequest *GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateInstanceRequest) *ProjectsInstancesCreateCall {
	c := &ProjectsInstancesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googledevtoolsremotebuildexecutionadminv1alphacreateinstancerequest = googledevtoolsremotebuildexecutionadminv1alphacreateinstancerequest
	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 *ProjectsInstancesCreateCall) Fields(s ...googleapi.Field) *ProjectsInstancesCreateCall {
	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 *ProjectsInstancesCreateCall) Context(ctx context.Context) *ProjectsInstancesCreateCall {
	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 *ProjectsInstancesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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.googledevtoolsremotebuildexecutionadminv1alphacreateinstancerequest)
	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, "v1alpha/{+parent}/instances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.projects.instances.create" 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 *ProjectsInstancesCreateCall) 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": "Creates a new instance in the specified region. Returns a long running operation which contains an instance on completion. While the long running operation is in progress, any call to `GetInstance` returns an instance in state `CREATING`.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances",
	//   "httpMethod": "POST",
	//   "id": "remotebuildexecution.projects.instances.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Resource name of the project containing the instance. Format: `projects/[PROJECT_ID]`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/instances",
	//   "request": {
	//     "$ref": "GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateInstanceRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.projects.instances.delete":

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

// Delete: Deletes the specified instance. Returns a long running
// operation which contains a `google.protobuf.Empty` response on
// completion. Deleting an instance with worker pools in it will delete
// these worker pools.
func (r *ProjectsInstancesService) Delete(name string) *ProjectsInstancesDeleteCall {
	c := &ProjectsInstancesDeleteCall{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 *ProjectsInstancesDeleteCall) Fields(s ...googleapi.Field) *ProjectsInstancesDeleteCall {
	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 *ProjectsInstancesDeleteCall) Context(ctx context.Context) *ProjectsInstancesDeleteCall {
	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 *ProjectsInstancesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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, "v1alpha/{+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.projects.instances.delete" 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 *ProjectsInstancesDeleteCall) 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": "Deletes the specified instance. Returns a long running operation which contains a `google.protobuf.Empty` response on completion. Deleting an instance with worker pools in it will delete these worker pools.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances/{instancesId}",
	//   "httpMethod": "DELETE",
	//   "id": "remotebuildexecution.projects.instances.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the instance to delete. Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// Get: Returns the specified instance.
func (r *ProjectsInstancesService) Get(name string) *ProjectsInstancesGetCall {
	c := &ProjectsInstancesGetCall{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 *ProjectsInstancesGetCall) Fields(s ...googleapi.Field) *ProjectsInstancesGetCall {
	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 *ProjectsInstancesGetCall) IfNoneMatch(entityTag string) *ProjectsInstancesGetCall {
	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 *ProjectsInstancesGetCall) Context(ctx context.Context) *ProjectsInstancesGetCall {
	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 *ProjectsInstancesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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, "v1alpha/{+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.instances.get" call.
// Exactly one of
// *GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance.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 *ProjectsInstancesGetCall) Do(opts ...googleapi.CallOption) (*GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance, 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 := &GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified instance.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances/{instancesId}",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.projects.instances.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the instance to retrieve. Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.projects.instances.list":

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

// List: Lists instances in a project.
func (r *ProjectsInstancesService) List(parent string) *ProjectsInstancesListCall {
	c := &ProjectsInstancesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

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

func (c *ProjectsInstancesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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, "v1alpha/{+parent}/instances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.projects.instances.list" call.
// Exactly one of
// *GoogleDevtoolsRemotebuildexecutionAdminV1alphaListInstancesResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleDevtoolsRemotebuildexecutionAdminV1alphaListInstancesResponse.S
// erverResponse.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 *ProjectsInstancesListCall) Do(opts ...googleapi.CallOption) (*GoogleDevtoolsRemotebuildexecutionAdminV1alphaListInstancesResponse, 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 := &GoogleDevtoolsRemotebuildexecutionAdminV1alphaListInstancesResponse{
		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 instances in a project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.projects.instances.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Resource name of the project. Format: `projects/[PROJECT_ID]`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/instances",
	//   "response": {
	//     "$ref": "GoogleDevtoolsRemotebuildexecutionAdminV1alphaListInstancesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.projects.instances.patch":

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

// Patch: Updates the specified instance. Returns a long running
// operation which contains the updated instance in the response on
// completion.
func (r *ProjectsInstancesService) Patch(name string, googledevtoolsremotebuildexecutionadminv1alphainstance *GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance) *ProjectsInstancesPatchCall {
	c := &ProjectsInstancesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googledevtoolsremotebuildexecutionadminv1alphainstance = googledevtoolsremotebuildexecutionadminv1alphainstance
	return c
}

// LoggingEnabled sets the optional parameter "loggingEnabled":
// Deprecated, use instance.logging_enabled instead. Whether to enable
// Stackdriver logging for this instance.
func (c *ProjectsInstancesPatchCall) LoggingEnabled(loggingEnabled bool) *ProjectsInstancesPatchCall {
	c.urlParams_.Set("loggingEnabled", fmt.Sprint(loggingEnabled))
	return c
}

// Name1 sets the optional parameter "name1": Deprecated, use
// instance.Name instead. Name of the instance to update. Format:
// `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.
func (c *ProjectsInstancesPatchCall) Name1(name1 string) *ProjectsInstancesPatchCall {
	c.urlParams_.Set("name1", name1)
	return c
}

// UpdateMask sets the optional parameter "updateMask": The update mask
// applies to instance. 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.
func (c *ProjectsInstancesPatchCall) UpdateMask(updateMask string) *ProjectsInstancesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsInstancesPatchCall) Fields(s ...googleapi.Field) *ProjectsInstancesPatchCall {
	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 *ProjectsInstancesPatchCall) Context(ctx context.Context) *ProjectsInstancesPatchCall {
	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 *ProjectsInstancesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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.googledevtoolsremotebuildexecutionadminv1alphainstance)
	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, "v1alpha/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.projects.instances.patch" 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 *ProjectsInstancesPatchCall) 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": "Updates the specified instance. Returns a long running operation which contains the updated instance in the response on completion.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances/{instancesId}",
	//   "httpMethod": "PATCH",
	//   "id": "remotebuildexecution.projects.instances.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "loggingEnabled": {
	//       "description": "Deprecated, use instance.logging_enabled instead. Whether to enable Stackdriver logging for this instance.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "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.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "name1": {
	//       "description": "Deprecated, use instance.Name instead. Name of the instance to update. Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "The update mask applies to instance. 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.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleDevtoolsRemotebuildexecutionAdminV1alphaInstance"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.projects.instances.workerpools.create":

type ProjectsInstancesWorkerpoolsCreateCall struct {
	s                                                                     *Service
	parent                                                                string
	googledevtoolsremotebuildexecutionadminv1alphacreateworkerpoolrequest *GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateWorkerPoolRequest
	urlParams_                                                            gensupport.URLParams
	ctx_                                                                  context.Context
	header_                                                               http.Header
}

// Create: Creates a new worker pool with a specified size and
// configuration. Returns a long running operation which contains a
// worker pool on completion. While the long running operation is in
// progress, any call to `GetWorkerPool` returns a worker pool in state
// `CREATING`.
func (r *ProjectsInstancesWorkerpoolsService) Create(parent string, googledevtoolsremotebuildexecutionadminv1alphacreateworkerpoolrequest *GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateWorkerPoolRequest) *ProjectsInstancesWorkerpoolsCreateCall {
	c := &ProjectsInstancesWorkerpoolsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googledevtoolsremotebuildexecutionadminv1alphacreateworkerpoolrequest = googledevtoolsremotebuildexecutionadminv1alphacreateworkerpoolrequest
	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 *ProjectsInstancesWorkerpoolsCreateCall) Fields(s ...googleapi.Field) *ProjectsInstancesWorkerpoolsCreateCall {
	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 *ProjectsInstancesWorkerpoolsCreateCall) Context(ctx context.Context) *ProjectsInstancesWorkerpoolsCreateCall {
	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 *ProjectsInstancesWorkerpoolsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesWorkerpoolsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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.googledevtoolsremotebuildexecutionadminv1alphacreateworkerpoolrequest)
	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, "v1alpha/{+parent}/workerpools")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.projects.instances.workerpools.create" 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 *ProjectsInstancesWorkerpoolsCreateCall) 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": "Creates a new worker pool with a specified size and configuration. Returns a long running operation which contains a worker pool on completion. While the long running operation is in progress, any call to `GetWorkerPool` returns a worker pool in state `CREATING`.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances/{instancesId}/workerpools",
	//   "httpMethod": "POST",
	//   "id": "remotebuildexecution.projects.instances.workerpools.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Resource name of the instance in which to create the new worker pool. Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/workerpools",
	//   "request": {
	//     "$ref": "GoogleDevtoolsRemotebuildexecutionAdminV1alphaCreateWorkerPoolRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.projects.instances.workerpools.delete":

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

// Delete: Deletes the specified worker pool. Returns a long running
// operation, which contains a `google.protobuf.Empty` response on
// completion. While the long running operation is in progress, any call
// to `GetWorkerPool` returns a worker pool in state `DELETING`.
func (r *ProjectsInstancesWorkerpoolsService) Delete(name string) *ProjectsInstancesWorkerpoolsDeleteCall {
	c := &ProjectsInstancesWorkerpoolsDeleteCall{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 *ProjectsInstancesWorkerpoolsDeleteCall) Fields(s ...googleapi.Field) *ProjectsInstancesWorkerpoolsDeleteCall {
	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 *ProjectsInstancesWorkerpoolsDeleteCall) Context(ctx context.Context) *ProjectsInstancesWorkerpoolsDeleteCall {
	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 *ProjectsInstancesWorkerpoolsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesWorkerpoolsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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, "v1alpha/{+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.projects.instances.workerpools.delete" 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 *ProjectsInstancesWorkerpoolsDeleteCall) 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": "Deletes the specified worker pool. Returns a long running operation, which contains a `google.protobuf.Empty` response on completion. While the long running operation is in progress, any call to `GetWorkerPool` returns a worker pool in state `DELETING`.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances/{instancesId}/workerpools/{workerpoolsId}",
	//   "httpMethod": "DELETE",
	//   "id": "remotebuildexecution.projects.instances.workerpools.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the worker pool to delete. Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/workerpools/[POOL_ID]`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/instances/[^/]+/workerpools/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.projects.instances.workerpools.get":

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

// Get: Returns the specified worker pool.
func (r *ProjectsInstancesWorkerpoolsService) Get(name string) *ProjectsInstancesWorkerpoolsGetCall {
	c := &ProjectsInstancesWorkerpoolsGetCall{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 *ProjectsInstancesWorkerpoolsGetCall) Fields(s ...googleapi.Field) *ProjectsInstancesWorkerpoolsGetCall {
	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 *ProjectsInstancesWorkerpoolsGetCall) IfNoneMatch(entityTag string) *ProjectsInstancesWorkerpoolsGetCall {
	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 *ProjectsInstancesWorkerpoolsGetCall) Context(ctx context.Context) *ProjectsInstancesWorkerpoolsGetCall {
	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 *ProjectsInstancesWorkerpoolsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesWorkerpoolsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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, "v1alpha/{+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.instances.workerpools.get" call.
// Exactly one of
// *GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool.ServerRespon
// se.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 *ProjectsInstancesWorkerpoolsGetCall) Do(opts ...googleapi.CallOption) (*GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool, 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 := &GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the specified worker pool.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances/{instancesId}/workerpools/{workerpoolsId}",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.projects.instances.workerpools.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the worker pool to retrieve. Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/workerpools/[POOL_ID]`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/instances/[^/]+/workerpools/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleDevtoolsRemotebuildexecutionAdminV1alphaWorkerPool"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.projects.instances.workerpools.list":

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

// List: Lists worker pools in an instance.
func (r *ProjectsInstancesWorkerpoolsService) List(parent string) *ProjectsInstancesWorkerpoolsListCall {
	c := &ProjectsInstancesWorkerpoolsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters resources listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to
// use for filtering. The value must be a string, a number, or a
// boolean. String values are case-insensitive. The comparison operator
// must be either `:`, `=`, `!=`, `>`, `>=`, `<=` or `<`. The `:`
// operator can be used with string fields to match substrings. For
// non-string fields it is equivalent to the `=` operator. The `:*`
// comparison can be used to test whether a key has been defined. You
// can also filter on nested fields. To filter on multiple expressions,
// you can separate expression using `AND` and `OR` operators, using
// parentheses to specify precedence. If neither operator is specified,
// `AND` is assumed. Examples: Include only pools with more than 100
// reserved workers: `(worker_count > 100) (worker_config.reserved =
// true)` Include only pools with a certain label or machines of the
// n1-standard family: `worker_config.labels.key1 : * OR
// worker_config.machine_type: n1-standard`
func (c *ProjectsInstancesWorkerpoolsListCall) Filter(filter string) *ProjectsInstancesWorkerpoolsListCall {
	c.urlParams_.Set("filter", filter)
	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 *ProjectsInstancesWorkerpoolsListCall) Fields(s ...googleapi.Field) *ProjectsInstancesWorkerpoolsListCall {
	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 *ProjectsInstancesWorkerpoolsListCall) IfNoneMatch(entityTag string) *ProjectsInstancesWorkerpoolsListCall {
	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 *ProjectsInstancesWorkerpoolsListCall) Context(ctx context.Context) *ProjectsInstancesWorkerpoolsListCall {
	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 *ProjectsInstancesWorkerpoolsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesWorkerpoolsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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, "v1alpha/{+parent}/workerpools")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.projects.instances.workerpools.list" call.
// Exactly one of
// *GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsResponse
//  or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsResponse
// .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 *ProjectsInstancesWorkerpoolsListCall) Do(opts ...googleapi.CallOption) (*GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsResponse, 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 := &GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsResponse{
		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 worker pools in an instance.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances/{instancesId}/workerpools",
	//   "httpMethod": "GET",
	//   "id": "remotebuildexecution.projects.instances.workerpools.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Optional. A filter expression that filters resources listed in the response. The expression must specify the field name, a comparison operator, and the value that you want to use for filtering. The value must be a string, a number, or a boolean. String values are case-insensitive. The comparison operator must be either `:`, `=`, `!=`, `\u003e`, `\u003e=`, `\u003c=` or `\u003c`. The `:` operator can be used with string fields to match substrings. For non-string fields it is equivalent to the `=` operator. The `:*` comparison can be used to test whether a key has been defined. You can also filter on nested fields. To filter on multiple expressions, you can separate expression using `AND` and `OR` operators, using parentheses to specify precedence. If neither operator is specified, `AND` is assumed. Examples: Include only pools with more than 100 reserved workers: `(worker_count \u003e 100) (worker_config.reserved = true)` Include only pools with a certain label or machines of the n1-standard family: `worker_config.labels.key1 : * OR worker_config.machine_type: n1-standard`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Resource name of the instance. Format: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/instances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/workerpools",
	//   "response": {
	//     "$ref": "GoogleDevtoolsRemotebuildexecutionAdminV1alphaListWorkerPoolsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "remotebuildexecution.projects.instances.workerpools.patch":

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

// Patch: Updates an existing worker pool with a specified size and/or
// configuration. Returns a long running operation, which contains a
// worker pool on completion. While the long running operation is in
// progress, any call to `GetWorkerPool` returns a worker pool in state
// `UPDATING`.
func (r *ProjectsInstancesWorkerpoolsService) Patch(name string, googledevtoolsremotebuildexecutionadminv1alphaupdateworkerpoolrequest *GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateWorkerPoolRequest) *ProjectsInstancesWorkerpoolsPatchCall {
	c := &ProjectsInstancesWorkerpoolsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googledevtoolsremotebuildexecutionadminv1alphaupdateworkerpoolrequest = googledevtoolsremotebuildexecutionadminv1alphaupdateworkerpoolrequest
	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 *ProjectsInstancesWorkerpoolsPatchCall) Fields(s ...googleapi.Field) *ProjectsInstancesWorkerpoolsPatchCall {
	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 *ProjectsInstancesWorkerpoolsPatchCall) Context(ctx context.Context) *ProjectsInstancesWorkerpoolsPatchCall {
	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 *ProjectsInstancesWorkerpoolsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsInstancesWorkerpoolsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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.googledevtoolsremotebuildexecutionadminv1alphaupdateworkerpoolrequest)
	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, "v1alpha/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "remotebuildexecution.projects.instances.workerpools.patch" 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 *ProjectsInstancesWorkerpoolsPatchCall) 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": "Updates an existing worker pool with a specified size and/or configuration. Returns a long running operation, which contains a worker pool on completion. While the long running operation is in progress, any call to `GetWorkerPool` returns a worker pool in state `UPDATING`.",
	//   "flatPath": "v1alpha/projects/{projectsId}/instances/{instancesId}/workerpools/{workerpoolsId}",
	//   "httpMethod": "PATCH",
	//   "id": "remotebuildexecution.projects.instances.workerpools.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "WorkerPool resource name formatted as: `projects/[PROJECT_ID]/instances/[INSTANCE_ID]/workerpools/[POOL_ID]`. name should not be populated when creating a worker pool since it is provided in the `poolId` field.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/instances/[^/]+/workerpools/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleDevtoolsRemotebuildexecutionAdminV1alphaUpdateWorkerPoolRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

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

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

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

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

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

func (c *ProjectsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	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, "v1alpha/{+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 method to poll the operation result at intervals as recommended by the API service.",
	//   "flatPath": "v1alpha/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": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
