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

// 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))
	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_m
	// ulti_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#r
	// esource
	// and
	// https://cloud.google.com/compute/docs/disks/persistent-dis
	// ks#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
	// whitelist,
	// `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&#58;
	// `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:
//
// <table>
//   <thead>
//     <tr><th>Google Cloud storage path</th><th>Local path</th></tr>
//   </thead>
//   <tbody>
//     <tr><td>file</td><td>file</td></tr>
//     <tr><td>glob</td><td>directory</td></tr>
//   </tbody>
// </table>
//
// For outputs, the direction of the copy is reversed:
//
// ```
//   gsutil cp /mnt/disk/file.txt gs://my-bucket/bar.txt
// ```
//
// Acceptable paths are:
//
// <table>
//   <thead>
//     <tr><th>Local path</th><th>Google Cloud Storage path</th></tr>
//   </thead>
//   <tbody>
//     <tr><td>file</td><td>file</td></tr>
//     <tr>
//       <td>file</td>
//       <td>directory - directory must already exist</td>
//     </tr>
//     <tr>
//       <td>glob</td>
//       <td>directory - directory will be created if it doesn't
// exist</td></tr>
//   </tbody>
// </table>
//
// 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/instanc
	// es/create).
	// 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-access#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
	// whitelist,
	// `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&#58;
//
// * `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/20200512")
	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.\nThe server makes a best effort to cancel the operation, but success is not\nguaranteed. Clients may use Operations.GetOperation\nor Operations.ListOperations\nto check whether the cancellation succeeded or the operation completed\ndespite cancellation.\nAuthorization requires the following [Google IAM](https://cloud.google.com/iam) permission\u0026#58;\n\n* `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&#58;
//
// * `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/20200512")
	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.\nClients can use this method to poll the operation result at intervals as\nrecommended by the API service.\nAuthorization requires the following [Google IAM](https://cloud.google.com/iam) permission\u0026#58;\n\n* `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&#58;
//
// * `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&#58;
//
// * createTime&#58; The time this job was created
// * events&#58; The set of event (names) that have occurred while
// running
//   the pipeline.  The &#58; operator can be used to determine if a
//   particular event has occurred.
// * error&#58; 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&#58; 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&#58;
//
// * projectId&#58; Required. Corresponds to
//   OperationMetadata.projectId.
// * createTime&#58; The time this job was created, in seconds from the
//   [epoch](http://en.wikipedia.org/wiki/Unix_time). Can use `>=`
// and/or `<=`
//   operators.
// * status&#58; Can be `RUNNING`, `SUCCESS`, `FAILURE`, or `CANCELED`.
// Only
//   one status may be specified.
// * labels.key where key is a label key.
//
// Examples&#58;
//
// * `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/20200512")
	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.\nAuthorization requires the following [Google IAM](https://cloud.google.com/iam) permission\u0026#58;\n\n* `genomics.operations.list`",
	//   "flatPath": "v1alpha2/operations",
	//   "httpMethod": "GET",
	//   "id": "genomics.operations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "A string for filtering Operations.\nIn v2alpha1, the following filter fields are supported\u0026#58;\n\n* createTime\u0026#58; The time this job was created\n* events\u0026#58; The set of event (names) that have occurred while running\n  the pipeline.  The \u0026#58; operator can be used to determine if a\n  particular event has occurred.\n* error\u0026#58; If the pipeline is running, this value is NULL.  Once the\n  pipeline finishes, the value is the standard Google error code.\n* labels.key or labels.\"key with space\" where key is a label key.\n* done\u0026#58; If the pipeline is running, this value is false. Once the\n  pipeline finishes, the value is true.\n\nIn v1 and v1alpha2, the following filter fields are supported\u0026#58;\n\n* projectId\u0026#58; Required. Corresponds to\n  OperationMetadata.projectId.\n* createTime\u0026#58; The time this job was created, in seconds from the\n  [epoch](http://en.wikipedia.org/wiki/Unix_time). Can use `\u003e=` and/or `\u003c=`\n  operators.\n* status\u0026#58; Can be `RUNNING`, `SUCCESS`, `FAILURE`, or `CANCELED`. Only\n  one status may be specified.\n* labels.key where key is a label key.\n\nExamples\u0026#58;\n\n* `projectId = my-project AND createTime \u003e= 1432140000`\n* `projectId = my-project AND createTime \u003e= 1432140000 AND createTime \u003c= 1432150000 AND status = RUNNING`\n* `projectId = my-project AND labels.color = *`\n* `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/20200512")
	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\nhas all fields other than `pipelineId` populated, and then returns\nthe same pipeline with `pipelineId` populated. This id can be used\nto run the pipeline.\n\nCaller 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/20200512")
	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.\n\nCaller 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\nis 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/20200512")
	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.\n\nCaller 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\nis 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/20200512")
	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\nby 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/20200512")
	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.\n\nCaller 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\nreturned.  If unspecified, all pipelines in the project, up to\n`pageSize`, will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Number of pipelines to return at once. Defaults to 256, and max\nis 2048.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to use to indicate where to start getting results.\nIf unspecified, returns the first page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. The name of the project to search for pipelines. Caller\nmust 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/20200512")
	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\nrun a saved pipeline. If `ephemeralPipeline` is specified, then run\nthat pipeline once without saving a copy.\n\nThe caller must have READ permission to the project where the pipeline\nis stored and WRITE permission to the project where the pipeline will be\nrun, as VMs will be created and storage will be used.\n\nIf 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/20200512")
	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\ndescription) are appended to TimestampEvents. Should only be called by VMs\ncreated 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"
	//   ]
	// }

}
