// 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 genomics provides access to the Genomics API.
//
// For product documentation, see: https://cloud.google.com/genomics
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/genomics/v1alpha2"
//   ...
//   ctx := context.Background()
//   genomicsService, err := genomics.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
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   genomicsService, err := genomics.NewService(ctx, option.WithScopes(genomics.GenomicsScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   genomicsService, err := genomics.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, ...)
//   genomicsService, err := genomics.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package genomics // import "google.golang.org/api/genomics/v1alpha2"

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 = "genomics:v1alpha2"
const apiName = "genomics"
const apiVersion = "v1alpha2"
const basePath = "https://genomics.googleapis.com/"
const mtlsBasePath = "https://genomics.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"

	// View and manage your Google Compute Engine resources
	ComputeScope = "https://www.googleapis.com/auth/compute"

	// View and manage Genomics data
	GenomicsScope = "https://www.googleapis.com/auth/genomics"
)

// 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",
		"https://www.googleapis.com/auth/compute",
		"https://www.googleapis.com/auth/genomics",
	)
	// 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.Operations = NewOperationsService(s)
	s.Pipelines = NewPipelinesService(s)
	return s, nil
}

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

	Operations *OperationsService

	Pipelines *PipelinesService
}

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

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

type OperationsService struct {
	s *Service
}

func NewPipelinesService(s *Service) *PipelinesService {
	rs := &PipelinesService{s: s}
	return rs
}

type PipelinesService struct {
	s *Service
}

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

// ComputeEngine: Describes a Compute Engine resource that is being
// managed by a running pipeline.
type ComputeEngine struct {
	// DiskNames: The names of the disks that were created for this
	// pipeline.
	DiskNames []string `json:"diskNames,omitempty"`

	// InstanceName: The instance on which the operation is running.
	InstanceName string `json:"instanceName,omitempty"`

	// MachineType: The machine type of the instance.
	MachineType string `json:"machineType,omitempty"`

	// Zone: The availability zone in which the instance resides.
	Zone string `json:"zone,omitempty"`

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

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

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

// ContainerKilledEvent: An event generated when a container is forcibly
// terminated by the worker. Currently, this only occurs when the
// container outlives the timeout specified by the user.
type ContainerKilledEvent struct {
	// ActionId: The numeric ID of the action that started the container.
	ActionId int64 `json:"actionId,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 *ContainerKilledEvent) MarshalJSON() ([]byte, error) {
	type NoMethod ContainerKilledEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ContainerStartedEvent: An event generated when a container starts.
type ContainerStartedEvent struct {
	// ActionId: The numeric ID of the action that started this container.
	ActionId int64 `json:"actionId,omitempty"`

	// IpAddress: The public IP address that can be used to connect to the
	// container. This field is only populated when at least one port
	// mapping is present. If the instance was created with a private
	// address, this field will be empty even if port mappings exist.
	IpAddress string `json:"ipAddress,omitempty"`

	// PortMappings: The container-to-host port mappings installed for this
	// container. This set will contain any ports exposed using the
	// `PUBLISH_EXPOSED_PORTS` flag as well as any specified in the `Action`
	// definition.
	PortMappings map[string]int64 `json:"portMappings,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 *ContainerStartedEvent) MarshalJSON() ([]byte, error) {
	type NoMethod ContainerStartedEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ContainerStoppedEvent: An event generated when a container exits.
type ContainerStoppedEvent struct {
	// ActionId: The numeric ID of the action that started this container.
	ActionId int64 `json:"actionId,omitempty"`

	// ExitStatus: The exit status of the container.
	ExitStatus int64 `json:"exitStatus,omitempty"`

	// Stderr: The tail end of any content written to standard error by the
	// container. If the content emits large amounts of debugging noise or
	// contains sensitive information, you can prevent the content from
	// being printed by setting the `DISABLE_STANDARD_ERROR_CAPTURE` flag.
	// Note that only a small amount of the end of the stream is captured
	// here. The entire stream is stored in the `/google/logs` directory
	// mounted into each action, and can be copied off the machine as
	// described elsewhere.
	Stderr string `json:"stderr,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 *ContainerStoppedEvent) MarshalJSON() ([]byte, error) {
	type NoMethod ContainerStoppedEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ControllerConfig: Stores the information that the controller will
// fetch from the server in order to run. Should only be used by VMs
// created by the Pipelines Service and not by end users.
type ControllerConfig struct {
	Cmd string `json:"cmd,omitempty"`

	Disks map[string]string `json:"disks,omitempty"`

	GcsLogPath string `json:"gcsLogPath,omitempty"`

	GcsSinks map[string]RepeatedString `json:"gcsSinks,omitempty"`

	GcsSources map[string]RepeatedString `json:"gcsSources,omitempty"`

	Image string `json:"image,omitempty"`

	MachineType string `json:"machineType,omitempty"`

	Vars map[string]string `json:"vars,omitempty"`

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

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

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

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

// DelayedEvent: An event generated whenever a resource limitation or
// transient error delays execution of a pipeline that was otherwise
// ready to run.
type DelayedEvent struct {
	// Cause: A textual description of the cause of the delay. The string
	// can change without notice because it is often generated by another
	// service (such as Compute Engine).
	Cause string `json:"cause,omitempty"`

	// Metrics: If the delay was caused by a resource shortage, this field
	// lists the Compute Engine metrics that are preventing this operation
	// from running (for example, `CPUS` or `INSTANCES`). If the particular
	// metric is not known, a single `UNKNOWN` metric will be present.
	Metrics []string `json:"metrics,omitempty"`

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

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

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

// Disk: A Google Compute Engine disk resource specification.
type Disk struct {
	// AutoDelete: Deprecated. Disks created by the Pipelines API will be
	// deleted at the end of the pipeline run, regardless of what this field
	// is set to.
	AutoDelete bool `json:"autoDelete,omitempty"`

	// MountPoint: Required at create time and cannot be overridden at run
	// time. Specifies the path in the docker container where files on this
	// disk should be located. For example, if `mountPoint` is `/mnt/disk`,
	// and the parameter has `localPath` `inputs/file.txt`, the docker
	// container can access the data at `/mnt/disk/inputs/file.txt`.
	MountPoint string `json:"mountPoint,omitempty"`

	// Name: Required. The name of the disk that can be used in the pipeline
	// parameters. Must be 1 - 63 characters. The name "boot" is reserved
	// for system use.
	Name string `json:"name,omitempty"`

	// ReadOnly: Specifies how a sourced-base persistent disk will be
	// mounted. See
	// https://cloud.google.com/compute/docs/disks/persistent-disks#use_multi_instances for more details. Can only be set at create
	// time.
	ReadOnly bool `json:"readOnly,omitempty"`

	// SizeGb: The size of the disk. Defaults to 500 (GB). This field is not
	// applicable for local SSD.
	SizeGb int64 `json:"sizeGb,omitempty"`

	// Source: The full or partial URL of the persistent disk to attach. See
	// https://cloud.google.com/compute/docs/reference/latest/instances#resource and https://cloud.google.com/compute/docs/disks/persistent-disks#snapshots for more
	// details.
	Source string `json:"source,omitempty"`

	// Type: Required. The type of the disk to create.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Default disk type. Use one of the other
	// options below.
	//   "PERSISTENT_HDD" - Specifies a Google Compute Engine persistent
	// hard disk. See https://cloud.google.com/compute/docs/disks/#pdspecs
	// for details.
	//   "PERSISTENT_SSD" - Specifies a Google Compute Engine persistent
	// solid-state disk. See
	// https://cloud.google.com/compute/docs/disks/#pdspecs for details.
	//   "LOCAL_SSD" - Specifies a Google Compute Engine local SSD. See
	// https://cloud.google.com/compute/docs/disks/local-ssd for details.
	Type string `json:"type,omitempty"`

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

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

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

// DockerExecutor: The Docker execuctor specification.
type DockerExecutor struct {
	// Cmd: Required. The command or newline delimited script to run. The
	// command string will be executed within a bash shell. If the command
	// exits with a non-zero exit code, output parameter de-localization
	// will be skipped and the pipeline operation's `error` field will be
	// populated. Maximum command string length is 16384.
	Cmd string `json:"cmd,omitempty"`

	// ImageName: Required. Image name from either Docker Hub or Google
	// Container Registry. Users that run pipelines must have READ access to
	// the image.
	ImageName string `json:"imageName,omitempty"`

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

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

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

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

// Event: Carries information about events that occur during pipeline
// execution.
type Event struct {
	// Description: A human-readable description of the event. Note that
	// these strings can change at any time without notice. Any application
	// logic must use the information in the `details` field.
	Description string `json:"description,omitempty"`

	// Details: Machine-readable details about the event.
	Details googleapi.RawMessage `json:"details,omitempty"`

	// Timestamp: The time at which the event occurred.
	Timestamp string `json:"timestamp,omitempty"`

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

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

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

// FailedEvent: An event generated when the execution of a pipeline has
// failed. Note that other events can continue to occur after this
// event.
type FailedEvent struct {
	// Cause: The human-readable description of the cause of the failure.
	Cause string `json:"cause,omitempty"`

	// Code: The Google standard error code that best describes this
	// failure.
	//
	// Possible values:
	//   "OK" - Not an error; returned on success HTTP Mapping: 200 OK
	//   "CANCELLED" - The operation was cancelled, typically by the caller.
	// HTTP Mapping: 499 Client Closed Request
	//   "UNKNOWN" - Unknown error. For example, this error may be returned
	// when a `Status` value received from another address space belongs to
	// an error space that is not known in this address space. Also errors
	// raised by APIs that do not return enough error information may be
	// converted to this error. HTTP Mapping: 500 Internal Server Error
	//   "INVALID_ARGUMENT" - The client specified an invalid argument. Note
	// that this differs from `FAILED_PRECONDITION`. `INVALID_ARGUMENT`
	// indicates arguments that are problematic regardless of the state of
	// the system (e.g., a malformed file name). HTTP Mapping: 400 Bad
	// Request
	//   "DEADLINE_EXCEEDED" - The deadline expired before the operation
	// could complete. For operations that change the state of the system,
	// this error may be returned even if the operation has completed
	// successfully. For example, a successful response from a server could
	// have been delayed long enough for the deadline to expire. HTTP
	// Mapping: 504 Gateway Timeout
	//   "NOT_FOUND" - Some requested entity (e.g., file or directory) was
	// not found. Note to server developers: if a request is denied for an
	// entire class of users, such as gradual feature rollout or
	// undocumented allowlist, `NOT_FOUND` may be used. If a request is
	// denied for some users within a class of users, such as user-based
	// access control, `PERMISSION_DENIED` must be used. HTTP Mapping: 404
	// Not Found
	//   "ALREADY_EXISTS" - The entity that a client attempted to create
	// (e.g., file or directory) already exists. HTTP Mapping: 409 Conflict
	//   "PERMISSION_DENIED" - The caller does not have permission to
	// execute the specified operation. `PERMISSION_DENIED` must not be used
	// for rejections caused by exhausting some resource (use
	// `RESOURCE_EXHAUSTED` instead for those errors). `PERMISSION_DENIED`
	// must not be used if the caller can not be identified (use
	// `UNAUTHENTICATED` instead for those errors). This error code does not
	// imply the request is valid or the requested entity exists or
	// satisfies other pre-conditions. HTTP Mapping: 403 Forbidden
	//   "UNAUTHENTICATED" - The request does not have valid authentication
	// credentials for the operation. HTTP Mapping: 401 Unauthorized
	//   "RESOURCE_EXHAUSTED" - Some resource has been exhausted, perhaps a
	// per-user quota, or perhaps the entire file system is out of space.
	// HTTP Mapping: 429 Too Many Requests
	//   "FAILED_PRECONDITION" - The operation was rejected because the
	// system is not in a state required for the operation's execution. For
	// example, the directory to be deleted is non-empty, an rmdir operation
	// is applied to a non-directory, etc. Service implementors can use the
	// following guidelines to decide between `FAILED_PRECONDITION`,
	// `ABORTED`, and `UNAVAILABLE`: (a) Use `UNAVAILABLE` if the client can
	// retry just the failing call. (b) Use `ABORTED` if the client should
	// retry at a higher level (e.g., when a client-specified test-and-set
	// fails, indicating the client should restart a read-modify-write
	// sequence). (c) Use `FAILED_PRECONDITION` if the client should not
	// retry until the system state has been explicitly fixed. E.g., if an
	// "rmdir" fails because the directory is non-empty,
	// `FAILED_PRECONDITION` should be returned since the client should not
	// retry unless the files are deleted from the directory. HTTP Mapping:
	// 400 Bad Request
	//   "ABORTED" - The operation was aborted, typically due to a
	// concurrency issue such as a sequencer check failure or transaction
	// abort. See the guidelines above for deciding between
	// `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. HTTP Mapping:
	// 409 Conflict
	//   "OUT_OF_RANGE" - The operation was attempted past the valid range.
	// E.g., seeking or reading past end-of-file. Unlike `INVALID_ARGUMENT`,
	// this error indicates a problem that may be fixed if the system state
	// changes. For example, a 32-bit file system will generate
	// `INVALID_ARGUMENT` if asked to read at an offset that is not in the
	// range [0,2^32-1], but it will generate `OUT_OF_RANGE` if asked to
	// read from an offset past the current file size. There is a fair bit
	// of overlap between `FAILED_PRECONDITION` and `OUT_OF_RANGE`. We
	// recommend using `OUT_OF_RANGE` (the more specific error) when it
	// applies so that callers who are iterating through a space can easily
	// look for an `OUT_OF_RANGE` error to detect when they are done. HTTP
	// Mapping: 400 Bad Request
	//   "UNIMPLEMENTED" - The operation is not implemented or is not
	// supported/enabled in this service. HTTP Mapping: 501 Not Implemented
	//   "INTERNAL" - Internal errors. This means that some invariants
	// expected by the underlying system have been broken. This error code
	// is reserved for serious errors. HTTP Mapping: 500 Internal Server
	// Error
	//   "UNAVAILABLE" - The service is currently unavailable. This is most
	// likely a transient condition, which can be corrected by retrying with
	// a backoff. Note that it is not always safe to retry non-idempotent
	// operations. See the guidelines above for deciding between
	// `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. HTTP Mapping:
	// 503 Service Unavailable
	//   "DATA_LOSS" - Unrecoverable data loss or corruption. HTTP Mapping:
	// 500 Internal Server Error
	Code string `json:"code,omitempty"`

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

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

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

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

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

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

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

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

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

// ListPipelinesResponse: The response of ListPipelines. Contains at
// most `pageSize` pipelines. If it contains `pageSize` pipelines, and
// more pipelines exist, then `nextPageToken` will be populated and
// should be used as the `pageToken` argument to a subsequent
// ListPipelines request.
type ListPipelinesResponse struct {
	// NextPageToken: The token to use to get the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Pipelines: The matched pipelines.
	Pipelines []*Pipeline `json:"pipelines,omitempty"`

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

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

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

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

// LocalCopy: LocalCopy defines how a remote file should be copied to
// and from the VM.
type LocalCopy struct {
	// Disk: Required. The name of the disk where this parameter is located.
	// Can be the name of one of the disks specified in the Resources field,
	// or "boot", which represents the Docker instance's boot disk and has a
	// mount point of `/`.
	Disk string `json:"disk,omitempty"`

	// Path: Required. The path within the user's docker container where
	// this input should be localized to and from, relative to the specified
	// disk's mount point. For example: file.txt,
	Path string `json:"path,omitempty"`

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

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

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

// LoggingOptions: The logging options for the pipeline run.
type LoggingOptions struct {
	// GcsPath: The location in Google Cloud Storage to which the pipeline
	// logs will be copied. Can be specified as a fully qualified directory
	// path, in which case logs will be output with a unique identifier as
	// the filename in that directory, or as a fully specified path, which
	// must end in `.log`, in which case that path will be used, and the
	// user must ensure that logs are not overwritten. Stdout and stderr
	// logs from the run are also generated and output as `-stdout.log` and
	// `-stderr.log`.
	GcsPath string `json:"gcsPath,omitempty"`

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

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

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

// Operation: This resource represents a long-running operation that is
// the result of a network API call.
type Operation 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 *Status `json:"error,omitempty"`

	// Metadata: An OperationMetadata or Metadata object. This will always
	// be returned with the Operation.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that originally returns it. For example:
	// `operations/CJHU7Oi_ChDrveSpBRjfuL-qzoWAgEw`
	Name string `json:"name,omitempty"`

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

// OperationEvent: An event that occurred during an Operation.
type OperationEvent struct {
	// Description: Required description of event.
	Description string `json:"description,omitempty"`

	// EndTime: Optional time of when event finished. An event can have a
	// start time and no finish time. If an event has a finish time, there
	// must be a start time.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: Optional time of when event started.
	StartTime string `json:"startTime,omitempty"`

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

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

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

// OperationMetadata: Metadata describing an Operation.
type OperationMetadata struct {
	// ClientId: This field is deprecated. Use `labels` instead. Optionally
	// provided by the caller when submitting the request that creates the
	// operation.
	ClientId string `json:"clientId,omitempty"`

	// CreateTime: The time at which the job was submitted to the Genomics
	// service.
	CreateTime string `json:"createTime,omitempty"`

	// EndTime: The time at which the job stopped running.
	EndTime string `json:"endTime,omitempty"`

	// Events: Optional event messages that were generated during the job's
	// execution. This also contains any warnings that were generated during
	// import or export.
	Events []*OperationEvent `json:"events,omitempty"`

	// Labels: Optionally provided by the caller when submitting the request
	// that creates the operation.
	Labels map[string]string `json:"labels,omitempty"`

	// ProjectId: The Google Cloud Project in which the job is scoped.
	ProjectId string `json:"projectId,omitempty"`

	// Request: The original request that started the operation. Note that
	// this will be in current version of the API. If the operation was
	// started with v1beta2 API and a GetOperation is performed on v1 API, a
	// v1 request will be returned.
	Request googleapi.RawMessage `json:"request,omitempty"`

	// RuntimeMetadata: Runtime metadata on this Operation.
	RuntimeMetadata googleapi.RawMessage `json:"runtimeMetadata,omitempty"`

	// StartTime: The time at which the job began to run.
	StartTime string `json:"startTime,omitempty"`

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

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

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

// Pipeline: The pipeline object. Represents a transformation from a set
// of input parameters to a set of output parameters. The transformation
// is defined as a docker image and command to run within that image.
// Each pipeline is run on a Google Compute Engine VM. A pipeline can be
// created with the `create` method and then later run with the `run`
// method, or a pipeline can be defined and run all at once with the
// `run` method.
type Pipeline struct {
	// Description: User-specified description.
	Description string `json:"description,omitempty"`

	// Docker: Specifies the docker run information.
	Docker *DockerExecutor `json:"docker,omitempty"`

	// InputParameters: Input parameters of the pipeline.
	InputParameters []*PipelineParameter `json:"inputParameters,omitempty"`

	// Name: Required. A user specified pipeline name that does not have to
	// be unique. This name can be used for filtering Pipelines in
	// ListPipelines.
	Name string `json:"name,omitempty"`

	// OutputParameters: Output parameters of the pipeline.
	OutputParameters []*PipelineParameter `json:"outputParameters,omitempty"`

	// PipelineId: Unique pipeline id that is generated by the service when
	// CreatePipeline is called. Cannot be specified in the Pipeline used in
	// the CreatePipelineRequest, and will be populated in the response to
	// CreatePipeline and all subsequent Get and List calls. Indicates that
	// the service has registered this pipeline.
	PipelineId string `json:"pipelineId,omitempty"`

	// ProjectId: Required. The project in which to create the pipeline. The
	// caller must have WRITE access.
	ProjectId string `json:"projectId,omitempty"`

	// Resources: Required. Specifies resource requirements for the pipeline
	// run. Required fields: * minimumCpuCores * minimumRamGb
	Resources *PipelineResources `json:"resources,omitempty"`

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

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

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

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

// PipelineParameter: Parameters facilitate setting and delivering data
// into the pipeline's execution environment. They are defined at create
// time, with optional defaults, and can be overridden at run time. If
// `localCopy` is unset, then the parameter specifies a string that is
// passed as-is into the pipeline, as the value of the environment
// variable with the given name. A default value can be optionally
// specified at create time. The default can be overridden at run time
// using the inputs map. If no default is given, a value must be
// supplied at runtime. If `localCopy` is defined, then the parameter
// specifies a data source or sink, both in Google Cloud Storage and on
// the Docker container where the pipeline computation is run. The
// service account associated with the Pipeline (by default the
// project's Compute Engine service account) must have access to the
// Google Cloud Storage paths. At run time, the Google Cloud Storage
// paths can be overridden if a default was provided at create time, or
// must be set otherwise. The pipeline runner should add a key/value
// pair to either the inputs or outputs map. The indicated data copies
// will be carried out before/after pipeline execution, just as if the
// corresponding arguments were provided to `gsutil cp`. For example:
// Given the following `PipelineParameter`, specified in the
// `inputParameters` list: ``` {name: "input_file", localCopy: {path:
// "file.txt", disk: "pd1"}} ``` where `disk` is defined in the
// `PipelineResources` object as: ``` {name: "pd1", mountPoint:
// "/mnt/disk/"} ``` We create a disk named `pd1`, mount it on the host
// VM, and map `/mnt/pd1` to `/mnt/disk` in the docker container. At
// runtime, an entry for `input_file` would be required in the inputs
// map, such as: ``` inputs["input_file"] = "gs://my-bucket/bar.txt" ```
// This would generate the following gsutil call: ``` gsutil cp
// gs://my-bucket/bar.txt /mnt/pd1/file.txt ``` The file
// `/mnt/pd1/file.txt` maps to `/mnt/disk/file.txt` in the Docker
// container. Acceptable paths are: Google Cloud storage pathLocal path
// file file glob directory For outputs, the direction of the copy is
// reversed: ``` gsutil cp /mnt/disk/file.txt gs://my-bucket/bar.txt ```
// Acceptable paths are: Local pathGoogle Cloud Storage path file file
// file directory - directory must already exist glob directory -
// directory will be created if it doesn't exist One restriction due to
// docker limitations, is that for outputs that are found on the boot
// disk, the local path cannot be a glob and must be a file.
type PipelineParameter struct {
	// DefaultValue: The default value for this parameter. Can be overridden
	// at runtime. If `localCopy` is present, then this must be a Google
	// Cloud Storage path beginning with `gs://`.
	DefaultValue string `json:"defaultValue,omitempty"`

	// Description: Human-readable description.
	Description string `json:"description,omitempty"`

	// LocalCopy: If present, this parameter is marked for copying to and
	// from the VM. `LocalCopy` indicates where on the VM the file should
	// be. The value given to this parameter (either at runtime or using
	// `defaultValue`) must be the remote path where the file should be.
	LocalCopy *LocalCopy `json:"localCopy,omitempty"`

	// Name: Required. Name of the parameter - the pipeline runner uses this
	// string as the key to the input and output maps in RunPipeline.
	Name string `json:"name,omitempty"`

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

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

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

// PipelineResources: The system resources for the pipeline run.
type PipelineResources struct {
	// AcceleratorCount: Optional. The number of accelerators of the
	// specified type to attach. By specifying this parameter, you will
	// download and install the following third-party software onto your
	// managed Compute Engine instances: NVIDIA® Tesla® drivers and
	// NVIDIA® CUDA toolkit.
	AcceleratorCount int64 `json:"acceleratorCount,omitempty,string"`

	// AcceleratorType: Optional. The Compute Engine defined accelerator
	// type. By specifying this parameter, you will download and install the
	// following third-party software onto your managed Compute Engine
	// instances: NVIDIA® Tesla® drivers and NVIDIA® CUDA toolkit. Please
	// see https://cloud.google.com/compute/docs/gpus/ for a list of
	// available accelerator types.
	AcceleratorType string `json:"acceleratorType,omitempty"`

	// BootDiskSizeGb: The size of the boot disk. Defaults to 10 (GB).
	BootDiskSizeGb int64 `json:"bootDiskSizeGb,omitempty"`

	// Disks: Disks to attach.
	Disks []*Disk `json:"disks,omitempty"`

	// MinimumCpuCores: The minimum number of cores to use. Defaults to 1.
	MinimumCpuCores int64 `json:"minimumCpuCores,omitempty"`

	// MinimumRamGb: The minimum amount of RAM to use. Defaults to 3.75 (GB)
	MinimumRamGb float64 `json:"minimumRamGb,omitempty"`

	// NoAddress: Whether to assign an external IP to the instance. This is
	// an experimental feature that may go away. Defaults to false.
	// Corresponds to `--no_address` flag for [gcloud compute instances
	// create]
	// (https://cloud.google.com/sdk/gcloud/reference/compute/instances/creat
	// e). In order to use this, must be true for both create time and run
	// time. Cannot be true at run time if false at create time. If you need
	// to ssh into a private IP VM for debugging, you can ssh to a public VM
	// and then ssh into the private VM's Internal IP. If noAddress is set,
	// this pipeline run may only load docker images from Google Container
	// Registry and not Docker Hub. Before using this, you must [configure
	// access to Google services from internal
	// IPs](https://cloud.google.com/compute/docs/configure-private-google-ac
	// cess#configuring_access_to_google_services_from_internal_ips).
	NoAddress bool `json:"noAddress,omitempty"`

	// Preemptible: Whether to use preemptible VMs. Defaults to `false`. In
	// order to use this, must be true for both create time and run time.
	// Cannot be true at run time if false at create time.
	Preemptible bool `json:"preemptible,omitempty"`

	// Zones: List of Google Compute Engine availability zones to which
	// resource creation will restricted. If empty, any zone may be chosen.
	Zones []string `json:"zones,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 *PipelineResources) MarshalJSON() ([]byte, error) {
	type NoMethod PipelineResources
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// PullStartedEvent: An event generated when the worker starts pulling
// an image.
type PullStartedEvent struct {
	// ImageUri: The URI of the image that was pulled.
	ImageUri string `json:"imageUri,omitempty"`

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

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

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

// PullStoppedEvent: An event generated when the worker stops pulling an
// image.
type PullStoppedEvent struct {
	// ImageUri: The URI of the image that was pulled.
	ImageUri string `json:"imageUri,omitempty"`

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

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

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

type RepeatedString struct {
	Values []string `json:"values,omitempty"`

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

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

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

// RunPipelineArgs: The pipeline run arguments.
type RunPipelineArgs struct {
	// ClientId: This field is deprecated. Use `labels` instead.
	// Client-specified pipeline operation identifier.
	ClientId string `json:"clientId,omitempty"`

	// Inputs: Pipeline input arguments; keys are defined in the pipeline
	// documentation. All input parameters that do not have default values
	// must be specified. If parameters with defaults are specified here,
	// the defaults will be overridden.
	Inputs map[string]string `json:"inputs,omitempty"`

	// KeepVmAliveOnFailureDuration: How long to keep the VM up after a
	// failure (for example docker command failed, copying input or output
	// files failed, etc). While the VM is up, one can ssh into the VM to
	// debug. Default is 0; maximum allowed value is 1 day.
	KeepVmAliveOnFailureDuration string `json:"keepVmAliveOnFailureDuration,omitempty"`

	// Labels: Labels to apply to this pipeline run. Labels will also be
	// applied to compute resources (VM, disks) created by this pipeline
	// run. When listing operations, operations can filtered by labels.
	// Label keys may not be empty; label values may be empty. Non-empty
	// labels must be 1-63 characters long, and comply with [RFC1035]
	// (https://www.ietf.org/rfc/rfc1035.txt). Specifically, the name must
	// be 1-63 characters long and match the regular expression
	// `[a-z]([-a-z0-9]*[a-z0-9])?` which means the first character must be
	// a lowercase letter, and all following characters must be a dash,
	// lowercase letter, or digit, except the last character, which cannot
	// be a dash.
	Labels map[string]string `json:"labels,omitempty"`

	// Logging: Required. Logging options. Used by the service to
	// communicate results to the user.
	Logging *LoggingOptions `json:"logging,omitempty"`

	// Outputs: Pipeline output arguments; keys are defined in the pipeline
	// documentation. All output parameters of without default values must
	// be specified. If parameters with defaults are specified here, the
	// defaults will be overridden.
	Outputs map[string]string `json:"outputs,omitempty"`

	// ProjectId: Required. The project in which to run the pipeline. The
	// caller must have WRITER access to all Google Cloud services and
	// resources (e.g. Google Compute Engine) will be used.
	ProjectId string `json:"projectId,omitempty"`

	// Resources: Specifies resource requirements/overrides for the pipeline
	// run.
	Resources *PipelineResources `json:"resources,omitempty"`

	// ServiceAccount: The Google Cloud Service Account that will be used to
	// access data and services. By default, the compute service account
	// associated with `projectId` is used.
	ServiceAccount *ServiceAccount `json:"serviceAccount,omitempty"`

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

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

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

// RunPipelineRequest: The request to run a pipeline. If `pipelineId` is
// specified, it refers to a saved pipeline created with CreatePipeline
// and set as the `pipelineId` of the returned Pipeline object. If
// `ephemeralPipeline` is specified, that pipeline is run once with the
// given args and not saved. It is an error to specify both `pipelineId`
// and `ephemeralPipeline`. `pipelineArgs` must be specified.
type RunPipelineRequest struct {
	// EphemeralPipeline: A new pipeline object to run once and then delete.
	EphemeralPipeline *Pipeline `json:"ephemeralPipeline,omitempty"`

	// PipelineArgs: The arguments to use when running this pipeline.
	PipelineArgs *RunPipelineArgs `json:"pipelineArgs,omitempty"`

	// PipelineId: The already created pipeline to run.
	PipelineId string `json:"pipelineId,omitempty"`

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

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

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

// RunPipelineResponse: The response to the RunPipeline method, returned
// in the operation's result field on success.
type RunPipelineResponse struct {
}

// RuntimeMetadata: Runtime metadata that will be populated in the
// runtimeMetadata field of the Operation associated with a RunPipeline
// execution.
type RuntimeMetadata struct {
	// ComputeEngine: Execution information specific to Google Compute
	// Engine.
	ComputeEngine *ComputeEngine `json:"computeEngine,omitempty"`

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

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

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

// ServiceAccount: A Google Cloud Service Account.
type ServiceAccount struct {
	// Email: Email address of the service account. Defaults to `default`,
	// which uses the compute service account associated with the project.
	Email string `json:"email,omitempty"`

	// Scopes: List of scopes to be enabled for this service account on the
	// VM. The following scopes are automatically included: *
	// https://www.googleapis.com/auth/compute *
	// https://www.googleapis.com/auth/devstorage.full_control *
	// https://www.googleapis.com/auth/genomics *
	// https://www.googleapis.com/auth/logging.write *
	// https://www.googleapis.com/auth/monitoring.write
	Scopes []string `json:"scopes,omitempty"`

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

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

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

// SetOperationStatusRequest: Request to set operation status. Should
// only be used by VMs created by the Pipelines Service and not by end
// users.
type SetOperationStatusRequest struct {
	// Possible values:
	//   "OK" - Not an error; returned on success HTTP Mapping: 200 OK
	//   "CANCELLED" - The operation was cancelled, typically by the caller.
	// HTTP Mapping: 499 Client Closed Request
	//   "UNKNOWN" - Unknown error. For example, this error may be returned
	// when a `Status` value received from another address space belongs to
	// an error space that is not known in this address space. Also errors
	// raised by APIs that do not return enough error information may be
	// converted to this error. HTTP Mapping: 500 Internal Server Error
	//   "INVALID_ARGUMENT" - The client specified an invalid argument. Note
	// that this differs from `FAILED_PRECONDITION`. `INVALID_ARGUMENT`
	// indicates arguments that are problematic regardless of the state of
	// the system (e.g., a malformed file name). HTTP Mapping: 400 Bad
	// Request
	//   "DEADLINE_EXCEEDED" - The deadline expired before the operation
	// could complete. For operations that change the state of the system,
	// this error may be returned even if the operation has completed
	// successfully. For example, a successful response from a server could
	// have been delayed long enough for the deadline to expire. HTTP
	// Mapping: 504 Gateway Timeout
	//   "NOT_FOUND" - Some requested entity (e.g., file or directory) was
	// not found. Note to server developers: if a request is denied for an
	// entire class of users, such as gradual feature rollout or
	// undocumented allowlist, `NOT_FOUND` may be used. If a request is
	// denied for some users within a class of users, such as user-based
	// access control, `PERMISSION_DENIED` must be used. HTTP Mapping: 404
	// Not Found
	//   "ALREADY_EXISTS" - The entity that a client attempted to create
	// (e.g., file or directory) already exists. HTTP Mapping: 409 Conflict
	//   "PERMISSION_DENIED" - The caller does not have permission to
	// execute the specified operation. `PERMISSION_DENIED` must not be used
	// for rejections caused by exhausting some resource (use
	// `RESOURCE_EXHAUSTED` instead for those errors). `PERMISSION_DENIED`
	// must not be used if the caller can not be identified (use
	// `UNAUTHENTICATED` instead for those errors). This error code does not
	// imply the request is valid or the requested entity exists or
	// satisfies other pre-conditions. HTTP Mapping: 403 Forbidden
	//   "UNAUTHENTICATED" - The request does not have valid authentication
	// credentials for the operation. HTTP Mapping: 401 Unauthorized
	//   "RESOURCE_EXHAUSTED" - Some resource has been exhausted, perhaps a
	// per-user quota, or perhaps the entire file system is out of space.
	// HTTP Mapping: 429 Too Many Requests
	//   "FAILED_PRECONDITION" - The operation was rejected because the
	// system is not in a state required for the operation's execution. For
	// example, the directory to be deleted is non-empty, an rmdir operation
	// is applied to a non-directory, etc. Service implementors can use the
	// following guidelines to decide between `FAILED_PRECONDITION`,
	// `ABORTED`, and `UNAVAILABLE`: (a) Use `UNAVAILABLE` if the client can
	// retry just the failing call. (b) Use `ABORTED` if the client should
	// retry at a higher level (e.g., when a client-specified test-and-set
	// fails, indicating the client should restart a read-modify-write
	// sequence). (c) Use `FAILED_PRECONDITION` if the client should not
	// retry until the system state has been explicitly fixed. E.g., if an
	// "rmdir" fails because the directory is non-empty,
	// `FAILED_PRECONDITION` should be returned since the client should not
	// retry unless the files are deleted from the directory. HTTP Mapping:
	// 400 Bad Request
	//   "ABORTED" - The operation was aborted, typically due to a
	// concurrency issue such as a sequencer check failure or transaction
	// abort. See the guidelines above for deciding between
	// `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. HTTP Mapping:
	// 409 Conflict
	//   "OUT_OF_RANGE" - The operation was attempted past the valid range.
	// E.g., seeking or reading past end-of-file. Unlike `INVALID_ARGUMENT`,
	// this error indicates a problem that may be fixed if the system state
	// changes. For example, a 32-bit file system will generate
	// `INVALID_ARGUMENT` if asked to read at an offset that is not in the
	// range [0,2^32-1], but it will generate `OUT_OF_RANGE` if asked to
	// read from an offset past the current file size. There is a fair bit
	// of overlap between `FAILED_PRECONDITION` and `OUT_OF_RANGE`. We
	// recommend using `OUT_OF_RANGE` (the more specific error) when it
	// applies so that callers who are iterating through a space can easily
	// look for an `OUT_OF_RANGE` error to detect when they are done. HTTP
	// Mapping: 400 Bad Request
	//   "UNIMPLEMENTED" - The operation is not implemented or is not
	// supported/enabled in this service. HTTP Mapping: 501 Not Implemented
	//   "INTERNAL" - Internal errors. This means that some invariants
	// expected by the underlying system have been broken. This error code
	// is reserved for serious errors. HTTP Mapping: 500 Internal Server
	// Error
	//   "UNAVAILABLE" - The service is currently unavailable. This is most
	// likely a transient condition, which can be corrected by retrying with
	// a backoff. Note that it is not always safe to retry non-idempotent
	// operations. See the guidelines above for deciding between
	// `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`. HTTP Mapping:
	// 503 Service Unavailable
	//   "DATA_LOSS" - Unrecoverable data loss or corruption. HTTP Mapping:
	// 500 Internal Server Error
	ErrorCode string `json:"errorCode,omitempty"`

	ErrorMessage string `json:"errorMessage,omitempty"`

	OperationId string `json:"operationId,omitempty"`

	TimestampEvents []*TimestampEvent `json:"timestampEvents,omitempty"`

	ValidationToken uint64 `json:"validationToken,omitempty,string"`

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

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

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

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

// TimestampEvent: Stores the list of events and times they occured for
// major events in job execution.
type TimestampEvent struct {
	// Description: String indicating the type of event
	Description string `json:"description,omitempty"`

	// Timestamp: The time this event occured.
	Timestamp string `json:"timestamp,omitempty"`

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

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

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

// UnexpectedExitStatusEvent: An event generated when the execution of a
// container results in a non-zero exit status that was not otherwise
// ignored. Execution will continue, but only actions that are flagged
// as `ALWAYS_RUN` will be executed. Other actions will be skipped.
type UnexpectedExitStatusEvent struct {
	// ActionId: The numeric ID of the action that started the container.
	ActionId int64 `json:"actionId,omitempty"`

	// ExitStatus: The exit status of the container.
	ExitStatus int64 `json:"exitStatus,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 *UnexpectedExitStatusEvent) MarshalJSON() ([]byte, error) {
	type NoMethod UnexpectedExitStatusEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WorkerAssignedEvent: An event generated after a worker VM has been
// assigned to run the pipeline.
type WorkerAssignedEvent struct {
	// Instance: The worker's instance name.
	Instance string `json:"instance,omitempty"`

	// MachineType: The machine type that was assigned for the worker.
	MachineType string `json:"machineType,omitempty"`

	// Zone: The zone the worker is running in.
	Zone string `json:"zone,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 *WorkerAssignedEvent) MarshalJSON() ([]byte, error) {
	type NoMethod WorkerAssignedEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WorkerReleasedEvent: An event generated when the worker VM that was
// assigned to the pipeline has been released (deleted).
type WorkerReleasedEvent struct {
	// Instance: The worker's instance name.
	Instance string `json:"instance,omitempty"`

	// Zone: The zone the worker was running in.
	Zone string `json:"zone,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 *WorkerReleasedEvent) MarshalJSON() ([]byte, error) {
	type NoMethod WorkerReleasedEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

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

// Cancel: Starts asynchronous cancellation on a long-running operation.
// The server makes a best effort to cancel the operation, but success
// is not guaranteed. Clients may use Operations.GetOperation or
// Operations.ListOperations to check whether the cancellation succeeded
// or the operation completed despite cancellation. Authorization
// requires the following [Google IAM](https://cloud.google.com/iam)
// permission: * `genomics.operations.cancel`
func (r *OperationsService) Cancel(name string, canceloperationrequest *CancelOperationRequest) *OperationsCancelCall {
	c := &OperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.canceloperationrequest = canceloperationrequest
	return c
}

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

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

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

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

// Do executes the "genomics.operations.cancel" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *OperationsCancelCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Starts asynchronous cancellation on a long-running operation. The server makes a best effort to cancel the operation, but success is not guaranteed. Clients may use Operations.GetOperation or Operations.ListOperations to check whether the cancellation succeeded or the operation completed despite cancellation. Authorization requires the following [Google IAM](https://cloud.google.com/iam) permission: * `genomics.operations.cancel`",
	//   "flatPath": "v1alpha2/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "genomics.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^operations/.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha2/{+name}:cancel",
	//   "request": {
	//     "$ref": "CancelOperationRequest"
	//   },
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

// method id "genomics.operations.get":

type OperationsGetCall 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. Authorization requires the following
// [Google IAM](https://cloud.google.com/iam) permission: *
// `genomics.operations.get`
func (r *OperationsService) Get(name string) *OperationsGetCall {
	c := &OperationsGetCall{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 *OperationsGetCall) Fields(s ...googleapi.Field) *OperationsGetCall {
	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 *OperationsGetCall) IfNoneMatch(entityTag string) *OperationsGetCall {
	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 *OperationsGetCall) Context(ctx context.Context) *OperationsGetCall {
	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 *OperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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, "v1alpha2/{+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 "genomics.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.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 *OperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, 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 := &Operation{
		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. Authorization requires the following [Google IAM](https://cloud.google.com/iam) permission: * `genomics.operations.get`",
	//   "flatPath": "v1alpha2/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "genomics.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^operations/.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha2/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

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

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

// List: Lists operations that match the specified filter in the
// request. Authorization requires the following [Google
// IAM](https://cloud.google.com/iam) permission: *
// `genomics.operations.list`
func (r *OperationsService) List(name string) *OperationsListCall {
	c := &OperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": A string for filtering
// Operations. In v2alpha1, the following filter fields are supported: *
// createTime: The time this job was created * events: The set of event
// (names) that have occurred while running the pipeline. The : operator
// can be used to determine if a particular event has occurred. * error:
// If the pipeline is running, this value is NULL. Once the pipeline
// finishes, the value is the standard Google error code. * labels.key
// or labels."key with space" where key is a label key. * done: If the
// pipeline is running, this value is false. Once the pipeline finishes,
// the value is true. In v1 and v1alpha2, the following filter fields
// are supported: * projectId: Required. Corresponds to
// OperationMetadata.projectId. * createTime: The time this job was
// created, in seconds from the
// [epoch](http://en.wikipedia.org/wiki/Unix_time). Can use `>=` and/or
// `<=` operators. * status: Can be `RUNNING`, `SUCCESS`, `FAILURE`, or
// `CANCELED`. Only one status may be specified. * labels.key where key
// is a label key. Examples: * `projectId = my-project AND createTime >=
// 1432140000` * `projectId = my-project AND createTime >= 1432140000
// AND createTime <= 1432150000 AND status = RUNNING` * `projectId =
// my-project AND labels.color = *` * `projectId = my-project AND
// labels.color = red`
func (c *OperationsListCall) Filter(filter string) *OperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results to return. The maximum value is 256.
func (c *OperationsListCall) PageSize(pageSize int64) *OperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

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

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

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

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

func (c *OperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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, "v1alpha2/{+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 "genomics.operations.list" call.
// Exactly one of *ListOperationsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OperationsListCall) Do(opts ...googleapi.CallOption) (*ListOperationsResponse, 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 := &ListOperationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists operations that match the specified filter in the request. Authorization requires the following [Google IAM](https://cloud.google.com/iam) permission: * `genomics.operations.list`",
	//   "flatPath": "v1alpha2/operations",
	//   "httpMethod": "GET",
	//   "id": "genomics.operations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A string for filtering Operations. In v2alpha1, the following filter fields are supported: * createTime: The time this job was created * events: The set of event (names) that have occurred while running the pipeline. The : operator can be used to determine if a particular event has occurred. * error: If the pipeline is running, this value is NULL. Once the pipeline finishes, the value is the standard Google error code. * labels.key or labels.\"key with space\" where key is a label key. * done: If the pipeline is running, this value is false. Once the pipeline finishes, the value is true. In v1 and v1alpha2, the following filter fields are supported: * projectId: Required. Corresponds to OperationMetadata.projectId. * createTime: The time this job was created, in seconds from the [epoch](http://en.wikipedia.org/wiki/Unix_time). Can use `\u003e=` and/or `\u003c=` operators. * status: Can be `RUNNING`, `SUCCESS`, `FAILURE`, or `CANCELED`. Only one status may be specified. * labels.key where key is a label key. Examples: * `projectId = my-project AND createTime \u003e= 1432140000` * `projectId = my-project AND createTime \u003e= 1432140000 AND createTime \u003c= 1432150000 AND status = RUNNING` * `projectId = my-project AND labels.color = *` * `projectId = my-project AND labels.color = red`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "path",
	//       "pattern": "^operations$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of results to return. The maximum value is 256.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha2/{+name}",
	//   "response": {
	//     "$ref": "ListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

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

// method id "genomics.pipelines.create":

type PipelinesCreateCall struct {
	s          *Service
	pipeline   *Pipeline
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a pipeline that can be run later. Create takes a
// Pipeline that has all fields other than `pipelineId` populated, and
// then returns the same pipeline with `pipelineId` populated. This id
// can be used to run the pipeline. Caller must have WRITE permission to
// the project.
func (r *PipelinesService) Create(pipeline *Pipeline) *PipelinesCreateCall {
	c := &PipelinesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.pipeline = pipeline
	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 *PipelinesCreateCall) Fields(s ...googleapi.Field) *PipelinesCreateCall {
	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 *PipelinesCreateCall) Context(ctx context.Context) *PipelinesCreateCall {
	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 *PipelinesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PipelinesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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.pipeline)
	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, "v1alpha2/pipelines")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "genomics.pipelines.create" call.
// Exactly one of *Pipeline or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Pipeline.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 *PipelinesCreateCall) Do(opts ...googleapi.CallOption) (*Pipeline, 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 := &Pipeline{
		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 pipeline that can be run later. Create takes a Pipeline that has all fields other than `pipelineId` populated, and then returns the same pipeline with `pipelineId` populated. This id can be used to run the pipeline. Caller must have WRITE permission to the project.",
	//   "flatPath": "v1alpha2/pipelines",
	//   "httpMethod": "POST",
	//   "id": "genomics.pipelines.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha2/pipelines",
	//   "request": {
	//     "$ref": "Pipeline"
	//   },
	//   "response": {
	//     "$ref": "Pipeline"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

// method id "genomics.pipelines.delete":

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

// Delete: Deletes a pipeline based on ID. Caller must have WRITE
// permission to the project.
func (r *PipelinesService) Delete(pipelineId string) *PipelinesDeleteCall {
	c := &PipelinesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.pipelineId = pipelineId
	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 *PipelinesDeleteCall) Fields(s ...googleapi.Field) *PipelinesDeleteCall {
	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 *PipelinesDeleteCall) Context(ctx context.Context) *PipelinesDeleteCall {
	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 *PipelinesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PipelinesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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, "v1alpha2/pipelines/{pipelineId}")
	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{
		"pipelineId": c.pipelineId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "genomics.pipelines.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *PipelinesDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a pipeline based on ID. Caller must have WRITE permission to the project.",
	//   "flatPath": "v1alpha2/pipelines/{pipelineId}",
	//   "httpMethod": "DELETE",
	//   "id": "genomics.pipelines.delete",
	//   "parameterOrder": [
	//     "pipelineId"
	//   ],
	//   "parameters": {
	//     "pipelineId": {
	//       "description": "Caller must have WRITE access to the project in which this pipeline is defined.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha2/pipelines/{pipelineId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

// method id "genomics.pipelines.get":

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

// Get: Retrieves a pipeline based on ID. Caller must have READ
// permission to the project.
func (r *PipelinesService) Get(pipelineId string) *PipelinesGetCall {
	c := &PipelinesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.pipelineId = pipelineId
	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 *PipelinesGetCall) Fields(s ...googleapi.Field) *PipelinesGetCall {
	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 *PipelinesGetCall) IfNoneMatch(entityTag string) *PipelinesGetCall {
	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 *PipelinesGetCall) Context(ctx context.Context) *PipelinesGetCall {
	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 *PipelinesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PipelinesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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, "v1alpha2/pipelines/{pipelineId}")
	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{
		"pipelineId": c.pipelineId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "genomics.pipelines.get" call.
// Exactly one of *Pipeline or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Pipeline.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 *PipelinesGetCall) Do(opts ...googleapi.CallOption) (*Pipeline, 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 := &Pipeline{
		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": "Retrieves a pipeline based on ID. Caller must have READ permission to the project.",
	//   "flatPath": "v1alpha2/pipelines/{pipelineId}",
	//   "httpMethod": "GET",
	//   "id": "genomics.pipelines.get",
	//   "parameterOrder": [
	//     "pipelineId"
	//   ],
	//   "parameters": {
	//     "pipelineId": {
	//       "description": "Caller must have READ access to the project in which this pipeline is defined.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha2/pipelines/{pipelineId}",
	//   "response": {
	//     "$ref": "Pipeline"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

// method id "genomics.pipelines.getControllerConfig":

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

// GetControllerConfig: Gets controller configuration information.
// Should only be called by VMs created by the Pipelines Service and not
// by end users.
func (r *PipelinesService) GetControllerConfig() *PipelinesGetControllerConfigCall {
	c := &PipelinesGetControllerConfigCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// OperationId sets the optional parameter "operationId": The operation
// to retrieve controller configuration for.
func (c *PipelinesGetControllerConfigCall) OperationId(operationId string) *PipelinesGetControllerConfigCall {
	c.urlParams_.Set("operationId", operationId)
	return c
}

// ValidationToken sets the optional parameter "validationToken":
func (c *PipelinesGetControllerConfigCall) ValidationToken(validationToken uint64) *PipelinesGetControllerConfigCall {
	c.urlParams_.Set("validationToken", fmt.Sprint(validationToken))
	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 *PipelinesGetControllerConfigCall) Fields(s ...googleapi.Field) *PipelinesGetControllerConfigCall {
	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 *PipelinesGetControllerConfigCall) IfNoneMatch(entityTag string) *PipelinesGetControllerConfigCall {
	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 *PipelinesGetControllerConfigCall) Context(ctx context.Context) *PipelinesGetControllerConfigCall {
	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 *PipelinesGetControllerConfigCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PipelinesGetControllerConfigCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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, "v1alpha2/pipelines:getControllerConfig")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "genomics.pipelines.getControllerConfig" call.
// Exactly one of *ControllerConfig or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ControllerConfig.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 *PipelinesGetControllerConfigCall) Do(opts ...googleapi.CallOption) (*ControllerConfig, 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 := &ControllerConfig{
		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 controller configuration information. Should only be called by VMs created by the Pipelines Service and not by end users.",
	//   "flatPath": "v1alpha2/pipelines:getControllerConfig",
	//   "httpMethod": "GET",
	//   "id": "genomics.pipelines.getControllerConfig",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "operationId": {
	//       "description": "The operation to retrieve controller configuration for.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "validationToken": {
	//       "format": "uint64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha2/pipelines:getControllerConfig",
	//   "response": {
	//     "$ref": "ControllerConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

// method id "genomics.pipelines.list":

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

// List: Lists pipelines. Caller must have READ permission to the
// project.
func (r *PipelinesService) List() *PipelinesListCall {
	c := &PipelinesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// NamePrefix sets the optional parameter "namePrefix": Pipelines with
// names that match this prefix should be returned. If unspecified, all
// pipelines in the project, up to `pageSize`, will be returned.
func (c *PipelinesListCall) NamePrefix(namePrefix string) *PipelinesListCall {
	c.urlParams_.Set("namePrefix", namePrefix)
	return c
}

// PageSize sets the optional parameter "pageSize": Number of pipelines
// to return at once. Defaults to 256, and max is 2048.
func (c *PipelinesListCall) PageSize(pageSize int64) *PipelinesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to use to
// indicate where to start getting results. If unspecified, returns the
// first page of results.
func (c *PipelinesListCall) PageToken(pageToken string) *PipelinesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ProjectId sets the optional parameter "projectId": Required. The name
// of the project to search for pipelines. Caller must have READ access
// to this project.
func (c *PipelinesListCall) ProjectId(projectId string) *PipelinesListCall {
	c.urlParams_.Set("projectId", projectId)
	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 *PipelinesListCall) Fields(s ...googleapi.Field) *PipelinesListCall {
	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 *PipelinesListCall) IfNoneMatch(entityTag string) *PipelinesListCall {
	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 *PipelinesListCall) Context(ctx context.Context) *PipelinesListCall {
	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 *PipelinesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PipelinesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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, "v1alpha2/pipelines")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "genomics.pipelines.list" call.
// Exactly one of *ListPipelinesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListPipelinesResponse.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 *PipelinesListCall) Do(opts ...googleapi.CallOption) (*ListPipelinesResponse, 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 := &ListPipelinesResponse{
		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 pipelines. Caller must have READ permission to the project.",
	//   "flatPath": "v1alpha2/pipelines",
	//   "httpMethod": "GET",
	//   "id": "genomics.pipelines.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "namePrefix": {
	//       "description": "Pipelines with names that match this prefix should be returned. If unspecified, all pipelines in the project, up to `pageSize`, will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Number of pipelines to return at once. Defaults to 256, and max is 2048.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to use to indicate where to start getting results. If unspecified, returns the first page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. The name of the project to search for pipelines. Caller must have READ access to this project.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha2/pipelines",
	//   "response": {
	//     "$ref": "ListPipelinesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

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

// method id "genomics.pipelines.run":

type PipelinesRunCall struct {
	s                  *Service
	runpipelinerequest *RunPipelineRequest
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Run: Runs a pipeline. If `pipelineId` is specified in the request,
// then run a saved pipeline. If `ephemeralPipeline` is specified, then
// run that pipeline once without saving a copy. The caller must have
// READ permission to the project where the pipeline is stored and WRITE
// permission to the project where the pipeline will be run, as VMs will
// be created and storage will be used. If a pipeline operation is still
// running after 6 days, it will be canceled.
func (r *PipelinesService) Run(runpipelinerequest *RunPipelineRequest) *PipelinesRunCall {
	c := &PipelinesRunCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.runpipelinerequest = runpipelinerequest
	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 *PipelinesRunCall) Fields(s ...googleapi.Field) *PipelinesRunCall {
	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 *PipelinesRunCall) Context(ctx context.Context) *PipelinesRunCall {
	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 *PipelinesRunCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PipelinesRunCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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.runpipelinerequest)
	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, "v1alpha2/pipelines:run")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "genomics.pipelines.run" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.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 *PipelinesRunCall) Do(opts ...googleapi.CallOption) (*Operation, 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 := &Operation{
		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": "Runs a pipeline. If `pipelineId` is specified in the request, then run a saved pipeline. If `ephemeralPipeline` is specified, then run that pipeline once without saving a copy. The caller must have READ permission to the project where the pipeline is stored and WRITE permission to the project where the pipeline will be run, as VMs will be created and storage will be used. If a pipeline operation is still running after 6 days, it will be canceled.",
	//   "flatPath": "v1alpha2/pipelines:run",
	//   "httpMethod": "POST",
	//   "id": "genomics.pipelines.run",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha2/pipelines:run",
	//   "request": {
	//     "$ref": "RunPipelineRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/compute",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}

// method id "genomics.pipelines.setOperationStatus":

type PipelinesSetOperationStatusCall struct {
	s                         *Service
	setoperationstatusrequest *SetOperationStatusRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// SetOperationStatus: Sets status of a given operation. Any new
// timestamps (as determined by description) are appended to
// TimestampEvents. Should only be called by VMs created by the
// Pipelines Service and not by end users.
func (r *PipelinesService) SetOperationStatus(setoperationstatusrequest *SetOperationStatusRequest) *PipelinesSetOperationStatusCall {
	c := &PipelinesSetOperationStatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.setoperationstatusrequest = setoperationstatusrequest
	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 *PipelinesSetOperationStatusCall) Fields(s ...googleapi.Field) *PipelinesSetOperationStatusCall {
	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 *PipelinesSetOperationStatusCall) Context(ctx context.Context) *PipelinesSetOperationStatusCall {
	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 *PipelinesSetOperationStatusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PipelinesSetOperationStatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201001")
	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.setoperationstatusrequest)
	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, "v1alpha2/pipelines:setOperationStatus")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "genomics.pipelines.setOperationStatus" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *PipelinesSetOperationStatusCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		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": "Sets status of a given operation. Any new timestamps (as determined by description) are appended to TimestampEvents. Should only be called by VMs created by the Pipelines Service and not by end users.",
	//   "flatPath": "v1alpha2/pipelines:setOperationStatus",
	//   "httpMethod": "PUT",
	//   "id": "genomics.pipelines.setOperationStatus",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha2/pipelines:setOperationStatus",
	//   "request": {
	//     "$ref": "SetOperationStatusRequest"
	//   },
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/genomics"
	//   ]
	// }

}
