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

// Code generated file. DO NOT EDIT.

// Package run provides access to the Cloud Run API.
//
// For product documentation, see: https://cloud.google.com/run/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/run/v1alpha1"
//   ...
//   ctx := context.Background()
//   runService, err := run.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   runService, err := run.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, ...)
//   runService, err := run.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package run // import "google.golang.org/api/run/v1alpha1"

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

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

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

const apiId = "run:v1alpha1"
const apiName = "run"
const apiVersion = "v1alpha1"
const basePath = "https://run.googleapis.com/"

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

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

// New creates a new APIService. 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) (*APIService, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &APIService{client: client, BasePath: basePath}
	s.Namespaces = NewNamespacesService(s)
	s.Projects = NewProjectsService(s)
	return s, nil
}

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

	Namespaces *NamespacesService

	Projects *ProjectsService
}

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

func NewNamespacesService(s *APIService) *NamespacesService {
	rs := &NamespacesService{s: s}
	rs.Authorizeddomains = NewNamespacesAuthorizeddomainsService(s)
	rs.Configurations = NewNamespacesConfigurationsService(s)
	rs.Domainmappings = NewNamespacesDomainmappingsService(s)
	rs.Eventtypes = NewNamespacesEventtypesService(s)
	rs.Revisions = NewNamespacesRevisionsService(s)
	rs.Routes = NewNamespacesRoutesService(s)
	rs.Services = NewNamespacesServicesService(s)
	rs.Triggers = NewNamespacesTriggersService(s)
	return rs
}

type NamespacesService struct {
	s *APIService

	Authorizeddomains *NamespacesAuthorizeddomainsService

	Configurations *NamespacesConfigurationsService

	Domainmappings *NamespacesDomainmappingsService

	Eventtypes *NamespacesEventtypesService

	Revisions *NamespacesRevisionsService

	Routes *NamespacesRoutesService

	Services *NamespacesServicesService

	Triggers *NamespacesTriggersService
}

func NewNamespacesAuthorizeddomainsService(s *APIService) *NamespacesAuthorizeddomainsService {
	rs := &NamespacesAuthorizeddomainsService{s: s}
	return rs
}

type NamespacesAuthorizeddomainsService struct {
	s *APIService
}

func NewNamespacesConfigurationsService(s *APIService) *NamespacesConfigurationsService {
	rs := &NamespacesConfigurationsService{s: s}
	return rs
}

type NamespacesConfigurationsService struct {
	s *APIService
}

func NewNamespacesDomainmappingsService(s *APIService) *NamespacesDomainmappingsService {
	rs := &NamespacesDomainmappingsService{s: s}
	return rs
}

type NamespacesDomainmappingsService struct {
	s *APIService
}

func NewNamespacesEventtypesService(s *APIService) *NamespacesEventtypesService {
	rs := &NamespacesEventtypesService{s: s}
	return rs
}

type NamespacesEventtypesService struct {
	s *APIService
}

func NewNamespacesRevisionsService(s *APIService) *NamespacesRevisionsService {
	rs := &NamespacesRevisionsService{s: s}
	return rs
}

type NamespacesRevisionsService struct {
	s *APIService
}

func NewNamespacesRoutesService(s *APIService) *NamespacesRoutesService {
	rs := &NamespacesRoutesService{s: s}
	return rs
}

type NamespacesRoutesService struct {
	s *APIService
}

func NewNamespacesServicesService(s *APIService) *NamespacesServicesService {
	rs := &NamespacesServicesService{s: s}
	return rs
}

type NamespacesServicesService struct {
	s *APIService
}

func NewNamespacesTriggersService(s *APIService) *NamespacesTriggersService {
	rs := &NamespacesTriggersService{s: s}
	return rs
}

type NamespacesTriggersService struct {
	s *APIService
}

func NewProjectsService(s *APIService) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Locations = NewProjectsLocationsService(s)
	return rs
}

type ProjectsService struct {
	s *APIService

	Locations *ProjectsLocationsService
}

func NewProjectsLocationsService(s *APIService) *ProjectsLocationsService {
	rs := &ProjectsLocationsService{s: s}
	rs.Authorizeddomains = NewProjectsLocationsAuthorizeddomainsService(s)
	rs.Configurations = NewProjectsLocationsConfigurationsService(s)
	rs.Domainmappings = NewProjectsLocationsDomainmappingsService(s)
	rs.Eventtypes = NewProjectsLocationsEventtypesService(s)
	rs.Revisions = NewProjectsLocationsRevisionsService(s)
	rs.Routes = NewProjectsLocationsRoutesService(s)
	rs.Services = NewProjectsLocationsServicesService(s)
	rs.Triggers = NewProjectsLocationsTriggersService(s)
	return rs
}

type ProjectsLocationsService struct {
	s *APIService

	Authorizeddomains *ProjectsLocationsAuthorizeddomainsService

	Configurations *ProjectsLocationsConfigurationsService

	Domainmappings *ProjectsLocationsDomainmappingsService

	Eventtypes *ProjectsLocationsEventtypesService

	Revisions *ProjectsLocationsRevisionsService

	Routes *ProjectsLocationsRoutesService

	Services *ProjectsLocationsServicesService

	Triggers *ProjectsLocationsTriggersService
}

func NewProjectsLocationsAuthorizeddomainsService(s *APIService) *ProjectsLocationsAuthorizeddomainsService {
	rs := &ProjectsLocationsAuthorizeddomainsService{s: s}
	return rs
}

type ProjectsLocationsAuthorizeddomainsService struct {
	s *APIService
}

func NewProjectsLocationsConfigurationsService(s *APIService) *ProjectsLocationsConfigurationsService {
	rs := &ProjectsLocationsConfigurationsService{s: s}
	return rs
}

type ProjectsLocationsConfigurationsService struct {
	s *APIService
}

func NewProjectsLocationsDomainmappingsService(s *APIService) *ProjectsLocationsDomainmappingsService {
	rs := &ProjectsLocationsDomainmappingsService{s: s}
	return rs
}

type ProjectsLocationsDomainmappingsService struct {
	s *APIService
}

func NewProjectsLocationsEventtypesService(s *APIService) *ProjectsLocationsEventtypesService {
	rs := &ProjectsLocationsEventtypesService{s: s}
	return rs
}

type ProjectsLocationsEventtypesService struct {
	s *APIService
}

func NewProjectsLocationsRevisionsService(s *APIService) *ProjectsLocationsRevisionsService {
	rs := &ProjectsLocationsRevisionsService{s: s}
	return rs
}

type ProjectsLocationsRevisionsService struct {
	s *APIService
}

func NewProjectsLocationsRoutesService(s *APIService) *ProjectsLocationsRoutesService {
	rs := &ProjectsLocationsRoutesService{s: s}
	return rs
}

type ProjectsLocationsRoutesService struct {
	s *APIService
}

func NewProjectsLocationsServicesService(s *APIService) *ProjectsLocationsServicesService {
	rs := &ProjectsLocationsServicesService{s: s}
	return rs
}

type ProjectsLocationsServicesService struct {
	s *APIService
}

func NewProjectsLocationsTriggersService(s *APIService) *ProjectsLocationsTriggersService {
	rs := &ProjectsLocationsTriggersService{s: s}
	return rs
}

type ProjectsLocationsTriggersService struct {
	s *APIService
}

// Addressable: Information for connecting over HTTP(s).
type Addressable struct {
	// Hostname: Deprecated - use url instead.
	Hostname string `json:"hostname,omitempty"`

	Url string `json:"url,omitempty"`

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

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

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

// AuditConfig: Specifies the audit configuration for a service.
// The configuration determines which permission types are logged, and
// what
// identities, if any, are exempted from logging.
// An AuditConfig must have one or more AuditLogConfigs.
//
// If there are AuditConfigs for both `allServices` and a specific
// service,
// the union of the two AuditConfigs is used for that service: the
// log_types
// specified in each AuditConfig are enabled, and the exempted_members
// in each
// AuditLogConfig are exempted.
//
// Example Policy with multiple AuditConfigs:
//
//     {
//       "audit_configs": [
//         {
//           "service": "allServices"
//           "audit_log_configs": [
//             {
//               "log_type": "DATA_READ",
//               "exempted_members": [
//                 "user:jose@example.com"
//               ]
//             },
//             {
//               "log_type": "DATA_WRITE",
//             },
//             {
//               "log_type": "ADMIN_READ",
//             }
//           ]
//         },
//         {
//           "service": "sampleservice.googleapis.com"
//           "audit_log_configs": [
//             {
//               "log_type": "DATA_READ",
//             },
//             {
//               "log_type": "DATA_WRITE",
//               "exempted_members": [
//                 "user:aliya@example.com"
//               ]
//             }
//           ]
//         }
//       ]
//     }
//
// For sampleservice, this policy enables DATA_READ, DATA_WRITE and
// ADMIN_READ
// logging. It also exempts jose@example.com from DATA_READ logging,
// and
// aliya@example.com from DATA_WRITE logging.
type AuditConfig struct {
	// AuditLogConfigs: The configuration for logging of each type of
	// permission.
	AuditLogConfigs []*AuditLogConfig `json:"auditLogConfigs,omitempty"`

	// Service: Specifies a service that will be enabled for audit
	// logging.
	// For example, `storage.googleapis.com`,
	// `cloudsql.googleapis.com`.
	// `allServices` is a special value that covers all services.
	Service string `json:"service,omitempty"`

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

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

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

// AuditLogConfig: Provides the configuration for logging a type of
// permissions.
// Example:
//
//     {
//       "audit_log_configs": [
//         {
//           "log_type": "DATA_READ",
//           "exempted_members": [
//             "user:jose@example.com"
//           ]
//         },
//         {
//           "log_type": "DATA_WRITE",
//         }
//       ]
//     }
//
// This enables 'DATA_READ' and 'DATA_WRITE' logging, while
// exempting
// jose@example.com from DATA_READ logging.
type AuditLogConfig struct {
	// ExemptedMembers: Specifies the identities that do not cause logging
	// for this type of
	// permission.
	// Follows the same format of Binding.members.
	ExemptedMembers []string `json:"exemptedMembers,omitempty"`

	// LogType: The log type that this config enables.
	//
	// Possible values:
	//   "LOG_TYPE_UNSPECIFIED" - Default case. Should never be this.
	//   "ADMIN_READ" - Admin reads. Example: CloudIAM getIamPolicy
	//   "DATA_WRITE" - Data writes. Example: CloudSQL Users create
	//   "DATA_READ" - Data reads. Example: CloudSQL Users list
	LogType string `json:"logType,omitempty"`

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

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

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

// AuthorizedDomain: A domain that a user has been authorized to
// administer. To authorize use
// of a domain, verify ownership via
// [Webmaster
// Central](https://www.google.com/webmasters/verification/home).
type AuthorizedDomain struct {
	// Id: Relative name of the domain authorized for use. Example:
	// `example.com`.
	Id string `json:"id,omitempty"`

	// Name: Read only. Full path to the `AuthorizedDomain` resource in the
	// API.
	// Example: `apps/myapp/authorizedDomains/example.com`.
	Name string `json:"name,omitempty"`

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

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

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

// Binding: Associates `members` with a `role`.
type Binding struct {
	// Condition: The condition that is associated with this binding.
	// NOTE: An unsatisfied condition will not allow user access via
	// current
	// binding. Different bindings, including their conditions, are
	// examined
	// independently.
	Condition *Expr `json:"condition,omitempty"`

	// Members: Specifies the identities requesting access for a Cloud
	// Platform resource.
	// `members` can have the following values:
	//
	// * `allUsers`: A special identifier that represents anyone who is
	//    on the internet; with or without a Google account.
	//
	// * `allAuthenticatedUsers`: A special identifier that represents
	// anyone
	//    who is authenticated with a Google account or a service
	// account.
	//
	// * `user:{emailid}`: An email address that represents a specific
	// Google
	//    account. For example, `alice@example.com` .
	//
	//
	// * `serviceAccount:{emailid}`: An email address that represents a
	// service
	//    account. For example,
	// `my-other-app@appspot.gserviceaccount.com`.
	//
	// * `group:{emailid}`: An email address that represents a Google
	// group.
	//    For example, `admins@example.com`.
	//
	//
	// * `domain:{domain}`: The G Suite domain (primary) that represents all
	// the
	//    users of that domain. For example, `google.com` or
	// `example.com`.
	//
	//
	Members []string `json:"members,omitempty"`

	// Role: Role that is assigned to `members`.
	// For example, `roles/viewer`, `roles/editor`, or `roles/owner`.
	Role string `json:"role,omitempty"`

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

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

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

// Capabilities: Adds and removes POSIX capabilities from running
// containers.
type Capabilities struct {
	// Add: Added capabilities
	// +optional
	Add []string `json:"add,omitempty"`

	// Drop: Removed capabilities
	// +optional
	Drop []string `json:"drop,omitempty"`

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

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

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

// ConfigMapEnvSource: ConfigMapEnvSource selects a ConfigMap to
// populate the environment
// variables with.
//
// The contents of the target ConfigMap's Data field will represent
// the
// key-value pairs as environment variables.
type ConfigMapEnvSource struct {
	// LocalObjectReference: This field should not be used directly as it is
	// meant to be inlined
	// directly into the message. Use the "name" field instead.
	LocalObjectReference *LocalObjectReference `json:"localObjectReference,omitempty"`

	// Name: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// The ConfigMap to select from.
	Name string `json:"name,omitempty"`

	// Optional: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Specify whether the ConfigMap must be defined
	// +optional
	Optional bool `json:"optional,omitempty"`

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

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

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

// ConfigMapKeySelector: Cloud Run fully managed: not supported
//
// Cloud Run on GKE: supported
//
// Selects a key from a ConfigMap.
type ConfigMapKeySelector struct {
	// Key: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// The key to select.
	Key string `json:"key,omitempty"`

	// LocalObjectReference: This field should not be used directly as it is
	// meant to be inlined
	// directly into the message. Use the "name" field instead.
	LocalObjectReference *LocalObjectReference `json:"localObjectReference,omitempty"`

	// Name: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// The ConfigMap to select from.
	Name string `json:"name,omitempty"`

	// Optional: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// Specify whether the ConfigMap or its key must be defined
	// +optional
	Optional bool `json:"optional,omitempty"`

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

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

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

// ConfigMapVolumeSource: Adapts a ConfigMap into a volume.
// The contents of the target ConfigMap's Data field will be presented
// in a
// volume as files using the keys in the Data field as the file names,
// unless
// the items element is populated with specific mappings of keys to
// paths.
type ConfigMapVolumeSource struct {
	// DefaultMode: Mode bits to use on created files by default. Must be a
	// value between 0 and
	// 0777. Defaults to 0644. Directories within the path are not affected
	// by
	// this setting. This might be in conflict with other options that
	// affect the
	// file mode, like fsGroup, and the result can be other mode bits set.
	DefaultMode int64 `json:"defaultMode,omitempty"`

	// Items: If unspecified, each key-value pair in the Data field of the
	// referenced
	// Secret will be projected into the volume as a file whose name is
	// the
	// key and content is the value. If specified, the listed keys will
	// be
	// projected into the specified paths, and unlisted keys will not
	// be
	// present. If a key is specified which is not present in the
	// Secret,
	// the volume setup will error unless it is marked optional.
	Items []*KeyToPath `json:"items,omitempty"`

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

	// Optional: Specify whether the Secret or its keys must be defined.
	Optional bool `json:"optional,omitempty"`

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

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

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

// Configuration: Configuration represents the "floating HEAD" of a
// linear history of
// Revisions, and optionally how the containers those revisions
// reference are
// built. Users create new Revisions by updating the Configuration's
// spec. The
// "latest created" revision's name is available under status, as is the
// "latest
// ready" revision's name. See
// also:
// https://github.com/knative/serving/blob/master/docs/spec/overvie
// w.md#configuration
type Configuration struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The kind of resource, in this case always "Configuration".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Configuration, including
	// name, namespace,
	// labels, and annotations.
	Metadata *ObjectMeta `json:"metadata,omitempty"`

	// Spec: Spec holds the desired state of the Configuration (from the
	// client).
	Spec *ConfigurationSpec `json:"spec,omitempty"`

	// Status: Status communicates the observed state of the Configuration
	// (from the
	// controller).
	Status *ConfigurationStatus `json:"status,omitempty"`

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

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

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

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

// ConfigurationCondition: ConfigurationCondition defines a readiness
// condition for a Configuration.
type ConfigurationCondition struct {
	// LastTransitionTime: Last time the condition transitioned from one
	// status to another.
	// +optional
	LastTransitionTime string `json:"lastTransitionTime,omitempty"`

	// Message: Human-readable message indicating details about last
	// transition.
	// +optional
	Message string `json:"message,omitempty"`

	// Reason: One-word CamelCase reason for the condition's last
	// transition.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Severity: How to interpret failures of this condition, one of Error,
	// Warning, Info
	// +optional
	Severity string `json:"severity,omitempty"`

	// Status: Status of the condition, one of True, False, Unknown.
	Status string `json:"status,omitempty"`

	// Type: ConfigurationConditionType is used to communicate the status of
	// the
	// reconciliation process. See
	// also:
	// https://github.com/knative/serving/blob/master/docs/spec/errors.
	// md#error-conditions-and-reporting
	// Types include:"Ready"
	Type string `json:"type,omitempty"`

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

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

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

// ConfigurationSpec: ConfigurationSpec holds the desired state of the
// Configuration (from the
// client).
type ConfigurationSpec struct {
	// Generation: Deprecated and not currently populated by Cloud Run.
	// See
	// metadata.generation instead, which is the sequence number containing
	// the
	// latest generation of the desired state.
	//
	// Read-only.
	Generation int64 `json:"generation,omitempty"`

	// RevisionTemplate: RevisionTemplate holds the latest specification for
	// the Revision to
	// be stamped out. The template references the container image, and may
	// also
	// include labels and annotations that should be attached to the
	// Revision.
	// To correlate a Revision, and/or to force a Revision to be created
	// when the
	// spec doesn't otherwise change, a nonce label may be provided in
	// the
	// template metadata. For more details,
	// see:
	// https://github.com/knative/serving/blob/master/docs/client-conven
	// tions.md#associate-modifications-with-revisions
	//
	// Cloud Run does not currently support referencing a build that
	// is
	// responsible for materializing the container image from source.
	RevisionTemplate *RevisionTemplate `json:"revisionTemplate,omitempty"`

	// Template: Template holds the latest specification for the Revision to
	// be stamped out.
	Template *RevisionTemplate `json:"template,omitempty"`

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

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

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

// ConfigurationStatus: ConfigurationStatus communicates the observed
// state of the Configuration
// (from the controller).
type ConfigurationStatus struct {
	// Conditions: Conditions communicates information about
	// ongoing/complete
	// reconciliation processes that bring the "spec" inline with the
	// observed
	// state of the world.
	Conditions []*ConfigurationCondition `json:"conditions,omitempty"`

	// LatestCreatedRevisionName: LatestCreatedRevisionName is the last
	// revision that was created from this
	// Configuration. It might not be ready yet, for that
	// use
	// LatestReadyRevisionName.
	LatestCreatedRevisionName string `json:"latestCreatedRevisionName,omitempty"`

	// LatestReadyRevisionName: LatestReadyRevisionName holds the name of
	// the latest Revision stamped out
	// from this Configuration that has had its "Ready" condition become
	// "True".
	LatestReadyRevisionName string `json:"latestReadyRevisionName,omitempty"`

	// ObservedGeneration: ObservedGeneration is the 'Generation' of the
	// Configuration that
	// was last processed by the controller. The observed generation is
	// updated
	// even if the controller failed to process the spec and create the
	// Revision.
	//
	// Clients polling for completed reconciliation should poll
	// until
	// observedGeneration = metadata.generation, and the Ready condition's
	// status
	// is True or False.
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

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

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

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

// Container: A single application container.
// This specifies both the container to run, the command to run in the
// container
// and the arguments to supply to it.
// Note that additional arguments may be supplied by the system to the
// container
// at runtime.
type Container struct {
	// Args: Arguments to the entrypoint.
	// The docker image's CMD is used if this is not provided.
	// Variable references $(VAR_NAME) are expanded using the
	// container's
	// environment. If a variable cannot be resolved, the reference in the
	// input
	// string will be unchanged. The $(VAR_NAME) syntax can be escaped with
	// a
	// double $$, ie: $$(VAR_NAME). Escaped references will never be
	// expanded,
	// regardless of whether the variable exists or not.
	// Cannot be updated.
	// More
	// info:
	// https://kubernetes.io/docs/tasks/inject-data-application/define-
	// command-argument-container/#running-a-command-in-a-shell
	// +optional
	Args []string `json:"args,omitempty"`

	// Command: Entrypoint array. Not executed within a shell.
	// The docker image's ENTRYPOINT is used if this is not
	// provided.
	// Variable references $(VAR_NAME) are expanded using the
	// container's
	// environment. If a variable cannot be resolved, the reference in the
	// input
	// string will be unchanged. The $(VAR_NAME) syntax can be escaped with
	// a
	// double $$, ie: $$(VAR_NAME). Escaped references will never be
	// expanded,
	// regardless of whether the variable exists or not.
	// Cannot be updated.
	// More
	// info:
	// https://kubernetes.io/docs/tasks/inject-data-application/define-
	// command-argument-container/#running-a-command-in-a-shell
	// +optional
	Command []string `json:"command,omitempty"`

	// Env: List of environment variables to set in the container.
	// Cannot be updated.
	// +optional
	Env []*EnvVar `json:"env,omitempty"`

	// EnvFrom: List of sources to populate environment variables in the
	// container.
	// The keys defined within a source must be a C_IDENTIFIER. All invalid
	// keys
	// will be reported as an event when the container is starting. When a
	// key
	// exists in multiple sources, the value associated with the last source
	// will
	// take precedence. Values defined by an Env with a duplicate key will
	// take
	// precedence. Cannot be updated. +optional
	EnvFrom []*EnvFromSource `json:"envFrom,omitempty"`

	// Image: Docker image name.
	// More info: https://kubernetes.io/docs/concepts/containers/images
	Image string `json:"image,omitempty"`

	// ImagePullPolicy: Image pull policy.
	// One of Always, Never, IfNotPresent.
	// Defaults to Always if :latest tag is specified, or IfNotPresent
	// otherwise.
	// Cannot be updated.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/containers/images#updating-i
	// mages
	// +optional
	ImagePullPolicy string `json:"imagePullPolicy,omitempty"`

	// Lifecycle: Actions that the management system should take in response
	// to container
	// lifecycle events. Cannot be updated. +optional
	Lifecycle *Lifecycle `json:"lifecycle,omitempty"`

	// LivenessProbe: Periodic probe of container liveness.
	// Container will be restarted if the probe fails.
	// Cannot be updated.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle
	// #container-probes
	// +optional
	LivenessProbe *Probe `json:"livenessProbe,omitempty"`

	// Name: Name of the container specified as a DNS_LABEL.
	// Each container must have a unique name (DNS_LABEL).
	// Cannot be updated.
	Name string `json:"name,omitempty"`

	// Ports: List of ports to expose from the container. Exposing a port
	// here gives
	// the system additional information about the network connections
	// a
	// container uses, but is primarily informational. Not specifying a port
	// here
	// DOES NOT prevent that port from being exposed. Any port which
	// is
	// listening on the default "0.0.0.0" address inside a container will
	// be
	// accessible from the network.
	// Cannot be updated.
	// +optional
	Ports []*ContainerPort `json:"ports,omitempty"`

	// ReadinessProbe: Periodic probe of container service
	// readiness.
	// Container will be removed from service endpoints if the probe
	// fails.
	// Cannot be updated.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle
	// #container-probes
	// +optional
	ReadinessProbe *Probe `json:"readinessProbe,omitempty"`

	// Resources: Compute Resources required by this container.
	// Cannot be updated.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/storage/persistent-volumes#r
	// esources
	// +optional
	Resources *ResourceRequirements `json:"resources,omitempty"`

	// SecurityContext: Security options the pod should run with.
	// More info:
	// https://kubernetes.io/docs/concepts/policy/security-context/
	// More
	// info:
	// https://kubernetes.io/docs/tasks/configure-pod-container/securit
	// y-context/
	// +optional
	SecurityContext *SecurityContext `json:"securityContext,omitempty"`

	// Stdin: Whether this container should allocate a buffer for stdin in
	// the container
	// runtime. If this is not set, reads from stdin in the container will
	// always
	// result in EOF. Default is false. +optional
	Stdin bool `json:"stdin,omitempty"`

	// StdinOnce: Whether the container runtime should close the stdin
	// channel after it has
	// been opened by a single attach. When stdin is true the stdin stream
	// will
	// remain open across multiple attach sessions. If stdinOnce is set to
	// true,
	// stdin is opened on container start, is empty until the first
	// client
	// attaches to stdin, and then remains open and accepts data until the
	// client
	// disconnects, at which time stdin is closed and remains closed until
	// the
	// container is restarted. If this flag is false, a container processes
	// that
	// reads from stdin will never receive an EOF. Default is false
	// +optional
	StdinOnce bool `json:"stdinOnce,omitempty"`

	// TerminationMessagePath: Optional: Path at which the file to which the
	// container's termination
	// message will be written is mounted into the container's filesystem.
	// Message
	// written is intended to be brief final status, such as an assertion
	// failure
	// message. Will be truncated by the node if greater than 4096 bytes.
	// The
	// total message length across all containers will be limited to
	// 12kb.
	// Defaults to /dev/termination-log.
	// Cannot be updated.
	// +optional
	TerminationMessagePath string `json:"terminationMessagePath,omitempty"`

	// TerminationMessagePolicy: Indicate how the termination message should
	// be populated. File will use the
	// contents of terminationMessagePath to populate the container status
	// message
	// on both success and failure. FallbackToLogsOnError will use the last
	// chunk
	// of container log output if the termination message file is empty and
	// the
	// container exited with an error. The log output is limited to 2048
	// bytes or
	// 80 lines, whichever is smaller. Defaults to File. Cannot be
	// updated.
	// +optional
	TerminationMessagePolicy string `json:"terminationMessagePolicy,omitempty"`

	// Tty: Whether this container should allocate a TTY for itself, also
	// requires
	// 'stdin' to be true. Default is false. +optional
	Tty bool `json:"tty,omitempty"`

	// VolumeDevices: volumeDevices is the list of block devices to be used
	// by the container.
	// This is an alpha feature and may change in the future.
	// +optional
	VolumeDevices []*VolumeDevice `json:"volumeDevices,omitempty"`

	// VolumeMounts: Pod volumes to mount into the container's
	// filesystem.
	// Cannot be updated.
	// +optional
	VolumeMounts []*VolumeMount `json:"volumeMounts,omitempty"`

	// WorkingDir: Container's working directory.
	// If not specified, the container runtime's default will be used,
	// which
	// might be configured in the container image.
	// Cannot be updated.
	// +optional
	WorkingDir string `json:"workingDir,omitempty"`

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

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

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

// ContainerPort: ContainerPort represents a network port in a single
// container.
type ContainerPort struct {
	// ContainerPort: Number of port to expose on the pod's IP address.
	// This must be a valid port number, 0 < x < 65536.
	ContainerPort int64 `json:"containerPort,omitempty"`

	// HostIP: What host IP to bind the external port to.
	// +optional
	HostIP string `json:"hostIP,omitempty"`

	// HostPort: Number of port to expose on the host.
	// If specified, this must be a valid port number, 0 < x < 65536.
	// If HostNetwork is specified, this must match ContainerPort.
	// Most containers do not need this.
	// +optional
	HostPort int64 `json:"hostPort,omitempty"`

	// Name: If specified, this must be an IANA_SVC_NAME and unique within
	// the pod. Each
	// named port in a pod must have a unique name. Name for the port that
	// can be
	// referred to by services.
	// +optional
	Name string `json:"name,omitempty"`

	// Protocol: Protocol for port. Must be UDP or TCP.
	// Defaults to "TCP".
	// +optional
	Protocol string `json:"protocol,omitempty"`

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

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

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

// DomainMapping: Resource to hold the state and status of a user's
// domain mapping.
type DomainMapping struct {
	// ApiVersion: The API version for this call such as
	// "domains.cloudrun.com/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The kind of resource, in this case "DomainMapping".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this BuildTemplate.
	Metadata *ObjectMeta `json:"metadata,omitempty"`

	// Spec: The spec for this DomainMapping.
	Spec *DomainMappingSpec `json:"spec,omitempty"`

	// Status: The current status of the DomainMapping.
	Status *DomainMappingStatus `json:"status,omitempty"`

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

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

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

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

// DomainMappingCondition: DomainMappingCondition contains state
// information for a DomainMapping.
type DomainMappingCondition struct {
	// LastTransitionTime: Last time the condition transitioned from one
	// status to another.
	// +optional
	LastTransitionTime string `json:"lastTransitionTime,omitempty"`

	// Message: Human readable message indicating details about the current
	// status.
	// +optional
	Message string `json:"message,omitempty"`

	// Reason: One-word CamelCase reason for the condition's current
	// status.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Severity: How to interpret failures of this condition, one of Error,
	// Warning, Info
	// +optional
	Severity string `json:"severity,omitempty"`

	// Status: Status of the condition, one of True, False, Unknown.
	Status string `json:"status,omitempty"`

	// Type: Type of domain mapping condition.
	Type string `json:"type,omitempty"`

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

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

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

// DomainMappingSpec: The desired state of the Domain Mapping.
type DomainMappingSpec struct {
	// CertificateMode: The mode of the certificate.
	//
	// Possible values:
	//   "CERTIFICATE_MODE_UNSPECIFIED"
	//   "NONE" - Do not provision an HTTPS certificate.
	//   "AUTOMATIC" - Automatically provisions an HTTPS certificate via
	// LetsEncrypt.
	CertificateMode string `json:"certificateMode,omitempty"`

	// ForceOverride: If set, the mapping will override any mapping set
	// before this spec was set.
	// It is recommended that the user leaves this empty to receive an
	// error
	// warning about a potential conflict and only set it once the
	// respective UI
	// has given such a warning.
	ForceOverride bool `json:"forceOverride,omitempty"`

	// RouteName: The name of the Knative Route that this DomainMapping
	// applies to.
	// The route must exist.
	RouteName string `json:"routeName,omitempty"`

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

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

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

// DomainMappingStatus: The current state of the Domain Mapping.
type DomainMappingStatus struct {
	// Conditions: Array of observed DomainMappingConditions, indicating the
	// current state
	// of the DomainMapping.
	Conditions []*DomainMappingCondition `json:"conditions,omitempty"`

	// MappedRouteName: The name of the route that the mapping currently
	// points to.
	MappedRouteName string `json:"mappedRouteName,omitempty"`

	// ObservedGeneration: ObservedGeneration is the 'Generation' of the
	// DomainMapping that
	// was last processed by the controller.
	//
	// Clients polling for completed reconciliation should poll
	// until
	// observedGeneration = metadata.generation and the Ready condition's
	// status
	// is True or False.
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// ResourceRecords: The resource records required to configure this
	// domain mapping. These
	// records must be added to the domain's DNS configuration in order
	// to
	// serve the application via this domain mapping.
	ResourceRecords []*ResourceRecord `json:"resourceRecords,omitempty"`

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

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

func (s *DomainMappingStatus) MarshalJSON() ([]byte, error) {
	type NoMethod DomainMappingStatus
	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:"-"`
}

// EnvFromSource: EnvFromSource represents the source of a set of
// ConfigMaps
type EnvFromSource struct {
	// ConfigMapRef: The ConfigMap to select from
	// +optional
	ConfigMapRef *ConfigMapEnvSource `json:"configMapRef,omitempty"`

	// Prefix: An optional identifier to prepend to each key in the
	// ConfigMap. Must be a
	// C_IDENTIFIER. +optional
	Prefix string `json:"prefix,omitempty"`

	// SecretRef: The Secret to select from
	// +optional
	SecretRef *SecretEnvSource `json:"secretRef,omitempty"`

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

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

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

// EnvVar: EnvVar represents an environment variable present in a
// Container.
type EnvVar struct {
	// Name: Name of the environment variable. Must be a C_IDENTIFIER.
	Name string `json:"name,omitempty"`

	// Value: Variable references $(VAR_NAME) are expanded
	// using the previous defined environment variables in the container
	// and
	// any route environment variables. If a variable cannot be
	// resolved,
	// the reference in the input string will be unchanged. The
	// $(VAR_NAME)
	// syntax can be escaped with a double $$, ie: $$(VAR_NAME).
	// Escaped
	// references will never be expanded, regardless of whether the
	// variable
	// exists or not.
	// Defaults to "".
	// +optional
	Value string `json:"value,omitempty"`

	// ValueFrom: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// Source for the environment variable's value. Cannot be used if value
	// is not
	// empty. +optional
	ValueFrom *EnvVarSource `json:"valueFrom,omitempty"`

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

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

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

// EnvVarSource: Cloud Run fully managed: not supported
//
// Cloud Run on GKE: supported
//
// EnvVarSource represents a source for the value of an EnvVar.
type EnvVarSource struct {
	// ConfigMapKeyRef: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// Selects a key of a ConfigMap.
	// +optional
	ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`

	// SecretKeyRef: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// Selects a key of a secret in the pod's namespace
	// +optional
	SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty"`

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

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

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

type EventType struct {
	// ApiVersion: The API version for this call such as
	// "eventing.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The kind of resource, in this case "EventType".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this EventType.
	Metadata *ObjectMeta `json:"metadata,omitempty"`

	// Spec: Spec defines the desired state of the EventType.
	Spec *EventTypeSpec `json:"spec,omitempty"`

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

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

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

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

type EventTypeImporter struct {
	// ApiVersion: The API version of the importer CRD.
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The kind of the importer CRD.
	Kind string `json:"kind,omitempty"`

	// Parameters: Parameters required to create an importer for the
	// EventType.
	Parameters []*EventTypeParameter `json:"parameters,omitempty"`

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

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

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

type EventTypeParameter struct {
	// Description: Description of the parameter. E.g. "Google Cloud Project
	// Id."
	Description string `json:"description,omitempty"`

	// Name: Name of the parameter. E.g. googleCloudProject.
	Name string `json:"name,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 *EventTypeParameter) MarshalJSON() ([]byte, error) {
	type NoMethod EventTypeParameter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type EventTypeSpec struct {
	// Broker: Refers to the Broker that can provide the EventType.
	Broker string `json:"broker,omitempty"`

	// Description: Description is a string describing what the EventType is
	// about.
	// +optional
	Description string `json:"description,omitempty"`

	// Importer: The importer that provides this EventType to the eventing
	// mesh.
	Importer *EventTypeImporter `json:"importer,omitempty"`

	// Schema: Schema is a URI with the EventType schema. It may be a JSON
	// schema, a
	// protobuf schema, etc.
	// +optional
	Schema string `json:"schema,omitempty"`

	// Source: Source is a valid URI. Refers to the CloudEvent source as it
	// enters into
	// the eventing mesh.
	Source string `json:"source,omitempty"`

	// Type: Type is authoritative. This refers to the CloudEvent type as it
	// enters
	// into the eventing mesh.
	Type string `json:"type,omitempty"`

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

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

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

// ExecAction: ExecAction describes a "run in container" action.
type ExecAction struct {
	// Command: Command is the command line to execute inside the container,
	// the working
	// directory for the command  is root ('/') in the container's
	// filesystem. The
	// command is simply exec'd, it is not run inside a shell, so
	// traditional
	// shell instructions ('|', etc) won't work. To use a shell, you need
	// to
	// explicitly call out to that shell. Exit status of 0 is treated
	// as
	// live/healthy and non-zero is unhealthy. +optional
	Command string `json:"command,omitempty"`

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

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

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

// Expr: Represents an expression text. Example:
//
//     title: "User account presence"
//     description: "Determines whether the request has a user account"
//     expression: "size(request.user) > 0"
type Expr struct {
	// Description: An optional description of the expression. This is a
	// longer text which
	// describes the expression, e.g. when hovered over it in a UI.
	Description string `json:"description,omitempty"`

	// Expression: Textual representation of an expression in
	// Common Expression Language syntax.
	//
	// The application context of the containing message determines
	// which
	// well-known feature set of CEL is supported.
	Expression string `json:"expression,omitempty"`

	// Location: An optional string indicating the location of the
	// expression for error
	// reporting, e.g. a file name and a position in the file.
	Location string `json:"location,omitempty"`

	// Title: An optional title for the expression, i.e. a short string
	// describing
	// its purpose. This can be used e.g. in UIs which allow to enter
	// the
	// expression.
	Title string `json:"title,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 *Expr) MarshalJSON() ([]byte, error) {
	type NoMethod Expr
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HTTPGetAction: HTTPGetAction describes an action based on HTTP Get
// requests.
type HTTPGetAction struct {
	// Host: Host name to connect to, defaults to the pod IP. You probably
	// want to set
	// "Host" in httpHeaders instead.
	// +optional
	Host string `json:"host,omitempty"`

	// HttpHeaders: Custom headers to set in the request. HTTP allows
	// repeated headers.
	// +optional
	HttpHeaders []*HTTPHeader `json:"httpHeaders,omitempty"`

	// Path: Path to access on the HTTP server.
	// +optional
	Path string `json:"path,omitempty"`

	// Port: Name or number of the port to access on the container.
	// Number must be in the range 1 to 65535.
	// Name must be an IANA_SVC_NAME.
	Port *IntOrString `json:"port,omitempty"`

	// Scheme: Scheme to use for connecting to the host.
	// Defaults to HTTP.
	// +optional
	Scheme string `json:"scheme,omitempty"`

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

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

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

// HTTPHeader: HTTPHeader describes a custom header to be used in HTTP
// probes
type HTTPHeader struct {
	// Name: The header field name
	Name string `json:"name,omitempty"`

	// Value: The header field value
	Value string `json:"value,omitempty"`

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

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

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

// Handler: Handler defines a specific action that should be taken
type Handler struct {
	// Exec: One and only one of the following should be specified.
	// Exec specifies the action to take.
	// +optional
	Exec *ExecAction `json:"exec,omitempty"`

	// HttpGet: HTTPGet specifies the http request to perform.
	// +optional
	HttpGet *HTTPGetAction `json:"httpGet,omitempty"`

	// TcpSocket: TCPSocket specifies an action involving a TCP port.
	// TCP hooks not yet supported
	TcpSocket *TCPSocketAction `json:"tcpSocket,omitempty"`

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

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

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

// Initializer: Initializer is information about an initializer that has
// not yet completed.
type Initializer struct {
	// Name: name of the process that is responsible for initializing this
	// object.
	Name string `json:"name,omitempty"`

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

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

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

// Initializers: Initializers tracks the progress of initialization.
type Initializers struct {
	// Pending: Pending is a list of initializers that must execute in order
	// before this
	// object is visible. When the last pending initializer is removed, and
	// no
	// failing result is set, the initializers struct will be set to nil and
	// the
	// object is considered as initialized and visible to all
	// clients.
	// +patchMergeKey=name
	// +patchStrategy=merge
	Pending []*Initializer `json:"pending,omitempty"`

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

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

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

// IntOrString: IntOrString is a type that can hold an int32 or a
// string.  When used in
// JSON or YAML marshalling and unmarshalling, it produces or consumes
// the
// inner type.  This allows you to have, for example, a JSON field that
// can
// accept a name or number.
type IntOrString struct {
	// IntVal: The int value.
	IntVal int64 `json:"intVal,omitempty"`

	// StrVal: The string value.
	StrVal string `json:"strVal,omitempty"`

	// Type: The type of the value.
	Type int64 `json:"type,omitempty"`

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

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

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

// KeyToPath: Maps a string key to a path within a volume.
type KeyToPath struct {
	// Key: The key to project.
	Key string `json:"key,omitempty"`

	// Mode: Mode bits to use on this file, must be a value between 0 and
	// 0777. If not
	// specified, the volume defaultMode will be used. This might be in
	// conflict
	// with other options that affect the file mode, like fsGroup, and the
	// result
	// can be other mode bits set. +optional
	Mode int64 `json:"mode,omitempty"`

	// Path: The relative path of the file to map the key to.
	// May not be an absolute path.
	// May not contain the path element '..'.
	// May not start with the string '..'.
	Path string `json:"path,omitempty"`

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

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

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

// Lifecycle: Lifecycle describes actions that the management system
// should take in
// response to container lifecycle events. For the PostStart and
// PreStop
// lifecycle handlers, management of the container blocks until the
// action is
// complete, unless the container process fails, in which case the
// handler is
// aborted.
type Lifecycle struct {
	// PostStart: PostStart is called immediately after a container is
	// created. If the
	// handler fails, the container is terminated and restarted according to
	// its
	// restart policy. Other management of the container blocks until the
	// hook
	// completes. More
	// info:
	// https://kubernetes.io/docs/concepts/containers/container-lifecyc
	// le-hooks/#container-hooks
	// +optional
	PostStart *Handler `json:"postStart,omitempty"`

	// PreStop: PreStop is called immediately before a container is
	// terminated.
	// The container is terminated after the handler completes.
	// The reason for termination is passed to the handler.
	// Regardless of the outcome of the handler, the container is
	// eventually
	// terminated. Other management of the container blocks until the
	// hook
	// completes. More
	// info:
	// https://kubernetes.io/docs/concepts/containers/container-lifecyc
	// le-hooks/#container-hooks
	// +optional
	PreStop *Handler `json:"preStop,omitempty"`

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

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

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

// ListAuthorizedDomainsResponse: A list of Authorized Domains.
type ListAuthorizedDomainsResponse struct {
	// Domains: The authorized domains belonging to the user.
	Domains []*AuthorizedDomain `json:"domains,omitempty"`

	// NextPageToken: Continuation token for fetching the next page of
	// results.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// ListConfigurationsResponse: ListConfigurationsResponse is a list of
// Configuration resources.
type ListConfigurationsResponse struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Items: List of Configurations.
	Items []*Configuration `json:"items,omitempty"`

	// Kind: The kind of this resource, in this case "ConfigurationList".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Configuration list.
	Metadata *ListMeta `json:"metadata,omitempty"`

	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

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

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

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

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

// ListDomainMappingsResponse: ListDomainMappingsResponse is a list of
// DomainMapping resources.
type ListDomainMappingsResponse struct {
	// ApiVersion: The API version for this call such as
	// "domains.cloudrun.com/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Items: List of DomainMappings.
	Items []*DomainMapping `json:"items,omitempty"`

	// Kind: The kind of this resource, in this case "DomainMappingList".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this DomainMapping list.
	Metadata *ListMeta `json:"metadata,omitempty"`

	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

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

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

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

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

// ListEventTypesResponse: ListEventTypesResponse is a list of EventType
// resources.
type ListEventTypesResponse struct {
	// ApiVersion: The API version for this call such as
	// "eventing.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Items: List of EventTypes.
	Items []*EventType `json:"items,omitempty"`

	// Kind: The kind of this resource, in this case "EventTypeList".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this EventType list.
	Metadata *ListMeta `json:"metadata,omitempty"`

	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

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

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

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

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

// ListLocationsResponse: The response message for
// Locations.ListLocations.
type ListLocationsResponse struct {
	// Locations: A list of locations that matches the specified filter in
	// the request.
	Locations []*Location `json:"locations,omitempty"`

	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// ListMeta: ListMeta describes metadata that synthetic resources must
// have, including
// lists and various status objects. A resource may have only one
// of
// {ObjectMeta, ListMeta}.
type ListMeta struct {
	// Continue: continue may be set if the user set a limit on the number
	// of items
	// returned, and indicates that the server has more data available. The
	// value
	// is opaque and may be used to issue another request to the endpoint
	// that
	// served this list to retrieve the next set of available objects.
	// Continuing
	// a list may not be possible if the server configuration has changed or
	// more
	// than a few minutes have passed. The resourceVersion field returned
	// when
	// using this continue value will be identical to the value in the
	// first
	// response.
	Continue string `json:"continue,omitempty"`

	// ResourceVersion: String that identifies the server's internal version
	// of this object that
	// can be used by clients to determine when objects have changed. Value
	// must
	// be treated as opaque by clients and passed unmodified back to the
	// server.
	// Populated by the system.
	// Read-only.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#concurrency-control-and-consistency
	// +optional
	ResourceVersion string `json:"resourceVersion,omitempty"`

	// SelfLink: SelfLink is a URL representing this object.
	// Populated by the system.
	// Read-only.
	// +optional
	SelfLink string `json:"selfLink,omitempty"`

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

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

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

// ListRevisionsResponse: ListRevisionsResponse is a list of Revision
// resources.
type ListRevisionsResponse struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Items: List of Revisions.
	Items []*Revision `json:"items,omitempty"`

	// Kind: The kind of this resource, in this case "RevisionList".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this revision list.
	Metadata *ListMeta `json:"metadata,omitempty"`

	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

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

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

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

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

// ListRoutesResponse: ListRoutesResponse is a list of Route resources.
type ListRoutesResponse struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Items: List of Routes.
	Items []*Route `json:"items,omitempty"`

	// Kind: The kind of this resource, in this case always "RouteList".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Route list.
	Metadata *ListMeta `json:"metadata,omitempty"`

	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

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

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

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

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

// ListServicesResponse: A list of Service resources.
type ListServicesResponse struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Items: List of Services.
	Items []*Service `json:"items,omitempty"`

	// Kind: The kind of this resource, in this case "ServiceList".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Service list.
	Metadata *ListMeta `json:"metadata,omitempty"`

	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

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

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

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

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

// ListTriggersResponse: ListTriggersResponse is a list of Trigger
// resources.
type ListTriggersResponse struct {
	// ApiVersion: The API version for this call such as
	// "eventing.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Items: List of Triggers.
	Items []*Trigger `json:"items,omitempty"`

	// Kind: The kind of this resource, in this case "TriggerList".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Trigger list.
	Metadata *ListMeta `json:"metadata,omitempty"`

	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

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

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

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

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

// LocalObjectReference: LocalObjectReference contains enough
// information to let you locate the
// referenced object inside the same namespace.
type LocalObjectReference struct {
	// Name: Name of the referent.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/overview/working-with-object
	// s/names/#names
	Name string `json:"name,omitempty"`

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

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

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

// Location: A resource that represents Google Cloud Platform location.
type Location struct {
	// DisplayName: The friendly name for this location, typically a nearby
	// city name.
	// For example, "Tokyo".
	DisplayName string `json:"displayName,omitempty"`

	// Labels: Cross-service attributes for the location. For example
	//
	//     {"cloud.googleapis.com/region": "us-east1"}
	Labels map[string]string `json:"labels,omitempty"`

	// LocationId: The canonical id for this location. For example:
	// "us-east1".
	LocationId string `json:"locationId,omitempty"`

	// Metadata: Service-specific metadata. For example the available
	// capacity at the given
	// location.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: Resource name for the location, which may vary between
	// implementations.
	// For example: "projects/example-project/locations/us-east1"
	Name string `json:"name,omitempty"`

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

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

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

// ObjectMeta: ObjectMeta is metadata that all persisted resources must
// have, which includes
// all objects users must create.
type ObjectMeta struct {
	// Annotations: Annotations is an unstructured key value map stored with
	// a resource that
	// may be set by external tools to store and retrieve arbitrary
	// metadata. They
	// are not queryable and should be preserved when modifying objects.
	// More
	// info: http://kubernetes.io/docs/user-guide/annotations +optional
	Annotations map[string]string `json:"annotations,omitempty"`

	// ClusterName: Not currently supported by Cloud Run.
	//
	// The name of the cluster which the object belongs to.
	// This is used to distinguish resources with same name and namespace
	// in
	// different clusters. This field is not set anywhere right now and
	// apiserver
	// is going to ignore it if set in create or update request. +optional
	ClusterName string `json:"clusterName,omitempty"`

	// CreationTimestamp: CreationTimestamp is a timestamp representing the
	// server time when this
	// object was created. It is not guaranteed to be set in happens-before
	// order
	// across separate operations. Clients may not set this value. It
	// is
	// represented in RFC3339 form and is in UTC.
	//
	// Populated by the system.
	// Read-only.
	// Null for lists.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#metadata
	// +optional
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// DeletionGracePeriodSeconds: Not currently supported by Cloud
	// Run.
	//
	// Number of seconds allowed for this object to gracefully terminate
	// before
	// it will be removed from the system. Only set when deletionTimestamp
	// is also
	// set. May only be shortened. Read-only. +optional
	DeletionGracePeriodSeconds int64 `json:"deletionGracePeriodSeconds,omitempty"`

	// DeletionTimestamp: DeletionTimestamp is RFC 3339 date and time at
	// which this resource will be
	// deleted. This field is set by the server when a graceful deletion
	// is
	// requested by the user, and is not directly settable by a client.
	// The
	// resource is expected to be deleted (no longer visible from resource
	// lists,
	// and not reachable by name) after the time in this field, once
	// the
	// finalizers list is empty. As long as the finalizers list contains
	// items,
	// deletion is blocked. Once the deletionTimestamp is set, this value
	// may not
	// be unset or be set further into the future, although it may be
	// shortened or
	// the resource may be deleted prior to this time. For example, a user
	// may
	// request that a pod is deleted in 30 seconds. The Kubelet will react
	// by
	// sending a graceful termination signal to the containers in the pod.
	// After
	// that 30 seconds, the Kubelet will send a hard termination signal
	// (SIGKILL)
	// to the container and after cleanup, remove the pod from the API. In
	// the
	// presence of network partitions, this object may still exist after
	// this
	// timestamp, until an administrator or automated process can determine
	// the
	// resource is fully terminated.
	// If not set, graceful deletion of the object has not been
	// requested.
	//
	// Populated by the system when a graceful deletion is
	// requested.
	// Read-only.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#metadata
	// +optional
	DeletionTimestamp string `json:"deletionTimestamp,omitempty"`

	// Finalizers: Not currently supported by Cloud Run.
	//
	// Must be empty before the object is deleted from the registry. Each
	// entry
	// is an identifier for the responsible component that will remove the
	// entry
	// from the list. If the deletionTimestamp of the object is non-nil,
	// entries
	// in this list can only be removed.
	// +optional
	// +patchStrategy=merge
	Finalizers []string `json:"finalizers,omitempty"`

	// GenerateName: Not currently supported by Cloud Run.
	//
	// GenerateName is an optional prefix, used by the server, to generate
	// a
	// unique name ONLY IF the Name field has not been provided. If this
	// field is
	// used, the name returned to the client will be different than the
	// name
	// passed. This value will also be combined with a unique suffix. The
	// provided
	// value has the same validation rules as the Name field, and may be
	// truncated
	// by the length of the suffix required to make the value unique on
	// the
	// server.
	//
	// If this field is specified and the generated name exists, the server
	// will
	// NOT return a 409 - instead, it will either return 201 Created or 500
	// with
	// Reason ServerTimeout indicating a unique name could not be found in
	// the
	// time allotted, and the client should retry (optionally after the
	// time
	// indicated in the Retry-After header).
	//
	// Applied only if Name is not specified.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#idempotency
	// +optional
	//  string generateName = 2;
	GenerateName string `json:"generateName,omitempty"`

	// Generation: A sequence number representing a specific generation of
	// the desired state.
	// Populated by the system. Read-only.
	// +optional
	Generation int64 `json:"generation,omitempty"`

	// Initializers: Not currently supported by Cloud Run.
	//
	// An initializer is a controller which enforces some system invariant
	// at
	// object creation time. This field is a list of initializers that have
	// not
	// yet acted on this object. If nil or empty, this object has been
	// completely
	// initialized. Otherwise, the object is considered uninitialized and
	// is
	// hidden (in list/watch and get calls) from clients that haven't
	// explicitly
	// asked to observe uninitialized objects.
	//
	// When an object is created, the system will populate this list with
	// the
	// current set of initializers. Only privileged users may set or modify
	// this
	// list. Once it is empty, it may not be modified further by any user.
	Initializers *Initializers `json:"initializers,omitempty"`

	// Labels: Map of string keys and values that can be used to organize
	// and categorize
	// (scope and select) objects. May match selectors of replication
	// controllers
	// and routes.
	// More info: http://kubernetes.io/docs/user-guide/labels
	// +optional
	Labels map[string]string `json:"labels,omitempty"`

	// Name: Name must be unique within a namespace, within a Cloud Run
	// region.
	// Is required when creating
	// resources, although some resources may allow a client to request
	// the
	// generation of an appropriate name automatically. Name is primarily
	// intended
	// for creation idempotence and configuration definition. Cannot be
	// updated.
	// More info:
	// http://kubernetes.io/docs/user-guide/identifiers#names
	// +optional
	Name string `json:"name,omitempty"`

	// Namespace: Namespace defines the space within each name must be
	// unique, within a
	// Cloud Run region. In Cloud Run the namespace must be equal to either
	// the
	// project ID or project number.
	Namespace string `json:"namespace,omitempty"`

	// OwnerReferences: List of objects that own this object. If ALL objects
	// in the list have
	// been deleted, this object will be garbage collected.
	// +optional
	OwnerReferences []*OwnerReference `json:"ownerReferences,omitempty"`

	// ResourceVersion: An opaque value that represents the internal version
	// of this object that
	// can be used by clients to determine when objects have changed. May be
	// used
	// for optimistic concurrency, change detection, and the watch operation
	// on a
	// resource or set of resources. Clients must treat these values as
	// opaque and
	// passed unmodified back to the server. They may only be valid for
	// a
	// particular resource or set of resources.
	//
	// Populated by the system.
	// Read-only.
	// Value must be treated as opaque by clients and .
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#concurrency-control-and-consistency
	// +optional
	ResourceVersion string `json:"resourceVersion,omitempty"`

	// SelfLink: SelfLink is a URL representing this object.
	// Populated by the system.
	// Read-only.
	// +optional
	//  string selfLink = 4;
	SelfLink string `json:"selfLink,omitempty"`

	// Uid: UID is the unique in time and space value for this object. It is
	// typically
	// generated by the server on successful creation of a resource and is
	// not
	// allowed to change on PUT operations.
	//
	// Populated by the system.
	// Read-only.
	// More info:
	// http://kubernetes.io/docs/user-guide/identifiers#uids
	// +optional
	Uid string `json:"uid,omitempty"`

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

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

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

// ObjectReference: ObjectReference contains enough information to let
// you inspect or modify the
// referred object.
type ObjectReference struct {
	// ApiVersion: API version of the referent.
	// +optional
	ApiVersion string `json:"apiVersion,omitempty"`

	// FieldPath: If referring to a piece of an object instead of an entire
	// object, this
	// string should contain a valid JSON/Go field access statement, such
	// as
	// desiredState.manifest.containers[2]. For example, if the object
	// reference
	// is to a container within a pod, this would take on a value
	// like:
	// "spec.containers{name}" (where "name" refers to the name of the
	// container
	// that triggered the event) or if no container name is
	// specified
	// "spec.containers[2]" (container with index 2 in this pod). This
	// syntax is
	// chosen only to have some well-defined way of referencing a part of
	// an
	// object.
	FieldPath string `json:"fieldPath,omitempty"`

	// Kind: Kind of the referent.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#types-kinds
	// +optional
	Kind string `json:"kind,omitempty"`

	// Name: Name of the referent.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/overview/working-with-object
	// s/names/#names
	// +optional
	Name string `json:"name,omitempty"`

	// Namespace: Namespace of the referent.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/overview/working-with-object
	// s/namespaces/
	// +optional
	Namespace string `json:"namespace,omitempty"`

	// ResourceVersion: Specific resourceVersion to which this reference is
	// made, if any.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#concurrency-control-and-consistency
	// +optional
	ResourceVersion string `json:"resourceVersion,omitempty"`

	// Uid: UID of the referent.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/overview/working-with-object
	// s/names/#uids
	// +optional
	Uid string `json:"uid,omitempty"`

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

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

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

// OwnerReference: OwnerReference contains enough information to let you
// identify an owning
// object. Currently, an owning object must be in the same namespace, so
// there
// is no namespace field.
type OwnerReference struct {
	// ApiVersion: API version of the referent.
	ApiVersion string `json:"apiVersion,omitempty"`

	// BlockOwnerDeletion: If true, AND if the owner has the
	// "foregroundDeletion" finalizer, then
	// the owner cannot be deleted from the key-value store until
	// this
	// reference is removed.
	// Defaults to false.
	// To set this field, a user needs "delete" permission of the
	// owner,
	// otherwise 422 (Unprocessable Entity) will be returned.
	// +optional
	BlockOwnerDeletion bool `json:"blockOwnerDeletion,omitempty"`

	// Controller: If true, this reference points to the managing
	// controller.
	// +optional
	Controller bool `json:"controller,omitempty"`

	// Kind: Kind of the referent.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#types-kinds
	Kind string `json:"kind,omitempty"`

	// Name: Name of the referent.
	// More info: http://kubernetes.io/docs/user-guide/identifiers#names
	Name string `json:"name,omitempty"`

	// Uid: UID of the referent.
	// More info: http://kubernetes.io/docs/user-guide/identifiers#uids
	Uid string `json:"uid,omitempty"`

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

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

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

// Policy: Defines an Identity and Access Management (IAM) policy. It is
// used to
// specify access control policies for Cloud Platform resources.
//
//
// A `Policy` is a collection of `bindings`. A `binding` binds one or
// more
// `members` to a single `role`. Members can be user accounts, service
// accounts,
// Google groups, and domains (such as G Suite). A `role` is a named
// list of
// permissions (defined by IAM or configured by users). A `binding`
// can
// optionally specify a `condition`, which is a logic expression that
// further
// constrains the role binding based on attributes about the request
// and/or
// target resource.
//
// **JSON Example**
//
//     {
//       "bindings": [
//         {
//           "role": "roles/resourcemanager.organizationAdmin",
//           "members": [
//             "user:mike@example.com",
//             "group:admins@example.com",
//             "domain:google.com",
//
// "serviceAccount:my-project-id@appspot.gserviceaccount.com"
//           ]
//         },
//         {
//           "role": "roles/resourcemanager.organizationViewer",
//           "members": ["user:eve@example.com"],
//           "condition": {
//             "title": "expirable access",
//             "description": "Does not grant access after Sep 2020",
//             "expression": "request.time <
//             timestamp('2020-10-01T00:00:00.000Z')",
//           }
//         }
//       ]
//     }
//
// **YAML Example**
//
//     bindings:
//     - members:
//       - user:mike@example.com
//       - group:admins@example.com
//       - domain:google.com
//       - serviceAccount:my-project-id@appspot.gserviceaccount.com
//       role: roles/resourcemanager.organizationAdmin
//     - members:
//       - user:eve@example.com
//       role: roles/resourcemanager.organizationViewer
//       condition:
//         title: expirable access
//         description: Does not grant access after Sep 2020
//         expression: request.time <
// timestamp('2020-10-01T00:00:00.000Z')
//
// For a description of IAM and its features, see the
// [IAM developer's guide](https://cloud.google.com/iam/docs).
type Policy struct {
	// AuditConfigs: Specifies cloud audit logging configuration for this
	// policy.
	AuditConfigs []*AuditConfig `json:"auditConfigs,omitempty"`

	// Bindings: Associates a list of `members` to a `role`. Optionally may
	// specify a
	// `condition` that determines when binding is in effect.
	// `bindings` with no members will result in an error.
	Bindings []*Binding `json:"bindings,omitempty"`

	// Etag: `etag` is used for optimistic concurrency control as a way to
	// help
	// prevent simultaneous updates of a policy from overwriting each
	// other.
	// It is strongly suggested that systems make use of the `etag` in
	// the
	// read-modify-write cycle to perform policy updates in order to avoid
	// race
	// conditions: An `etag` is returned in the response to `getIamPolicy`,
	// and
	// systems are expected to put that etag in the request to
	// `setIamPolicy` to
	// ensure that their change will be applied to the same version of the
	// policy.
	//
	// If no `etag` is provided in the call to `setIamPolicy`, then the
	// existing
	// policy is overwritten. Due to blind-set semantics of an etag-less
	// policy,
	// 'setIamPolicy' will not fail even if either of incoming or stored
	// policy
	// does not meet the version requirements.
	Etag string `json:"etag,omitempty"`

	// Version: Specifies the format of the policy.
	//
	// Valid values are 0, 1, and 3. Requests specifying an invalid value
	// will be
	// rejected.
	//
	// Operations affecting conditional bindings must specify version 3.
	// This can
	// be either setting a conditional policy, modifying a conditional
	// binding,
	// or removing a conditional binding from the stored conditional
	// policy.
	// Operations on non-conditional policies may specify any valid value
	// or
	// leave the field unset.
	//
	// If no etag is provided in the call to `setIamPolicy`, any
	// version
	// compliance checks on the incoming and/or stored policy is skipped.
	Version int64 `json:"version,omitempty"`

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

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

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

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

// Probe: Probe describes a health check to be performed against a
// container to
// determine whether it is alive or ready to receive traffic.
type Probe struct {
	// FailureThreshold: Minimum consecutive failures for the probe to be
	// considered failed after
	// having succeeded. Defaults to 3. Minimum value is 1. +optional
	FailureThreshold int64 `json:"failureThreshold,omitempty"`

	// Handler: The action taken to determine the health of a container
	Handler *Handler `json:"handler,omitempty"`

	// InitialDelaySeconds: Number of seconds after the container has
	// started before liveness probes
	// are initiated. More
	// info:
	// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle
	// #container-probes
	// +optional
	InitialDelaySeconds int64 `json:"initialDelaySeconds,omitempty"`

	// PeriodSeconds: How often (in seconds) to perform the probe.
	// Default to 10 seconds. Minimum value is 1.
	// +optional
	PeriodSeconds int64 `json:"periodSeconds,omitempty"`

	// SuccessThreshold: Minimum consecutive successes for the probe to be
	// considered successful
	// after having failed. Defaults to 1. Must be 1 for liveness. Minimum
	// value
	// is 1. +optional
	SuccessThreshold int64 `json:"successThreshold,omitempty"`

	// TimeoutSeconds: Number of seconds after which the probe times
	// out.
	// Defaults to 1 second. Minimum value is 1.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle
	// #container-probes
	// +optional
	TimeoutSeconds int64 `json:"timeoutSeconds,omitempty"`

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

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

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

// Quantity: The view model of a single quantity, e.g. "800 MiB".
// Corresponds
// to
// https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8
// s.io/apimachinery/pkg/api/resource/generated.proto
type Quantity struct {
	// String: Stringified version of the quantity, e.g., "800 MiB".
	String string `json:"string,omitempty"`

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

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

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

// ResourceRecord: A DNS resource record.
type ResourceRecord struct {
	// Name: Relative name of the object affected by this record. Only
	// applicable for
	// `CNAME` records. Example: 'www'.
	Name string `json:"name,omitempty"`

	// Rrdata: Data for this record. Values vary by record type, as defined
	// in RFC 1035
	// (section 5) and RFC 1034 (section 3.6.1).
	Rrdata string `json:"rrdata,omitempty"`

	// Type: Resource record type. Example: `AAAA`.
	//
	// Possible values:
	//   "RECORD_TYPE_UNSPECIFIED" - An unknown resource record.
	//   "A" - An A resource record. Data is an IPv4 address.
	//   "AAAA" - An AAAA resource record. Data is an IPv6 address.
	//   "CNAME" - A CNAME resource record. Data is a domain name to be
	// aliased.
	Type string `json:"type,omitempty"`

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

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

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

// ResourceRequirements: ResourceRequirements describes the compute
// resource requirements.
type ResourceRequirements struct {
	// Limits: Limits describes the maximum amount of compute resources
	// allowed.
	// The values of the map is string form of the 'quantity' k8s
	// type:
	// https://github.com/kubernetes/kubernetes/blob/master/staging/src
	// /k8s.io/apimachinery/pkg/api/resource/quantity.go
	Limits map[string]string `json:"limits,omitempty"`

	// LimitsInMap: Limits describes the maximum amount of compute resources
	// allowed.
	// This is a temporary field created to migrate away from
	// the
	// map<string, Quantity> limits field. This is done to become
	// compliant
	// with k8s style API.
	// This field is deprecated in favor of limits field.
	LimitsInMap map[string]Quantity `json:"limitsInMap,omitempty"`

	// Requests: Requests describes the minimum amount of compute resources
	// required.
	// If Requests is omitted for a container, it defaults to Limits if that
	// is
	// explicitly specified, otherwise to an implementation-defined
	// value.
	// The values of the map is string form of the 'quantity' k8s
	// type:
	// https://github.com/kubernetes/kubernetes/blob/master/staging/src
	// /k8s.io/apimachinery/pkg/api/resource/quantity.go
	Requests map[string]string `json:"requests,omitempty"`

	// RequestsInMap: Requests describes the minimum amount of compute
	// resources required.
	// If Requests is omitted for a container, it defaults to Limits if that
	// is
	// explicitly specified, otherwise to an implementation-defined
	// value.
	// This is a temporary field created to migrate away from
	// the
	// map<string, Quantity> requests field. This is done to become
	// compliant
	// with k8s style API.
	// This field is deprecated in favor of requests field.
	RequestsInMap map[string]Quantity `json:"requestsInMap,omitempty"`

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

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

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

// Revision: Revision is an immutable snapshot of code and
// configuration.  A revision
// references a container image. Revisions are created by updates to
// a
// Configuration.
//
// Cloud Run does not currently support referencing a build that is
// responsible
// for materializing the container image from source.
//
// See
// also:
// https://github.com/knative/serving/blob/master/docs/spec/overvie
// w.md#revision
type Revision struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The kind of this resource, in this case "Revision".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Revision, including name,
	// namespace, labels,
	// and annotations.
	Metadata *ObjectMeta `json:"metadata,omitempty"`

	// Spec: Spec holds the desired state of the Revision (from the client).
	Spec *RevisionSpec `json:"spec,omitempty"`

	// Status: Status communicates the observed state of the Revision (from
	// the
	// controller).
	Status *RevisionStatus `json:"status,omitempty"`

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

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

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

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

// RevisionCondition: RevisionCondition defines a readiness condition
// for a Revision.
type RevisionCondition struct {
	// LastTransitionTime: Last time the condition transitioned from one
	// status to another.
	// +optional
	LastTransitionTime string `json:"lastTransitionTime,omitempty"`

	// Message: Human readable message indicating details about the current
	// status.
	// +optional
	Message string `json:"message,omitempty"`

	// Reason: One-word CamelCase reason for the condition's last
	// transition.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Severity: How to interpret failures of this condition, one of Error,
	// Warning, Info
	// +optional
	Severity string `json:"severity,omitempty"`

	// Status: Status of the condition, one of True, False, Unknown.
	Status string `json:"status,omitempty"`

	// Type: RevisionConditionType is used to communicate the status of
	// the
	// reconciliation process. See
	// also:
	// https://github.com/knative/serving/blob/master/docs/spec/errors.
	// md#error-conditions-and-reporting
	// Types include:
	//
	// * "Ready": True when the Revision is ready.
	// * "ResourcesAvailable": True when underlying resources have
	// been
	// provisioned.
	// * "ContainerHealthy": True when the Revision readiness check
	// completes.
	// * "Active": True when the Revision may receive traffic.
	Type string `json:"type,omitempty"`

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

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

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

// RevisionSpec: RevisionSpec holds the desired state of the Revision
// (from the client).
type RevisionSpec struct {
	// ConcurrencyModel: ConcurrencyModel specifies the desired concurrency
	// model
	// (Single or Multi) for the Revision. Defaults to Multi.
	// Deprecated in favor of ContainerConcurrency.
	// +optional
	ConcurrencyModel string `json:"concurrencyModel,omitempty"`

	// Container: Container defines the unit of execution for this
	// Revision.
	// In the context of a Revision, we disallow a number of the fields
	// of
	// this Container, including: name, ports, and volumeMounts.
	// The runtime contract is documented
	// here:
	// https://github.com/knative/serving/blob/master/docs/runtime-cont
	// ract.md
	Container *Container `json:"container,omitempty"`

	// ContainerConcurrency: (Optional)
	//
	// ContainerConcurrency specifies the maximum allowed in-flight
	// (concurrent)
	// requests per container instance of the Revision.
	//
	// Cloud Run fully managed: supported, defaults to 80
	//
	// Cloud Run on GKE: supported, defaults to 0, which means
	// concurrency
	// to the application is not limited, and the system decides the
	// target concurrency for the autoscaler.
	ContainerConcurrency int64 `json:"containerConcurrency,omitempty"`

	// Containers: Containers holds the single container that defines the
	// unit of execution
	// for this Revision. In the context of a Revision, we disallow a number
	// of
	// fields on this Container, including: name and lifecycle.
	// In Cloud Run, only a single container may be provided.
	Containers []*Container `json:"containers,omitempty"`

	// Generation: Deprecated and not currently populated by Cloud Run.
	// See
	// metadata.generation instead, which is the sequence number containing
	// the
	// latest generation of the desired state.
	//
	// Read-only.
	Generation int64 `json:"generation,omitempty"`

	// ServiceAccountName: Email address of the IAM service account
	// associated with the revision
	// of the service. The service account represents the identity of
	// the
	// running revision, and determines what permissions the revision has.
	// If
	// not provided, the revision will use the project's default service
	// account.
	ServiceAccountName string `json:"serviceAccountName,omitempty"`

	// ServingState: ServingState holds a value describing the state the
	// resources
	// are in for this Revision.
	// Users must not specify this when creating a revision. It is
	// expected
	// that the system will manipulate this based on routability and
	// load.
	//
	// Populated by the system.
	// Read-only.
	//
	// Possible values:
	//   "REVISION_SERVING_STATE_UNSPECIFIED" - The revision serving state
	// hasn't been specified.
	//   "ACTIVE" - The revision is ready to serve traffic.
	//   "RESERVE" - The revision is not currently serving traffic, but
	// could be made to serve
	// traffic quickly.
	// Not currently used by Cloud Run.
	//   "RETIRED" - The revision has been decommissioned and is not needed
	// to serve traffic
	// anymore. A Revision may be brought out of retirement, but it may
	// take
	// longer than it would from a "Reserve" state.
	ServingState string `json:"servingState,omitempty"`

	// TimeoutSeconds: TimeoutSeconds holds the max duration the instance is
	// allowed for
	// responding to a request.
	// Not currently used by Cloud Run.
	TimeoutSeconds int64 `json:"timeoutSeconds,omitempty"`

	Volumes []*Volume `json:"volumes,omitempty"`

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

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

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

// RevisionStatus: RevisionStatus communicates the observed state of the
// Revision (from the
// controller).
type RevisionStatus struct {
	// Conditions: Conditions communicates information about
	// ongoing/complete
	// reconciliation processes that bring the "spec" inline with the
	// observed
	// state of the world.
	//
	// As a Revision is being prepared, it will incrementally
	// update conditions "ResourcesAvailable", "ContainerHealthy", and
	// "Active",
	// which contribute to the overall "Ready" condition.
	Conditions []*RevisionCondition `json:"conditions,omitempty"`

	// ImageDigest: ImageDigest holds the resolved digest for the image
	// specified
	// within .Spec.Container.Image. The digest is resolved during the
	// creation
	// of Revision. This field holds the digest value regardless of
	// whether
	// a tag or digest was originally specified in the Container object.
	ImageDigest string `json:"imageDigest,omitempty"`

	// LogUrl: Specifies the generated logging url for this particular
	// revision
	// based on the revision url template specified in the controller's
	// config.
	// +optional
	LogUrl string `json:"logUrl,omitempty"`

	// ObservedGeneration: ObservedGeneration is the 'Generation' of the
	// Revision that
	// was last processed by the controller.
	//
	// Clients polling for completed reconciliation should poll
	// until
	// observedGeneration = metadata.generation, and the Ready condition's
	// status
	// is True or False.
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// ServiceName: Not currently used by Cloud Run.
	ServiceName string `json:"serviceName,omitempty"`

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

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

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

// RevisionTemplate: RevisionTemplateSpec describes the data a revision
// should have when created
// from a template. Based
// on:
// https://github.com/kubernetes/api/blob/e771f807/core/v1/types.go#L
// 3179-L3190
type RevisionTemplate struct {
	// Metadata: Optional metadata for this Revision, including labels and
	// annotations. Name
	// will be generated by the Configuration.
	// To set minimum instances for this revision, use
	// the
	// "autoscaling.knative.dev/minScale" annotation key. (Cloud Run on GKE
	// only).
	// To set maximum instances for this revision, use
	// the
	// "autoscaling.knative.dev/maxScale" annotation key.
	// To set Cloud SQL connections for the revision, use
	// the
	// "run.googleapis.com/cloudsql-instances" annotation key. Values should
	// be
	// comma separated.
	Metadata *ObjectMeta `json:"metadata,omitempty"`

	// Spec: RevisionSpec holds the desired state of the Revision (from the
	// client).
	Spec *RevisionSpec `json:"spec,omitempty"`

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

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

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

// Route: Route is responsible for configuring ingress over a collection
// of Revisions.
// Some of the Revisions a Route distributes traffic over may be
// specified by
// referencing the Configuration responsible for creating them; in these
// cases
// the Route is additionally responsible for monitoring the
// Configuration for
// "latest ready" revision changes, and smoothly rolling out latest
// revisions.
// See
// also:
// https://github.com/knative/serving/blob/master/docs/spec/overvie
// w.md#route
//
// Cloud Run currently supports referencing a single Configuration
// to
// automatically deploy the "latest ready" Revision from that
// Configuration.
type Route struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The kind of this resource, in this case always "Route".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Route, including name,
	// namespace, labels,
	// and annotations.
	Metadata *ObjectMeta `json:"metadata,omitempty"`

	// Spec: Spec holds the desired state of the Route (from the client).
	Spec *RouteSpec `json:"spec,omitempty"`

	// Status: Status communicates the observed state of the Route (from the
	// controller).
	Status *RouteStatus `json:"status,omitempty"`

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

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

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

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

// RouteCondition: RouteCondition defines a readiness condition for a
// Route.
type RouteCondition struct {
	// LastTransitionTime: Last time the condition transitioned from one
	// status to another.
	// +optional
	LastTransitionTime string `json:"lastTransitionTime,omitempty"`

	// Message: Human-readable message indicating details about last
	// transition.
	// +optional
	Message string `json:"message,omitempty"`

	// Reason: One-word CamelCase reason for the condition's last
	// transition.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Severity: How to interpret failures of this condition, one of Error,
	// Warning, Info
	// +optional
	Severity string `json:"severity,omitempty"`

	// Status: Status of the condition, one of "True", "False", "Unknown".
	Status string `json:"status,omitempty"`

	// Type: RouteConditionType is used to communicate the status of the
	// reconciliation
	// process. See
	// also:
	// https://github.com/knative/serving/blob/master/docs/spec/errors.
	// md#error-conditions-and-reporting
	// Types include: "Ready".
	Type string `json:"type,omitempty"`

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

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

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

// RouteSpec: RouteSpec holds the desired state of the Route (from the
// client).
type RouteSpec struct {
	// Generation: Deprecated and not currently populated by Cloud Run.
	// See
	// metadata.generation instead, which is the sequence number containing
	// the
	// latest generation of the desired state.
	//
	// Read-only.
	Generation int64 `json:"generation,omitempty"`

	// Traffic: Traffic specifies how to distribute traffic over a
	// collection of Knative
	// Revisions and Configurations.
	// Cloud Run currently supports a single configurationName.
	Traffic []*TrafficTarget `json:"traffic,omitempty"`

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

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

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

// RouteStatus: RouteStatus communicates the observed state of the Route
// (from the
// controller).
type RouteStatus struct {
	// Address: Similar to url, information on where the service is
	// available on HTTP.
	Address *Addressable `json:"address,omitempty"`

	// Conditions: Conditions communicates information about
	// ongoing/complete
	// reconciliation processes that bring the "spec" inline with the
	// observed
	// state of the world.
	Conditions []*RouteCondition `json:"conditions,omitempty"`

	// Domain: Deprecated - use url instead.
	// Domain holds the top-level domain that will distribute traffic over
	// the
	// provided targets.
	Domain string `json:"domain,omitempty"`

	// DomainInternal: Deprecated - use address instead.
	// For Cloud Run, identifical to domain.
	DomainInternal string `json:"domainInternal,omitempty"`

	// ObservedGeneration: ObservedGeneration is the 'Generation' of the
	// Route that
	// was last processed by the controller.
	//
	// Clients polling for completed reconciliation should poll
	// until
	// observedGeneration = metadata.generation and the Ready condition's
	// status
	// is True or False.
	//
	// Note that providing a trafficTarget that only has a configurationName
	// will
	// result in a Route that does not increment either its
	// metadata.generation or
	// its observedGeneration, as new "latest ready" revisions from
	// the
	// Configuration are processed without an update to the Route's spec.
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Traffic: Traffic holds the configured traffic distribution.
	// These entries will always contain RevisionName references.
	// When ConfigurationName appears in the spec, this will hold
	// the
	// LatestReadyRevisionName that we last observed.
	Traffic []*TrafficTarget `json:"traffic,omitempty"`

	// Url: URL holds the url that will distribute traffic over the provided
	// traffic
	// targets. It generally has the
	// form
	// https://{route-hash}-{project-hash}-{cluster-level-suffix}.a.run.
	// app
	Url string `json:"url,omitempty"`

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

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

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

// SELinuxOptions: SELinuxOptions are the labels to be applied to the
// container
type SELinuxOptions struct {
	// Level: Level is SELinux level label that applies to the
	// container.
	// +optional
	Level string `json:"level,omitempty"`

	// Role: Role is a SELinux role label that applies to the
	// container.
	// +optional
	Role string `json:"role,omitempty"`

	// Type: Type is a SELinux type label that applies to the
	// container.
	// +optional
	Type string `json:"type,omitempty"`

	// User: User is a SELinux user label that applies to the
	// container.
	// +optional
	User string `json:"user,omitempty"`

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

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

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

// SecretEnvSource: SecretEnvSource selects a Secret to populate the
// environment
// variables with.
//
// The contents of the target Secret's Data field will represent
// the
// key-value pairs as environment variables.
type SecretEnvSource struct {
	// LocalObjectReference: This field should not be used directly as it is
	// meant to be inlined
	// directly into the message. Use the "name" field instead.
	LocalObjectReference *LocalObjectReference `json:"localObjectReference,omitempty"`

	// Name: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// The Secret to select from.
	Name string `json:"name,omitempty"`

	// Optional: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Specify whether the Secret must be defined
	// +optional
	Optional bool `json:"optional,omitempty"`

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

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

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

// SecretKeySelector: Cloud Run fully managed: not supported
//
// Cloud Run on GKE: supported
//
// SecretKeySelector selects a key of a Secret.
type SecretKeySelector struct {
	// Key: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// The key of the secret to select from.  Must be a valid secret key.
	Key string `json:"key,omitempty"`

	// LocalObjectReference: This field should not be used directly as it is
	// meant to be inlined
	// directly into the message. Use the "name" field instead.
	LocalObjectReference *LocalObjectReference `json:"localObjectReference,omitempty"`

	// Name: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// The name of the secret in the pod's namespace to select from.
	Name string `json:"name,omitempty"`

	// Optional: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// Specify whether the Secret or its key must be defined
	// +optional
	Optional bool `json:"optional,omitempty"`

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

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

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

// SecretVolumeSource: The contents of the target Secret's Data field
// will be presented in a volume
// as files using the keys in the Data field as the file names.
type SecretVolumeSource struct {
	// DefaultMode: Mode bits to use on created files by default. Must be a
	// value between 0 and
	// 0777. Defaults to 0644. Directories within the path are not affected
	// by
	// this setting. This might be in conflict with other options that
	// affect the
	// file mode, like fsGroup, and the result can be other mode bits set.
	DefaultMode int64 `json:"defaultMode,omitempty"`

	// Items: If unspecified, each key-value pair in the Data field of the
	// referenced
	// Secret will be projected into the volume as a file whose name is
	// the
	// key and content is the value. If specified, the listed keys will
	// be
	// projected into the specified paths, and unlisted keys will not
	// be
	// present. If a key is specified which is not present in the
	// Secret,
	// the volume setup will error unless it is marked optional.
	Items []*KeyToPath `json:"items,omitempty"`

	// Optional: Specify whether the Secret or its keys must be defined.
	Optional bool `json:"optional,omitempty"`

	// SecretName: Name of the secret in the container's namespace to use.
	SecretName string `json:"secretName,omitempty"`

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

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

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

// SecurityContext: SecurityContext holds security configuration that
// will be applied to a
// container. Some fields are present in both SecurityContext
// and
// PodSecurityContext.  When both are set, the values in SecurityContext
// take
// precedence.
type SecurityContext struct {
	// AllowPrivilegeEscalation: AllowPrivilegeEscalation controls whether a
	// process can gain more
	// privileges than its parent process. This bool directly controls
	// if
	// the no_new_privs flag will be set on the container
	// process.
	// AllowPrivilegeEscalation is true always when the container is:
	// 1) run as Privileged
	// 2) has CAP_SYS_ADMIN
	// +optional
	AllowPrivilegeEscalation bool `json:"allowPrivilegeEscalation,omitempty"`

	// Capabilities: The capabilities to add/drop when running
	// containers.
	// Defaults to the default set of capabilities granted by the
	// container
	// runtime. +optional
	Capabilities *Capabilities `json:"capabilities,omitempty"`

	// Privileged: Run container in privileged mode.
	// Processes in privileged containers are essentially equivalent to root
	// on
	// the host. Defaults to false. +optional
	Privileged bool `json:"privileged,omitempty"`

	// ReadOnlyRootFilesystem: Whether this container has a read-only root
	// filesystem.
	// Default is false.
	// +optional
	ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty"`

	// RunAsGroup: The GID to run the entrypoint of the container
	// process.
	// Uses runtime default if unset.
	// May also be set in PodSecurityContext.  If set in both
	// SecurityContext and
	// PodSecurityContext, the value specified in SecurityContext
	// takes
	// precedence. +optional
	RunAsGroup int64 `json:"runAsGroup,omitempty"`

	// RunAsNonRoot: Indicates that the container must run as a non-root
	// user.
	// If true, the Kubelet will validate the image at runtime to ensure
	// that it
	// does not run as UID 0 (root) and fail to start the container if it
	// does.
	// If unset or false, no such validation will be performed.
	// May also be set in PodSecurityContext.  If set in both
	// SecurityContext and
	// PodSecurityContext, the value specified in SecurityContext
	// takes
	// precedence. +optional
	RunAsNonRoot bool `json:"runAsNonRoot,omitempty"`

	// RunAsUser: The UID to run the entrypoint of the container
	// process.
	// Defaults to user specified in image metadata if unspecified.
	// May also be set in PodSecurityContext.  If set in both
	// SecurityContext and
	// PodSecurityContext, the value specified in SecurityContext
	// takes
	// precedence. +optional
	RunAsUser int64 `json:"runAsUser,omitempty"`

	// SeLinuxOptions: The SELinux context to be applied to the
	// container.
	// If unspecified, the container runtime will allocate a random
	// SELinux
	// context for each container.  May also be set in PodSecurityContext.
	// If set
	// in both SecurityContext and PodSecurityContext, the value specified
	// in
	// SecurityContext takes precedence. +optional
	SeLinuxOptions *SELinuxOptions `json:"seLinuxOptions,omitempty"`

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

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

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

// Service: Service acts as a top-level container that manages a set of
// Routes and
// Configurations which implement a network service. Service exists to
// provide a
// singular abstraction which can be access controlled, reasoned about,
// and
// which encapsulates software lifecycle decisions such as rollout
// policy and
// team resource ownership. Service acts only as an orchestrator of
// the
// underlying Routes and Configurations (much as a kubernetes
// Deployment
// orchestrates ReplicaSets).
//
// The Service's controller will track the statuses of its owned
// Configuration
// and Route, reflecting their statuses and conditions as its own.
//
// See
// also:
// https://github.com/knative/serving/blob/master/docs/spec/overvie
// w.md#service
type Service struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The kind of resource, in this case "Service".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Service, including name,
	// namespace, labels,
	// and annotations.
	Metadata *ObjectMeta `json:"metadata,omitempty"`

	// Spec: Spec holds the desired state of the Service (from the client).
	Spec *ServiceSpec `json:"spec,omitempty"`

	// Status: Status communicates the observed state of the Service (from
	// the
	// controller).
	Status *ServiceStatus `json:"status,omitempty"`

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

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

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

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

// ServiceCondition: ServiceCondition defines a readiness condition for
// a Service.
type ServiceCondition struct {
	// LastTransitionTime: Last time the condition transitioned from one
	// status to another.
	// +optional
	LastTransitionTime string `json:"lastTransitionTime,omitempty"`

	// Message: Human-readable message indicating details about last
	// transition.
	// +optional
	Message string `json:"message,omitempty"`

	// Reason: One-word CamelCase reason for the condition's last
	// transition.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Severity: How to interpret failures of this condition, one of Error,
	// Warning, Info
	// +optional
	Severity string `json:"severity,omitempty"`

	// Status: Status of the condition, one of True, False, Unknown.
	Status string `json:"status,omitempty"`

	// Type: ServiceConditionType is used to communicate the status of
	// the
	// reconciliation process. See
	// also:
	// https://github.com/knative/serving/blob/master/docs/spec/errors.
	// md#error-conditions-and-reporting
	//
	// Types include: "Ready", "ConfigurationsReady", and "RoutesReady".
	// "Ready"
	// will be true when the underlying Route and Configuration are ready.
	Type string `json:"type,omitempty"`

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

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

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

// ServiceSpec: ServiceSpec holds the desired state of the Route (from
// the client), which
// is used to manipulate the underlying Route and Configuration(s).
type ServiceSpec struct {
	// Generation: Deprecated and not currently populated by Cloud Run.
	// See
	// metadata.generation instead, which is the sequence number containing
	// the
	// latest generation of the desired state.
	//
	// Read-only.
	Generation int64 `json:"generation,omitempty"`

	// Manual: Manual contains the options for configuring a manual service.
	// See
	// ServiceSpec for more details.
	//
	// Not currently supported by Cloud Run.
	Manual *ServiceSpecManualType `json:"manual,omitempty"`

	// Pinned: Pins this service to a specific revision name. The revision
	// must
	// be owned by the configuration provided.
	//
	// Deprecated and not supported by Cloud Run.
	// +optional
	Pinned *ServiceSpecPinnedType `json:"pinned,omitempty"`

	// Release: Release enables gradual promotion of new revisions by
	// allowing traffic
	// to be split between two revisions. This type replaces the
	// deprecated
	// Pinned type.
	//
	// Not currently supported by Cloud Run.
	Release *ServiceSpecReleaseType `json:"release,omitempty"`

	// RunLatest: RunLatest defines a simple Service. It will
	// automatically
	// configure a route that keeps the latest ready revision
	// from the supplied configuration running.
	// +optional
	RunLatest *ServiceSpecRunLatest `json:"runLatest,omitempty"`

	// Template: Template holds the latest specification for the Revision
	// to
	// be stamped out.
	Template *RevisionTemplate `json:"template,omitempty"`

	// Traffic: Traffic specifies how to distribute traffic over a
	// collection of Knative
	// Revisions and Configurations.
	Traffic []*TrafficTarget `json:"traffic,omitempty"`

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

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

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

// ServiceSpecManualType: ServiceSpecManualType contains the options for
// configuring a manual service.
// See ServiceSpec for more details.
//
// Not currently supported by Cloud Run.
type ServiceSpecManualType struct {
}

// ServiceSpecPinnedType: ServiceSpecPinnedType Pins this service to a
// specific revision name. The
// revision must be owned by the configuration provided.
//
// Deprecated and not supported by Cloud Run.
type ServiceSpecPinnedType struct {
	// Configuration: The configuration for this service.
	Configuration *ConfigurationSpec `json:"configuration,omitempty"`

	// RevisionName: The revision name to pin this service to until
	// changed
	// to a different service type.
	RevisionName string `json:"revisionName,omitempty"`

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

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

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

// ServiceSpecReleaseType: ServiceSpecReleaseType contains the options
// for slowly releasing revisions.
// See ServiceSpec for more details.
//
// Not currently supported by Cloud Run.
type ServiceSpecReleaseType struct {
	// Configuration: The configuration for this service. All revisions from
	// this service must
	// come from a single configuration.
	Configuration *ConfigurationSpec `json:"configuration,omitempty"`

	// Revisions: Revisions is an ordered list of 1 or 2 revisions. The
	// first is the current
	// revision, and the second is the candidate revision. If a single
	// revision
	// is provided, traffic will be pinned at that revision.
	//
	// "@latest" is a shortcut for usage that refers to the latest
	// created
	// revision by the configuration.
	Revisions []string `json:"revisions,omitempty"`

	// RolloutPercent: RolloutPercent is the percent of traffic that should
	// be sent to the
	// candidate revision, i.e. the 2nd revision in the revisions
	// list.
	// Valid values are between 0 and 99 inclusive.
	RolloutPercent int64 `json:"rolloutPercent,omitempty"`

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

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

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

// ServiceSpecRunLatest: ServiceSpecRunLatest contains the options for
// always having a route to the
// latest configuration. See ServiceSpec for more details.
type ServiceSpecRunLatest struct {
	// Configuration: The configuration for this service.
	Configuration *ConfigurationSpec `json:"configuration,omitempty"`

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

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

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

// ServiceStatus: The current state of the Service. Output only.
type ServiceStatus struct {
	// Address: From RouteStatus.
	// Similar to url, information on where the service is available on
	// HTTP.
	Address *Addressable `json:"address,omitempty"`

	// Conditions: Conditions communicates information about
	// ongoing/complete
	// reconciliation processes that bring the "spec" inline with the
	// observed
	// state of the world.
	Conditions []*ServiceCondition `json:"conditions,omitempty"`

	// Domain: From RouteStatus.
	// Domain holds the top-level domain that will distribute traffic over
	// the
	// provided targets. It generally has the
	// form
	// https://{route-hash}-{project-hash}-{cluster-level-suffix}.a.run.
	// app
	Domain string `json:"domain,omitempty"`

	// LatestCreatedRevisionName: From
	// ConfigurationStatus.
	// LatestCreatedRevisionName is the last revision that was created from
	// this
	// Service's Configuration. It might not be ready yet, for that
	// use
	// LatestReadyRevisionName.
	LatestCreatedRevisionName string `json:"latestCreatedRevisionName,omitempty"`

	// LatestReadyRevisionName: From
	// ConfigurationStatus.
	// LatestReadyRevisionName holds the name of the latest Revision stamped
	// out
	// from this Service's Configuration that has had its "Ready" condition
	// become
	// "True".
	LatestReadyRevisionName string `json:"latestReadyRevisionName,omitempty"`

	// ObservedGeneration: ObservedGeneration is the 'Generation' of the
	// Route that
	// was last processed by the controller.
	//
	// Clients polling for completed reconciliation should poll
	// until
	// observedGeneration = metadata.generation and the Ready condition's
	// status
	// is True or False.
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// Traffic: From RouteStatus.
	// Traffic holds the configured traffic distribution.
	// These entries will always contain RevisionName references.
	// When ConfigurationName appears in the spec, this will hold
	// the
	// LatestReadyRevisionName that we last observed.
	Traffic []*TrafficTarget `json:"traffic,omitempty"`

	// Url: From RouteStatus.
	// URL holds the url that will distribute traffic over the provided
	// traffic
	// targets. It generally has the
	// form
	// https://{route-hash}-{project-hash}-{cluster-level-suffix}.a.run.
	// app
	Url string `json:"url,omitempty"`

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

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

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

// SetIamPolicyRequest: Request message for `SetIamPolicy` method.
type SetIamPolicyRequest struct {
	// Policy: REQUIRED: The complete policy to be applied to the
	// `resource`. The size of
	// the policy is limited to a few 10s of KB. An empty policy is a
	// valid policy but certain Cloud Platform services (such as
	// Projects)
	// might reject them.
	Policy *Policy `json:"policy,omitempty"`

	// UpdateMask: OPTIONAL: A FieldMask specifying which fields of the
	// policy to modify. Only
	// the fields in the mask will be modified. If no mask is provided,
	// the
	// following default mask is used:
	// paths: "bindings, etag"
	// This field is only used by Cloud IAM.
	UpdateMask string `json:"updateMask,omitempty"`

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

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

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

type SubscriberSpec struct {
	// Ref: Reference to an object that will be used to find the
	// target
	// endpoint, which should implement the Addressable duck type.
	// For example, this could be a reference to a Route resource
	// or a Knative Service resource.
	Ref *ObjectReference `json:"ref,omitempty"`

	// Uri: Reference to a 'known' endpoint where no resolving is
	// done.
	// http://k8s-service for
	// example
	// http://myexternalhandler.example.com/foo/bar
	Uri string `json:"uri,omitempty"`

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

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

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

// TCPSocketAction: TCPSocketAction describes an action based on opening
// a socket
type TCPSocketAction struct {
	// Host: Optional: Host name to connect to, defaults to the pod
	// IP.
	// +optional
	Host string `json:"host,omitempty"`

	// Port: Number or name of the port to access on the container.
	// Number must be in the range 1 to 65535.
	// Name must be an IANA_SVC_NAME.
	Port *IntOrString `json:"port,omitempty"`

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

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

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

// TestIamPermissionsRequest: Request message for `TestIamPermissions`
// method.
type TestIamPermissionsRequest struct {
	// Permissions: The set of permissions to check for the `resource`.
	// Permissions with
	// wildcards (such as '*' or 'storage.*') are not allowed. For
	// more
	// information see
	// [IAM
	// Overview](https://cloud.google.com/iam/docs/overview#permissions).
	Permissions []string `json:"permissions,omitempty"`

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

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

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

// TestIamPermissionsResponse: Response message for `TestIamPermissions`
// method.
type TestIamPermissionsResponse struct {
	// Permissions: A subset of `TestPermissionsRequest.permissions` that
	// the caller is
	// allowed.
	Permissions []string `json:"permissions,omitempty"`

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

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

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

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

// TrafficTarget: TrafficTarget holds a single entry of the routing
// table for a Route.
type TrafficTarget struct {
	// ConfigurationName: ConfigurationName of a configuration to whose
	// latest revision we will
	// send this portion of traffic. When the
	// "status.latestReadyRevisionName"
	// of the referenced configuration changes, we will automatically
	// migrate
	// traffic from the prior "latest ready" revision to the new one. This
	// field
	// is never set in Route's status, only its spec. This is mutually
	// exclusive
	// with RevisionName.
	//
	// Cloud Run currently supports a single ConfigurationName.
	ConfigurationName string `json:"configurationName,omitempty"`

	// LatestRevision: LatestRevision may be optionally provided to indicate
	// that the latest
	// ready Revision of the Configuration should be used for this
	// traffic
	// target. When provided LatestRevision must be true if RevisionName
	// is
	// empty; it must be false when RevisionName is non-empty.
	// +optional
	LatestRevision bool `json:"latestRevision,omitempty"`

	// Name: Name is optionally used to expose a dedicated hostname for
	// referencing this
	// target exclusively.
	//
	// Not currently supported by Cloud Run.
	// +optional
	Name string `json:"name,omitempty"`

	// Percent: Percent specifies percent of the traffic to this Revision or
	// Configuration.
	// This defaults to zero if unspecified.
	//
	// Cloud Run currently requires 100 percent for a single
	// ConfigurationName
	// TrafficTarget entry.
	Percent int64 `json:"percent,omitempty"`

	// RevisionName: RevisionName of a specific revision to which to send
	// this portion of
	// traffic. This is mutually exclusive with
	// ConfigurationName.
	//
	// Providing RevisionName in spec is not currently supported by Cloud
	// Run.
	RevisionName string `json:"revisionName,omitempty"`

	// Tag: Tag is optionally used to expose a dedicated url for
	// referencing
	// this target exclusively.
	//
	// Not currently supported in Cloud Run.
	// +optional
	Tag string `json:"tag,omitempty"`

	// Url: Output only. URL displays the URL for accessing named traffic
	// targets. URL
	// is displayed in status, and is disallowed on spec. URL must contain
	// a
	// scheme (e.g. http://) and a hostname, but may not contain anything
	// else
	// (e.g. basic auth, url path, etc.
	//
	// Not currently supported in Cloud Run.
	Url string `json:"url,omitempty"`

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

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

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

type Trigger struct {
	// ApiVersion: The API version for this call such as
	// "eventing.knative.dev/v1alpha1".
	ApiVersion string `json:"apiVersion,omitempty"`

	// Kind: The kind of resource, in this case "Trigger".
	Kind string `json:"kind,omitempty"`

	// Metadata: Metadata associated with this Trigger.
	Metadata *ObjectMeta `json:"metadata,omitempty"`

	// Spec: Spec defines the desired state of the Trigger.
	Spec *TriggerSpec `json:"spec,omitempty"`

	// Status: Status represents the current state of the Trigger. This data
	// may be out of
	// date.
	// +optional
	Status *TriggerStatus `json:"status,omitempty"`

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

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

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

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

// TriggerCondition: TriggerCondition contains state information for an
// Trigger.
type TriggerCondition struct {
	// LastTransitionTime: Last time the condition transitioned from one
	// status to another.
	// +optional
	LastTransitionTime string `json:"lastTransitionTime,omitempty"`

	// Message: Human readable message indicating details about the current
	// status.
	// +optional
	Message string `json:"message,omitempty"`

	// Reason: One-word CamelCase reason for the condition's current
	// status.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Severity: How to interpret failures of this condition, one of Error,
	// Warning, Info
	// +optional
	Severity string `json:"severity,omitempty"`

	// Status: Status of the condition, one of True, False, Unknown.
	Status string `json:"status,omitempty"`

	// Type: Type of Trigger condition.
	Type string `json:"type,omitempty"`

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

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

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

type TriggerFilter struct {
	// Attributes: Cloud Run fully managed: not supported
	//
	// Cloud Run on GKE: supported
	//
	// Attributes filters events by exact match on event context
	// attributes.
	// Each key in the map is compared with the equivalent key in the
	// event
	// context. An event passes the filter if all values are equal to
	// the
	// specified values.
	//
	// Nested context attributes are not supported as keys.
	// Only string values are supported.
	//
	// +optional
	Attributes map[string]string `json:"attributes,omitempty"`

	// SourceAndType: SourceAndType is DEPRECATED and replaced by the
	// Attributes field.
	SourceAndType *TriggerFilterSourceAndType `json:"sourceAndType,omitempty"`

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

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

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

// TriggerFilterSourceAndType: TriggerFilterSourceAndType is DEPRECATED.
// Filters are now contained in the
// map of attributes in TriggerFilter proto.
type TriggerFilterSourceAndType struct {
	Source string `json:"source,omitempty"`

	Type string `json:"type,omitempty"`

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

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

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

type TriggerImporterSpec struct {
	// Arguments: Arguments to use for the importer. These must match the
	// parameters in the
	// EventType's importer.
	Arguments map[string]string `json:"arguments,omitempty"`

	// EventTypeName: Name of the EventType that this importer provides.
	EventTypeName string `json:"eventTypeName,omitempty"`

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

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

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

// TriggerSpec: The desired state of the Trigger.
type TriggerSpec struct {
	// Broker: Broker is the broker that this trigger receives events from.
	// If not
	// specified, will default to 'default'.
	//
	// Not currently supported by Cloud Run.
	Broker string `json:"broker,omitempty"`

	// Filter: Filter is the filter to apply against all events from the
	// Broker. Only
	// events that pass this filter will be sent to the Subscriber.
	Filter *TriggerFilter `json:"filter,omitempty"`

	// Importers: Specification of the importers that will provide events to
	// the trigger.
	// Note, for Cloud Run, the importers will only be used if a filter is
	// not
	// specified.
	Importers []*TriggerImporterSpec `json:"importers,omitempty"`

	// Subscriber: Subscriber is the addressable that receives events from
	// the Broker that
	// pass the Filter. It is required.
	//
	// E.g. https://us-central1-myproject.cloudfunctions.net/myfunction
	// or
	// /namespaces/my-project/services/my-service.
	Subscriber *SubscriberSpec `json:"subscriber,omitempty"`

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

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

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

// TriggerStatus: TriggerStatus represents the current state of a
// Trigger.
type TriggerStatus struct {
	// Conditions: Array of observed TriggerConditions, indicating the
	// current state
	// of the Trigger.
	Conditions []*TriggerCondition `json:"conditions,omitempty"`

	// ObservedGeneration: ObservedGeneration is the 'Generation' of the
	// Trigger that
	// was last processed by the controller.
	ObservedGeneration int64 `json:"observedGeneration,omitempty"`

	// SubscriberUri: SubscriberURI is the resolved URI of the receiver for
	// this Trigger.
	SubscriberUri string `json:"subscriberUri,omitempty"`

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

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

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

// Volume: Volume represents a named volume in a container.
type Volume struct {
	ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty"`

	// Name: Volume's name.
	Name string `json:"name,omitempty"`

	Secret *SecretVolumeSource `json:"secret,omitempty"`

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

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

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

// VolumeDevice: volumeDevice describes a mapping of a raw block device
// within a container.
type VolumeDevice struct {
	// DevicePath: devicePath is the path inside of the container that the
	// device will be
	// mapped to.
	DevicePath string `json:"devicePath,omitempty"`

	// Name: name must match the name of a persistentVolumeClaim in the pod
	Name string `json:"name,omitempty"`

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

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

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

// VolumeMount: VolumeMount describes a mounting of a Volume within a
// container.
type VolumeMount struct {
	// MountPath: Path within the container at which the volume should be
	// mounted.  Must
	// not contain ':'.
	MountPath string `json:"mountPath,omitempty"`

	// MountPropagation: mountPropagation determines how mounts are
	// propagated from the host
	// to container and the other way around.
	// When not set, MountPropagationHostToContainer is used.
	// This field is beta in 1.10.
	// +optional
	MountPropagation string `json:"mountPropagation,omitempty"`

	// Name: This must match the Name of a Volume.
	Name string `json:"name,omitempty"`

	// ReadOnly: Mounted read-only if true, read-write otherwise (false or
	// unspecified).
	// Defaults to false.
	// +optional
	ReadOnly bool `json:"readOnly,omitempty"`

	// SubPath: Path within the volume from which the container's volume
	// should be mounted.
	// Defaults to "" (volume's root).
	// +optional
	SubPath string `json:"subPath,omitempty"`

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

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

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

// method id "run.namespaces.authorizeddomains.list":

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

// List: RPC to list authorized domains.
func (r *NamespacesAuthorizeddomainsService) List(parent string) *NamespacesAuthorizeddomainsListCall {
	c := &NamespacesAuthorizeddomainsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum results to
// return per page.
func (c *NamespacesAuthorizeddomainsListCall) PageSize(pageSize int64) *NamespacesAuthorizeddomainsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Continuation token
// for fetching the next page of results.
func (c *NamespacesAuthorizeddomainsListCall) PageToken(pageToken string) *NamespacesAuthorizeddomainsListCall {
	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 *NamespacesAuthorizeddomainsListCall) Fields(s ...googleapi.Field) *NamespacesAuthorizeddomainsListCall {
	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 *NamespacesAuthorizeddomainsListCall) IfNoneMatch(entityTag string) *NamespacesAuthorizeddomainsListCall {
	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 *NamespacesAuthorizeddomainsListCall) Context(ctx context.Context) *NamespacesAuthorizeddomainsListCall {
	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 *NamespacesAuthorizeddomainsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.authorizeddomains.list" call.
// Exactly one of *ListAuthorizedDomainsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListAuthorizedDomainsResponse.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 *NamespacesAuthorizeddomainsListCall) Do(opts ...googleapi.CallOption) (*ListAuthorizedDomainsResponse, 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 := &ListAuthorizedDomainsResponse{
		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": "RPC to list authorized domains.",
	//   "flatPath": "apis/domains.cloudrun.com/v1alpha1/namespaces/{namespacesId}/authorizeddomains",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.authorizeddomains.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Maximum results to return per page.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Continuation token for fetching the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Name of the parent Application resource. Example: `apps/myapp`.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/domains.cloudrun.com/v1alpha1/{+parent}/authorizeddomains",
	//   "response": {
	//     "$ref": "ListAuthorizedDomainsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *NamespacesAuthorizeddomainsListCall) Pages(ctx context.Context, f func(*ListAuthorizedDomainsResponse) 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 "run.namespaces.configurations.get":

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

// Get: Rpc to get information about a configuration.
func (r *NamespacesConfigurationsService) Get(name string) *NamespacesConfigurationsGetCall {
	c := &NamespacesConfigurationsGetCall{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 *NamespacesConfigurationsGetCall) Fields(s ...googleapi.Field) *NamespacesConfigurationsGetCall {
	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 *NamespacesConfigurationsGetCall) IfNoneMatch(entityTag string) *NamespacesConfigurationsGetCall {
	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 *NamespacesConfigurationsGetCall) Context(ctx context.Context) *NamespacesConfigurationsGetCall {
	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 *NamespacesConfigurationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesConfigurationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/serving.knative.dev/v1alpha1/{+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 "run.namespaces.configurations.get" call.
// Exactly one of *Configuration or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Configuration.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 *NamespacesConfigurationsGetCall) Do(opts ...googleapi.CallOption) (*Configuration, 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 := &Configuration{
		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": "Rpc to get information about a configuration.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/configurations/{configurationsId}",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.configurations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the configuration being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/configurations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Configuration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.configurations.list":

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

// List: Rpc to list configurations.
func (r *NamespacesConfigurationsService) List(parent string) *NamespacesConfigurationsListCall {
	c := &NamespacesConfigurationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *NamespacesConfigurationsListCall) Continue(continue_ string) *NamespacesConfigurationsListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *NamespacesConfigurationsListCall) FieldSelector(fieldSelector string) *NamespacesConfigurationsListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *NamespacesConfigurationsListCall) IncludeUninitialized(includeUninitialized bool) *NamespacesConfigurationsListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *NamespacesConfigurationsListCall) LabelSelector(labelSelector string) *NamespacesConfigurationsListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *NamespacesConfigurationsListCall) Limit(limit int64) *NamespacesConfigurationsListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *NamespacesConfigurationsListCall) ResourceVersion(resourceVersion string) *NamespacesConfigurationsListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *NamespacesConfigurationsListCall) Watch(watch bool) *NamespacesConfigurationsListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *NamespacesConfigurationsListCall) Fields(s ...googleapi.Field) *NamespacesConfigurationsListCall {
	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 *NamespacesConfigurationsListCall) IfNoneMatch(entityTag string) *NamespacesConfigurationsListCall {
	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 *NamespacesConfigurationsListCall) Context(ctx context.Context) *NamespacesConfigurationsListCall {
	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 *NamespacesConfigurationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.configurations.list" call.
// Exactly one of *ListConfigurationsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListConfigurationsResponse.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 *NamespacesConfigurationsListCall) Do(opts ...googleapi.CallOption) (*ListConfigurationsResponse, 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 := &ListConfigurationsResponse{
		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": "Rpc to list configurations.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/configurations",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.configurations.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the configurations should be\nlisted.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+parent}/configurations",
	//   "response": {
	//     "$ref": "ListConfigurationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.domainmappings.create":

type NamespacesDomainmappingsCreateCall struct {
	s             *APIService
	parent        string
	domainmapping *DomainMapping
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Create: Creates a new domain mapping.
func (r *NamespacesDomainmappingsService) Create(parent string, domainmapping *DomainMapping) *NamespacesDomainmappingsCreateCall {
	c := &NamespacesDomainmappingsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.domainmapping = domainmapping
	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 *NamespacesDomainmappingsCreateCall) Fields(s ...googleapi.Field) *NamespacesDomainmappingsCreateCall {
	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 *NamespacesDomainmappingsCreateCall) Context(ctx context.Context) *NamespacesDomainmappingsCreateCall {
	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 *NamespacesDomainmappingsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesDomainmappingsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.domainmapping)
	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, "apis/domains.cloudrun.com/v1alpha1/{+parent}/domainmappings")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.domainmappings.create" call.
// Exactly one of *DomainMapping or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DomainMapping.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 *NamespacesDomainmappingsCreateCall) Do(opts ...googleapi.CallOption) (*DomainMapping, 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 := &DomainMapping{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a new domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1alpha1/namespaces/{namespacesId}/domainmappings",
	//   "httpMethod": "POST",
	//   "id": "run.namespaces.domainmappings.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this domain mapping should be\ncreated.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/domains.cloudrun.com/v1alpha1/{+parent}/domainmappings",
	//   "request": {
	//     "$ref": "DomainMapping"
	//   },
	//   "response": {
	//     "$ref": "DomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.domainmappings.delete":

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

// Delete: Rpc to delete a domain mapping.
func (r *NamespacesDomainmappingsService) Delete(name string) *NamespacesDomainmappingsDeleteCall {
	c := &NamespacesDomainmappingsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ApiVersion sets the optional parameter "apiVersion": Cloud Run
// currently ignores this parameter.
func (c *NamespacesDomainmappingsDeleteCall) ApiVersion(apiVersion string) *NamespacesDomainmappingsDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *NamespacesDomainmappingsDeleteCall) Kind(kind string) *NamespacesDomainmappingsDeleteCall {
	c.urlParams_.Set("kind", kind)
	return c
}

// OrphanDependents sets the optional parameter "orphanDependents":
// Deprecated.
// Specifies the cascade behavior on delete.
// Cloud Run only supports cascading behavior, so this must be
// false.
// This attribute is deprecated, and is now replaced with
// PropagationPolicy
// See https://github.com/kubernetes/kubernetes/issues/46659 for more
// info.
func (c *NamespacesDomainmappingsDeleteCall) OrphanDependents(orphanDependents bool) *NamespacesDomainmappingsDeleteCall {
	c.urlParams_.Set("orphanDependents", fmt.Sprint(orphanDependents))
	return c
}

// PropagationPolicy sets the optional parameter "propagationPolicy":
// Specifies the propagation policy of delete. Cloud Run currently
// ignores
// this setting, and deletes in the background. Please
// see
// kubernetes.io/docs/concepts/workloads/controllers/garbage-collecti
// on/ for
// more information.
func (c *NamespacesDomainmappingsDeleteCall) PropagationPolicy(propagationPolicy string) *NamespacesDomainmappingsDeleteCall {
	c.urlParams_.Set("propagationPolicy", propagationPolicy)
	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 *NamespacesDomainmappingsDeleteCall) Fields(s ...googleapi.Field) *NamespacesDomainmappingsDeleteCall {
	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 *NamespacesDomainmappingsDeleteCall) Context(ctx context.Context) *NamespacesDomainmappingsDeleteCall {
	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 *NamespacesDomainmappingsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesDomainmappingsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/domains.cloudrun.com/v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.domainmappings.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 *NamespacesDomainmappingsDeleteCall) 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": "Rpc to delete a domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1alpha1/namespaces/{namespacesId}/domainmappings/{domainmappingsId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.namespaces.domainmappings.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "apiVersion": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "kind": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the domain mapping being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/domainmappings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orphanDependents": {
	//       "description": "Deprecated.\nSpecifies the cascade behavior on delete.\nCloud Run only supports cascading behavior, so this must be false.\nThis attribute is deprecated, and is now replaced with PropagationPolicy\nSee https://github.com/kubernetes/kubernetes/issues/46659 for more info.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "propagationPolicy": {
	//       "description": "Specifies the propagation policy of delete. Cloud Run currently ignores\nthis setting, and deletes in the background. Please see\nkubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ for\nmore information.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/domains.cloudrun.com/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.domainmappings.get":

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

// Get: Rpc to get information about a domain mapping.
func (r *NamespacesDomainmappingsService) Get(name string) *NamespacesDomainmappingsGetCall {
	c := &NamespacesDomainmappingsGetCall{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 *NamespacesDomainmappingsGetCall) Fields(s ...googleapi.Field) *NamespacesDomainmappingsGetCall {
	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 *NamespacesDomainmappingsGetCall) IfNoneMatch(entityTag string) *NamespacesDomainmappingsGetCall {
	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 *NamespacesDomainmappingsGetCall) Context(ctx context.Context) *NamespacesDomainmappingsGetCall {
	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 *NamespacesDomainmappingsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesDomainmappingsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/domains.cloudrun.com/v1alpha1/{+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 "run.namespaces.domainmappings.get" call.
// Exactly one of *DomainMapping or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DomainMapping.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 *NamespacesDomainmappingsGetCall) Do(opts ...googleapi.CallOption) (*DomainMapping, 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 := &DomainMapping{
		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": "Rpc to get information about a domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1alpha1/namespaces/{namespacesId}/domainmappings/{domainmappingsId}",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.domainmappings.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the domain mapping being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/domainmappings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/domains.cloudrun.com/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "DomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.domainmappings.list":

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

// List: Rpc to list domain mappings.
func (r *NamespacesDomainmappingsService) List(parent string) *NamespacesDomainmappingsListCall {
	c := &NamespacesDomainmappingsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *NamespacesDomainmappingsListCall) Continue(continue_ string) *NamespacesDomainmappingsListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *NamespacesDomainmappingsListCall) FieldSelector(fieldSelector string) *NamespacesDomainmappingsListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *NamespacesDomainmappingsListCall) IncludeUninitialized(includeUninitialized bool) *NamespacesDomainmappingsListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *NamespacesDomainmappingsListCall) LabelSelector(labelSelector string) *NamespacesDomainmappingsListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *NamespacesDomainmappingsListCall) Limit(limit int64) *NamespacesDomainmappingsListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *NamespacesDomainmappingsListCall) ResourceVersion(resourceVersion string) *NamespacesDomainmappingsListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *NamespacesDomainmappingsListCall) Watch(watch bool) *NamespacesDomainmappingsListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *NamespacesDomainmappingsListCall) Fields(s ...googleapi.Field) *NamespacesDomainmappingsListCall {
	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 *NamespacesDomainmappingsListCall) IfNoneMatch(entityTag string) *NamespacesDomainmappingsListCall {
	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 *NamespacesDomainmappingsListCall) Context(ctx context.Context) *NamespacesDomainmappingsListCall {
	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 *NamespacesDomainmappingsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.domainmappings.list" call.
// Exactly one of *ListDomainMappingsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListDomainMappingsResponse.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 *NamespacesDomainmappingsListCall) Do(opts ...googleapi.CallOption) (*ListDomainMappingsResponse, 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 := &ListDomainMappingsResponse{
		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": "Rpc to list domain mappings.",
	//   "flatPath": "apis/domains.cloudrun.com/v1alpha1/namespaces/{namespacesId}/domainmappings",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.domainmappings.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the domain mappings should be\nlisted.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "apis/domains.cloudrun.com/v1alpha1/{+parent}/domainmappings",
	//   "response": {
	//     "$ref": "ListDomainMappingsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.eventtypes.get":

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

// Get: Rpc to get information about an EventType.
func (r *NamespacesEventtypesService) Get(name string) *NamespacesEventtypesGetCall {
	c := &NamespacesEventtypesGetCall{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 *NamespacesEventtypesGetCall) Fields(s ...googleapi.Field) *NamespacesEventtypesGetCall {
	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 *NamespacesEventtypesGetCall) IfNoneMatch(entityTag string) *NamespacesEventtypesGetCall {
	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 *NamespacesEventtypesGetCall) Context(ctx context.Context) *NamespacesEventtypesGetCall {
	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 *NamespacesEventtypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesEventtypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/eventing.knative.dev/v1alpha1/{+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 "run.namespaces.eventtypes.get" call.
// Exactly one of *EventType or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *EventType.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 *NamespacesEventtypesGetCall) Do(opts ...googleapi.CallOption) (*EventType, 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 := &EventType{
		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": "Rpc to get information about an EventType.",
	//   "flatPath": "apis/eventing.knative.dev/v1alpha1/namespaces/{namespacesId}/eventtypes/{eventtypesId}",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.eventtypes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the trigger being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/eventtypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/eventing.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "EventType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.eventtypes.list":

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

// List: Rpc to list EventTypes.
func (r *NamespacesEventtypesService) List(parent string) *NamespacesEventtypesListCall {
	c := &NamespacesEventtypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *NamespacesEventtypesListCall) Continue(continue_ string) *NamespacesEventtypesListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *NamespacesEventtypesListCall) FieldSelector(fieldSelector string) *NamespacesEventtypesListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *NamespacesEventtypesListCall) IncludeUninitialized(includeUninitialized bool) *NamespacesEventtypesListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *NamespacesEventtypesListCall) LabelSelector(labelSelector string) *NamespacesEventtypesListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *NamespacesEventtypesListCall) Limit(limit int64) *NamespacesEventtypesListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *NamespacesEventtypesListCall) ResourceVersion(resourceVersion string) *NamespacesEventtypesListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *NamespacesEventtypesListCall) Watch(watch bool) *NamespacesEventtypesListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *NamespacesEventtypesListCall) Fields(s ...googleapi.Field) *NamespacesEventtypesListCall {
	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 *NamespacesEventtypesListCall) IfNoneMatch(entityTag string) *NamespacesEventtypesListCall {
	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 *NamespacesEventtypesListCall) Context(ctx context.Context) *NamespacesEventtypesListCall {
	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 *NamespacesEventtypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.eventtypes.list" call.
// Exactly one of *ListEventTypesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListEventTypesResponse.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 *NamespacesEventtypesListCall) Do(opts ...googleapi.CallOption) (*ListEventTypesResponse, 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 := &ListEventTypesResponse{
		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": "Rpc to list EventTypes.",
	//   "flatPath": "apis/eventing.knative.dev/v1alpha1/namespaces/{namespacesId}/eventtypes",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.eventtypes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the EventTypes should be\nlisted.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "apis/eventing.knative.dev/v1alpha1/{+parent}/eventtypes",
	//   "response": {
	//     "$ref": "ListEventTypesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.revisions.delete":

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

// Delete: Rpc to delete a revision.
func (r *NamespacesRevisionsService) Delete(name string) *NamespacesRevisionsDeleteCall {
	c := &NamespacesRevisionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ApiVersion sets the optional parameter "apiVersion": Cloud Run
// currently ignores this parameter.
func (c *NamespacesRevisionsDeleteCall) ApiVersion(apiVersion string) *NamespacesRevisionsDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *NamespacesRevisionsDeleteCall) Kind(kind string) *NamespacesRevisionsDeleteCall {
	c.urlParams_.Set("kind", kind)
	return c
}

// OrphanDependents sets the optional parameter "orphanDependents":
// Deprecated.
// Specifies the cascade behavior on delete.
// Cloud Run only supports cascading behavior, so this must be
// false.
// This attribute is deprecated, and is now replaced with
// PropagationPolicy
// See https://github.com/kubernetes/kubernetes/issues/46659 for more
// info.
func (c *NamespacesRevisionsDeleteCall) OrphanDependents(orphanDependents bool) *NamespacesRevisionsDeleteCall {
	c.urlParams_.Set("orphanDependents", fmt.Sprint(orphanDependents))
	return c
}

// PropagationPolicy sets the optional parameter "propagationPolicy":
// Specifies the propagation policy of delete. Cloud Run currently
// ignores
// this setting, and deletes in the background. Please
// see
// kubernetes.io/docs/concepts/workloads/controllers/garbage-collecti
// on/ for
// more information.
func (c *NamespacesRevisionsDeleteCall) PropagationPolicy(propagationPolicy string) *NamespacesRevisionsDeleteCall {
	c.urlParams_.Set("propagationPolicy", propagationPolicy)
	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 *NamespacesRevisionsDeleteCall) Fields(s ...googleapi.Field) *NamespacesRevisionsDeleteCall {
	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 *NamespacesRevisionsDeleteCall) Context(ctx context.Context) *NamespacesRevisionsDeleteCall {
	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 *NamespacesRevisionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesRevisionsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/serving.knative.dev/v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.revisions.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 *NamespacesRevisionsDeleteCall) 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": "Rpc to delete a revision.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/revisions/{revisionsId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.namespaces.revisions.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "apiVersion": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "kind": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the revision being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orphanDependents": {
	//       "description": "Deprecated.\nSpecifies the cascade behavior on delete.\nCloud Run only supports cascading behavior, so this must be false.\nThis attribute is deprecated, and is now replaced with PropagationPolicy\nSee https://github.com/kubernetes/kubernetes/issues/46659 for more info.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "propagationPolicy": {
	//       "description": "Specifies the propagation policy of delete. Cloud Run currently ignores\nthis setting, and deletes in the background. Please see\nkubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ for\nmore information.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.revisions.get":

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

// Get: Rpc to get information about a revision.
func (r *NamespacesRevisionsService) Get(name string) *NamespacesRevisionsGetCall {
	c := &NamespacesRevisionsGetCall{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 *NamespacesRevisionsGetCall) Fields(s ...googleapi.Field) *NamespacesRevisionsGetCall {
	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 *NamespacesRevisionsGetCall) IfNoneMatch(entityTag string) *NamespacesRevisionsGetCall {
	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 *NamespacesRevisionsGetCall) Context(ctx context.Context) *NamespacesRevisionsGetCall {
	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 *NamespacesRevisionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesRevisionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/serving.knative.dev/v1alpha1/{+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 "run.namespaces.revisions.get" call.
// Exactly one of *Revision or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Revision.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 *NamespacesRevisionsGetCall) Do(opts ...googleapi.CallOption) (*Revision, 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 := &Revision{
		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": "Rpc to get information about a revision.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/revisions/{revisionsId}",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.revisions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the revision being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Revision"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.revisions.list":

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

// List: Rpc to list revisions.
func (r *NamespacesRevisionsService) List(parent string) *NamespacesRevisionsListCall {
	c := &NamespacesRevisionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *NamespacesRevisionsListCall) Continue(continue_ string) *NamespacesRevisionsListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *NamespacesRevisionsListCall) FieldSelector(fieldSelector string) *NamespacesRevisionsListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *NamespacesRevisionsListCall) IncludeUninitialized(includeUninitialized bool) *NamespacesRevisionsListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *NamespacesRevisionsListCall) LabelSelector(labelSelector string) *NamespacesRevisionsListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *NamespacesRevisionsListCall) Limit(limit int64) *NamespacesRevisionsListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *NamespacesRevisionsListCall) ResourceVersion(resourceVersion string) *NamespacesRevisionsListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *NamespacesRevisionsListCall) Watch(watch bool) *NamespacesRevisionsListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *NamespacesRevisionsListCall) Fields(s ...googleapi.Field) *NamespacesRevisionsListCall {
	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 *NamespacesRevisionsListCall) IfNoneMatch(entityTag string) *NamespacesRevisionsListCall {
	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 *NamespacesRevisionsListCall) Context(ctx context.Context) *NamespacesRevisionsListCall {
	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 *NamespacesRevisionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.revisions.list" call.
// Exactly one of *ListRevisionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListRevisionsResponse.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 *NamespacesRevisionsListCall) Do(opts ...googleapi.CallOption) (*ListRevisionsResponse, 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 := &ListRevisionsResponse{
		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": "Rpc to list revisions.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/revisions",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.revisions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the revisions should be listed.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+parent}/revisions",
	//   "response": {
	//     "$ref": "ListRevisionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.routes.get":

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

// Get: Rpc to get information about a route.
func (r *NamespacesRoutesService) Get(name string) *NamespacesRoutesGetCall {
	c := &NamespacesRoutesGetCall{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 *NamespacesRoutesGetCall) Fields(s ...googleapi.Field) *NamespacesRoutesGetCall {
	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 *NamespacesRoutesGetCall) IfNoneMatch(entityTag string) *NamespacesRoutesGetCall {
	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 *NamespacesRoutesGetCall) Context(ctx context.Context) *NamespacesRoutesGetCall {
	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 *NamespacesRoutesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesRoutesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/serving.knative.dev/v1alpha1/{+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 "run.namespaces.routes.get" call.
// Exactly one of *Route or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Route.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 *NamespacesRoutesGetCall) Do(opts ...googleapi.CallOption) (*Route, 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 := &Route{
		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": "Rpc to get information about a route.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/routes/{routesId}",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.routes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the route being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/routes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Route"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.routes.list":

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

// List: Rpc to list routes.
func (r *NamespacesRoutesService) List(parent string) *NamespacesRoutesListCall {
	c := &NamespacesRoutesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *NamespacesRoutesListCall) Continue(continue_ string) *NamespacesRoutesListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *NamespacesRoutesListCall) FieldSelector(fieldSelector string) *NamespacesRoutesListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *NamespacesRoutesListCall) IncludeUninitialized(includeUninitialized bool) *NamespacesRoutesListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *NamespacesRoutesListCall) LabelSelector(labelSelector string) *NamespacesRoutesListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *NamespacesRoutesListCall) Limit(limit int64) *NamespacesRoutesListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *NamespacesRoutesListCall) ResourceVersion(resourceVersion string) *NamespacesRoutesListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *NamespacesRoutesListCall) Watch(watch bool) *NamespacesRoutesListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *NamespacesRoutesListCall) Fields(s ...googleapi.Field) *NamespacesRoutesListCall {
	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 *NamespacesRoutesListCall) IfNoneMatch(entityTag string) *NamespacesRoutesListCall {
	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 *NamespacesRoutesListCall) Context(ctx context.Context) *NamespacesRoutesListCall {
	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 *NamespacesRoutesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.routes.list" call.
// Exactly one of *ListRoutesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListRoutesResponse.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 *NamespacesRoutesListCall) Do(opts ...googleapi.CallOption) (*ListRoutesResponse, 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 := &ListRoutesResponse{
		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": "Rpc to list routes.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/routes",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.routes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the routes should be listed.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+parent}/routes",
	//   "response": {
	//     "$ref": "ListRoutesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.services.create":

type NamespacesServicesCreateCall struct {
	s          *APIService
	parent     string
	service    *Service
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Rpc to create a service.
func (r *NamespacesServicesService) Create(parent string, service *Service) *NamespacesServicesCreateCall {
	c := &NamespacesServicesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.service = service
	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 *NamespacesServicesCreateCall) Fields(s ...googleapi.Field) *NamespacesServicesCreateCall {
	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 *NamespacesServicesCreateCall) Context(ctx context.Context) *NamespacesServicesCreateCall {
	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 *NamespacesServicesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesServicesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.service)
	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, "apis/serving.knative.dev/v1alpha1/{+parent}/services")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.services.create" call.
// Exactly one of *Service or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Service.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 *NamespacesServicesCreateCall) Do(opts ...googleapi.CallOption) (*Service, 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 := &Service{
		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": "Rpc to create a service.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/services",
	//   "httpMethod": "POST",
	//   "id": "run.namespaces.services.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this service should be created.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+parent}/services",
	//   "request": {
	//     "$ref": "Service"
	//   },
	//   "response": {
	//     "$ref": "Service"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.services.delete":

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

// Delete: Rpc to delete a service.
// This will cause the Service to stop serving traffic and will delete
// the
// child entities like Routes, Configurations and Revisions.
func (r *NamespacesServicesService) Delete(name string) *NamespacesServicesDeleteCall {
	c := &NamespacesServicesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ApiVersion sets the optional parameter "apiVersion": Cloud Run
// currently ignores this parameter.
func (c *NamespacesServicesDeleteCall) ApiVersion(apiVersion string) *NamespacesServicesDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *NamespacesServicesDeleteCall) Kind(kind string) *NamespacesServicesDeleteCall {
	c.urlParams_.Set("kind", kind)
	return c
}

// OrphanDependents sets the optional parameter "orphanDependents":
// Deprecated.
// Specifies the cascade behavior on delete.
// Cloud Run only supports cascading behavior, so this must be
// false.
// This attribute is deprecated, and is now replaced with
// PropagationPolicy
// See https://github.com/kubernetes/kubernetes/issues/46659 for more
// info.
func (c *NamespacesServicesDeleteCall) OrphanDependents(orphanDependents bool) *NamespacesServicesDeleteCall {
	c.urlParams_.Set("orphanDependents", fmt.Sprint(orphanDependents))
	return c
}

// PropagationPolicy sets the optional parameter "propagationPolicy":
// Specifies the propagation policy of delete. Cloud Run currently
// ignores
// this setting, and deletes in the background. Please
// see
// kubernetes.io/docs/concepts/workloads/controllers/garbage-collecti
// on/ for
// more information.
func (c *NamespacesServicesDeleteCall) PropagationPolicy(propagationPolicy string) *NamespacesServicesDeleteCall {
	c.urlParams_.Set("propagationPolicy", propagationPolicy)
	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 *NamespacesServicesDeleteCall) Fields(s ...googleapi.Field) *NamespacesServicesDeleteCall {
	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 *NamespacesServicesDeleteCall) Context(ctx context.Context) *NamespacesServicesDeleteCall {
	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 *NamespacesServicesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesServicesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/serving.knative.dev/v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.services.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 *NamespacesServicesDeleteCall) 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": "Rpc to delete a service.\nThis will cause the Service to stop serving traffic and will delete the\nchild entities like Routes, Configurations and Revisions.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/services/{servicesId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.namespaces.services.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "apiVersion": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "kind": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the service being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orphanDependents": {
	//       "description": "Deprecated.\nSpecifies the cascade behavior on delete.\nCloud Run only supports cascading behavior, so this must be false.\nThis attribute is deprecated, and is now replaced with PropagationPolicy\nSee https://github.com/kubernetes/kubernetes/issues/46659 for more info.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "propagationPolicy": {
	//       "description": "Specifies the propagation policy of delete. Cloud Run currently ignores\nthis setting, and deletes in the background. Please see\nkubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ for\nmore information.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.services.get":

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

// Get: Rpc to get information about a service.
func (r *NamespacesServicesService) Get(name string) *NamespacesServicesGetCall {
	c := &NamespacesServicesGetCall{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 *NamespacesServicesGetCall) Fields(s ...googleapi.Field) *NamespacesServicesGetCall {
	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 *NamespacesServicesGetCall) IfNoneMatch(entityTag string) *NamespacesServicesGetCall {
	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 *NamespacesServicesGetCall) Context(ctx context.Context) *NamespacesServicesGetCall {
	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 *NamespacesServicesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesServicesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/serving.knative.dev/v1alpha1/{+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 "run.namespaces.services.get" call.
// Exactly one of *Service or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Service.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 *NamespacesServicesGetCall) Do(opts ...googleapi.CallOption) (*Service, 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 := &Service{
		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": "Rpc to get information about a service.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/services/{servicesId}",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.services.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the service being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Service"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.services.list":

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

// List: Rpc to list services.
func (r *NamespacesServicesService) List(parent string) *NamespacesServicesListCall {
	c := &NamespacesServicesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *NamespacesServicesListCall) Continue(continue_ string) *NamespacesServicesListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *NamespacesServicesListCall) FieldSelector(fieldSelector string) *NamespacesServicesListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *NamespacesServicesListCall) IncludeUninitialized(includeUninitialized bool) *NamespacesServicesListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *NamespacesServicesListCall) LabelSelector(labelSelector string) *NamespacesServicesListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *NamespacesServicesListCall) Limit(limit int64) *NamespacesServicesListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *NamespacesServicesListCall) ResourceVersion(resourceVersion string) *NamespacesServicesListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *NamespacesServicesListCall) Watch(watch bool) *NamespacesServicesListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *NamespacesServicesListCall) Fields(s ...googleapi.Field) *NamespacesServicesListCall {
	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 *NamespacesServicesListCall) IfNoneMatch(entityTag string) *NamespacesServicesListCall {
	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 *NamespacesServicesListCall) Context(ctx context.Context) *NamespacesServicesListCall {
	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 *NamespacesServicesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.services.list" call.
// Exactly one of *ListServicesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListServicesResponse.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 *NamespacesServicesListCall) Do(opts ...googleapi.CallOption) (*ListServicesResponse, 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 := &ListServicesResponse{
		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": "Rpc to list services.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/services",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.services.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the services should be listed.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+parent}/services",
	//   "response": {
	//     "$ref": "ListServicesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.services.replaceService":

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

// ReplaceService: Rpc to replace a service.
//
// Only the spec and metadata labels and annotations are modifiable.
// After
// the Update request, Cloud Run will work to make the 'status'
// match the requested 'spec'.
//
// May provide metadata.resourceVersion to enforce update from last read
// for
// optimistic concurrency control.
func (r *NamespacesServicesService) ReplaceService(name string, service *Service) *NamespacesServicesReplaceServiceCall {
	c := &NamespacesServicesReplaceServiceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.service = service
	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 *NamespacesServicesReplaceServiceCall) Fields(s ...googleapi.Field) *NamespacesServicesReplaceServiceCall {
	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 *NamespacesServicesReplaceServiceCall) Context(ctx context.Context) *NamespacesServicesReplaceServiceCall {
	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 *NamespacesServicesReplaceServiceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesServicesReplaceServiceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.service)
	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, "apis/serving.knative.dev/v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", 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 "run.namespaces.services.replaceService" call.
// Exactly one of *Service or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Service.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 *NamespacesServicesReplaceServiceCall) Do(opts ...googleapi.CallOption) (*Service, 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 := &Service{
		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": "Rpc to replace a service.\n\nOnly the spec and metadata labels and annotations are modifiable. After\nthe Update request, Cloud Run will work to make the 'status'\nmatch the requested 'spec'.\n\nMay provide metadata.resourceVersion to enforce update from last read for\noptimistic concurrency control.",
	//   "flatPath": "apis/serving.knative.dev/v1alpha1/namespaces/{namespacesId}/services/{servicesId}",
	//   "httpMethod": "PUT",
	//   "id": "run.namespaces.services.replaceService",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the service being replaced. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1alpha1/{+name}",
	//   "request": {
	//     "$ref": "Service"
	//   },
	//   "response": {
	//     "$ref": "Service"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.triggers.create":

type NamespacesTriggersCreateCall struct {
	s          *APIService
	parent     string
	trigger    *Trigger
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a new trigger.
func (r *NamespacesTriggersService) Create(parent string, trigger *Trigger) *NamespacesTriggersCreateCall {
	c := &NamespacesTriggersCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.trigger = trigger
	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 *NamespacesTriggersCreateCall) Fields(s ...googleapi.Field) *NamespacesTriggersCreateCall {
	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 *NamespacesTriggersCreateCall) Context(ctx context.Context) *NamespacesTriggersCreateCall {
	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 *NamespacesTriggersCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesTriggersCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.trigger)
	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, "apis/eventing.knative.dev/v1alpha1/{+parent}/triggers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.triggers.create" call.
// Exactly one of *Trigger or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Trigger.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 *NamespacesTriggersCreateCall) Do(opts ...googleapi.CallOption) (*Trigger, 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 := &Trigger{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a new trigger.",
	//   "flatPath": "apis/eventing.knative.dev/v1alpha1/namespaces/{namespacesId}/triggers",
	//   "httpMethod": "POST",
	//   "id": "run.namespaces.triggers.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this trigger should\nbe created.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/eventing.knative.dev/v1alpha1/{+parent}/triggers",
	//   "request": {
	//     "$ref": "Trigger"
	//   },
	//   "response": {
	//     "$ref": "Trigger"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.triggers.delete":

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

// Delete: Rpc to delete a trigger.
func (r *NamespacesTriggersService) Delete(name string) *NamespacesTriggersDeleteCall {
	c := &NamespacesTriggersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ApiVersion sets the optional parameter "apiVersion": Cloud Run
// currently ignores this parameter.
func (c *NamespacesTriggersDeleteCall) ApiVersion(apiVersion string) *NamespacesTriggersDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *NamespacesTriggersDeleteCall) Kind(kind string) *NamespacesTriggersDeleteCall {
	c.urlParams_.Set("kind", kind)
	return c
}

// PropagationPolicy sets the optional parameter "propagationPolicy":
// Specifies the propagation policy of delete. Cloud Run currently
// ignores
// this setting, and deletes in the background. Please
// see
// kubernetes.io/docs/concepts/workloads/controllers/garbage-collecti
// on/ for
// more information.
func (c *NamespacesTriggersDeleteCall) PropagationPolicy(propagationPolicy string) *NamespacesTriggersDeleteCall {
	c.urlParams_.Set("propagationPolicy", propagationPolicy)
	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 *NamespacesTriggersDeleteCall) Fields(s ...googleapi.Field) *NamespacesTriggersDeleteCall {
	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 *NamespacesTriggersDeleteCall) Context(ctx context.Context) *NamespacesTriggersDeleteCall {
	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 *NamespacesTriggersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesTriggersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/eventing.knative.dev/v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.triggers.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 *NamespacesTriggersDeleteCall) 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": "Rpc to delete a trigger.",
	//   "flatPath": "apis/eventing.knative.dev/v1alpha1/namespaces/{namespacesId}/triggers/{triggersId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.namespaces.triggers.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "apiVersion": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "kind": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the trigger being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/triggers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "propagationPolicy": {
	//       "description": "Specifies the propagation policy of delete. Cloud Run currently ignores\nthis setting, and deletes in the background. Please see\nkubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ for\nmore information.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/eventing.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.triggers.get":

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

// Get: Rpc to get information about a trigger.
func (r *NamespacesTriggersService) Get(name string) *NamespacesTriggersGetCall {
	c := &NamespacesTriggersGetCall{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 *NamespacesTriggersGetCall) Fields(s ...googleapi.Field) *NamespacesTriggersGetCall {
	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 *NamespacesTriggersGetCall) IfNoneMatch(entityTag string) *NamespacesTriggersGetCall {
	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 *NamespacesTriggersGetCall) Context(ctx context.Context) *NamespacesTriggersGetCall {
	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 *NamespacesTriggersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesTriggersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "apis/eventing.knative.dev/v1alpha1/{+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 "run.namespaces.triggers.get" call.
// Exactly one of *Trigger or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Trigger.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 *NamespacesTriggersGetCall) Do(opts ...googleapi.CallOption) (*Trigger, 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 := &Trigger{
		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": "Rpc to get information about a trigger.",
	//   "flatPath": "apis/eventing.knative.dev/v1alpha1/namespaces/{namespacesId}/triggers/{triggersId}",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.triggers.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the trigger being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/triggers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/eventing.knative.dev/v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Trigger"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.triggers.list":

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

// List: Rpc to list triggers.
func (r *NamespacesTriggersService) List(parent string) *NamespacesTriggersListCall {
	c := &NamespacesTriggersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *NamespacesTriggersListCall) Continue(continue_ string) *NamespacesTriggersListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *NamespacesTriggersListCall) FieldSelector(fieldSelector string) *NamespacesTriggersListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *NamespacesTriggersListCall) IncludeUninitialized(includeUninitialized bool) *NamespacesTriggersListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *NamespacesTriggersListCall) LabelSelector(labelSelector string) *NamespacesTriggersListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *NamespacesTriggersListCall) Limit(limit int64) *NamespacesTriggersListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *NamespacesTriggersListCall) ResourceVersion(resourceVersion string) *NamespacesTriggersListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *NamespacesTriggersListCall) Watch(watch bool) *NamespacesTriggersListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *NamespacesTriggersListCall) Fields(s ...googleapi.Field) *NamespacesTriggersListCall {
	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 *NamespacesTriggersListCall) IfNoneMatch(entityTag string) *NamespacesTriggersListCall {
	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 *NamespacesTriggersListCall) Context(ctx context.Context) *NamespacesTriggersListCall {
	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 *NamespacesTriggersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.triggers.list" call.
// Exactly one of *ListTriggersResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListTriggersResponse.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 *NamespacesTriggersListCall) Do(opts ...googleapi.CallOption) (*ListTriggersResponse, 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 := &ListTriggersResponse{
		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": "Rpc to list triggers.",
	//   "flatPath": "apis/eventing.knative.dev/v1alpha1/namespaces/{namespacesId}/triggers",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.triggers.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the triggers should\nbe listed.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "apis/eventing.knative.dev/v1alpha1/{+parent}/triggers",
	//   "response": {
	//     "$ref": "ListTriggersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.triggers.replaceTrigger":

type NamespacesTriggersReplaceTriggerCall struct {
	s          *APIService
	name       string
	trigger    *Trigger
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// ReplaceTrigger: Rpc to replace a trigger.
//
// Only the spec and metadata labels and annotations are modifiable.
// After
// the Update request, Cloud Run will work to make the 'status'
// match the requested 'spec'.
//
// May provide metadata.resourceVersion to enforce update from last read
// for
// optimistic concurrency control.
func (r *NamespacesTriggersService) ReplaceTrigger(name string, trigger *Trigger) *NamespacesTriggersReplaceTriggerCall {
	c := &NamespacesTriggersReplaceTriggerCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.trigger = trigger
	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 *NamespacesTriggersReplaceTriggerCall) Fields(s ...googleapi.Field) *NamespacesTriggersReplaceTriggerCall {
	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 *NamespacesTriggersReplaceTriggerCall) Context(ctx context.Context) *NamespacesTriggersReplaceTriggerCall {
	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 *NamespacesTriggersReplaceTriggerCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesTriggersReplaceTriggerCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.trigger)
	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, "apis/eventing.knative.dev/v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", 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 "run.namespaces.triggers.replaceTrigger" call.
// Exactly one of *Trigger or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Trigger.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 *NamespacesTriggersReplaceTriggerCall) Do(opts ...googleapi.CallOption) (*Trigger, 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 := &Trigger{
		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": "Rpc to replace a trigger.\n\nOnly the spec and metadata labels and annotations are modifiable. After\nthe Update request, Cloud Run will work to make the 'status'\nmatch the requested 'spec'.\n\nMay provide metadata.resourceVersion to enforce update from last read for\noptimistic concurrency control.",
	//   "flatPath": "apis/eventing.knative.dev/v1alpha1/namespaces/{namespacesId}/triggers/{triggersId}",
	//   "httpMethod": "PUT",
	//   "id": "run.namespaces.triggers.replaceTrigger",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the trigger being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/triggers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/eventing.knative.dev/v1alpha1/{+name}",
	//   "request": {
	//     "$ref": "Trigger"
	//   },
	//   "response": {
	//     "$ref": "Trigger"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.list":

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

// List: Lists information about the supported locations for this
// service.
func (r *ProjectsLocationsService) List(name string) *ProjectsLocationsListCall {
	c := &ProjectsLocationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

// PageToken sets the optional parameter "pageToken": The standard list
// page token.
func (c *ProjectsLocationsListCall) PageToken(pageToken string) *ProjectsLocationsListCall {
	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 *ProjectsLocationsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsListCall {
	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 *ProjectsLocationsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsListCall {
	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 *ProjectsLocationsListCall) Context(ctx context.Context) *ProjectsLocationsListCall {
	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 *ProjectsLocationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+name}/locations")
	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 "run.projects.locations.list" call.
// Exactly one of *ListLocationsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListLocationsResponse.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 *ProjectsLocationsListCall) Do(opts ...googleapi.CallOption) (*ListLocationsResponse, 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 := &ListLocationsResponse{
		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 information about the supported locations for this service.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The resource that owns the locations collection, if applicable.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The standard list page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}/locations",
	//   "response": {
	//     "$ref": "ListLocationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsListCall) Pages(ctx context.Context, f func(*ListLocationsResponse) 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 "run.projects.locations.authorizeddomains.list":

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

// List: RPC to list authorized domains.
func (r *ProjectsLocationsAuthorizeddomainsService) List(parent string) *ProjectsLocationsAuthorizeddomainsListCall {
	c := &ProjectsLocationsAuthorizeddomainsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum results to
// return per page.
func (c *ProjectsLocationsAuthorizeddomainsListCall) PageSize(pageSize int64) *ProjectsLocationsAuthorizeddomainsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Continuation token
// for fetching the next page of results.
func (c *ProjectsLocationsAuthorizeddomainsListCall) PageToken(pageToken string) *ProjectsLocationsAuthorizeddomainsListCall {
	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 *ProjectsLocationsAuthorizeddomainsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsAuthorizeddomainsListCall {
	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 *ProjectsLocationsAuthorizeddomainsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsAuthorizeddomainsListCall {
	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 *ProjectsLocationsAuthorizeddomainsListCall) Context(ctx context.Context) *ProjectsLocationsAuthorizeddomainsListCall {
	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 *ProjectsLocationsAuthorizeddomainsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.authorizeddomains.list" call.
// Exactly one of *ListAuthorizedDomainsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListAuthorizedDomainsResponse.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 *ProjectsLocationsAuthorizeddomainsListCall) Do(opts ...googleapi.CallOption) (*ListAuthorizedDomainsResponse, 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 := &ListAuthorizedDomainsResponse{
		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": "RPC to list authorized domains.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/authorizeddomains",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.authorizeddomains.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Maximum results to return per page.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Continuation token for fetching the next page of results.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Name of the parent Application resource. Example: `apps/myapp`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/authorizeddomains",
	//   "response": {
	//     "$ref": "ListAuthorizedDomainsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsAuthorizeddomainsListCall) Pages(ctx context.Context, f func(*ListAuthorizedDomainsResponse) 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 "run.projects.locations.configurations.get":

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

// Get: Rpc to get information about a configuration.
func (r *ProjectsLocationsConfigurationsService) Get(name string) *ProjectsLocationsConfigurationsGetCall {
	c := &ProjectsLocationsConfigurationsGetCall{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 *ProjectsLocationsConfigurationsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsConfigurationsGetCall {
	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 *ProjectsLocationsConfigurationsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsConfigurationsGetCall {
	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 *ProjectsLocationsConfigurationsGetCall) Context(ctx context.Context) *ProjectsLocationsConfigurationsGetCall {
	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 *ProjectsLocationsConfigurationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsConfigurationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+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 "run.projects.locations.configurations.get" call.
// Exactly one of *Configuration or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Configuration.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 *ProjectsLocationsConfigurationsGetCall) Do(opts ...googleapi.CallOption) (*Configuration, 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 := &Configuration{
		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": "Rpc to get information about a configuration.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/configurations/{configurationsId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.configurations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the configuration being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/configurations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Configuration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.configurations.list":

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

// List: Rpc to list configurations.
func (r *ProjectsLocationsConfigurationsService) List(parent string) *ProjectsLocationsConfigurationsListCall {
	c := &ProjectsLocationsConfigurationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *ProjectsLocationsConfigurationsListCall) Continue(continue_ string) *ProjectsLocationsConfigurationsListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsConfigurationsListCall) FieldSelector(fieldSelector string) *ProjectsLocationsConfigurationsListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *ProjectsLocationsConfigurationsListCall) IncludeUninitialized(includeUninitialized bool) *ProjectsLocationsConfigurationsListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *ProjectsLocationsConfigurationsListCall) LabelSelector(labelSelector string) *ProjectsLocationsConfigurationsListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *ProjectsLocationsConfigurationsListCall) Limit(limit int64) *ProjectsLocationsConfigurationsListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *ProjectsLocationsConfigurationsListCall) ResourceVersion(resourceVersion string) *ProjectsLocationsConfigurationsListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsConfigurationsListCall) Watch(watch bool) *ProjectsLocationsConfigurationsListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *ProjectsLocationsConfigurationsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsConfigurationsListCall {
	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 *ProjectsLocationsConfigurationsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsConfigurationsListCall {
	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 *ProjectsLocationsConfigurationsListCall) Context(ctx context.Context) *ProjectsLocationsConfigurationsListCall {
	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 *ProjectsLocationsConfigurationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.configurations.list" call.
// Exactly one of *ListConfigurationsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListConfigurationsResponse.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 *ProjectsLocationsConfigurationsListCall) Do(opts ...googleapi.CallOption) (*ListConfigurationsResponse, 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 := &ListConfigurationsResponse{
		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": "Rpc to list configurations.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/configurations",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.configurations.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the configurations should be\nlisted.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/configurations",
	//   "response": {
	//     "$ref": "ListConfigurationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.domainmappings.create":

type ProjectsLocationsDomainmappingsCreateCall struct {
	s             *APIService
	parent        string
	domainmapping *DomainMapping
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Create: Creates a new domain mapping.
func (r *ProjectsLocationsDomainmappingsService) Create(parent string, domainmapping *DomainMapping) *ProjectsLocationsDomainmappingsCreateCall {
	c := &ProjectsLocationsDomainmappingsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.domainmapping = domainmapping
	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 *ProjectsLocationsDomainmappingsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsDomainmappingsCreateCall {
	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 *ProjectsLocationsDomainmappingsCreateCall) Context(ctx context.Context) *ProjectsLocationsDomainmappingsCreateCall {
	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 *ProjectsLocationsDomainmappingsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.domainmappings.create" call.
// Exactly one of *DomainMapping or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DomainMapping.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 *ProjectsLocationsDomainmappingsCreateCall) Do(opts ...googleapi.CallOption) (*DomainMapping, 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 := &DomainMapping{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a new domain mapping.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/domainmappings",
	//   "httpMethod": "POST",
	//   "id": "run.projects.locations.domainmappings.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this domain mapping should be\ncreated.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/domainmappings",
	//   "request": {
	//     "$ref": "DomainMapping"
	//   },
	//   "response": {
	//     "$ref": "DomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.domainmappings.delete":

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

// Delete: Rpc to delete a domain mapping.
func (r *ProjectsLocationsDomainmappingsService) Delete(name string) *ProjectsLocationsDomainmappingsDeleteCall {
	c := &ProjectsLocationsDomainmappingsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ApiVersion sets the optional parameter "apiVersion": Cloud Run
// currently ignores this parameter.
func (c *ProjectsLocationsDomainmappingsDeleteCall) ApiVersion(apiVersion string) *ProjectsLocationsDomainmappingsDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *ProjectsLocationsDomainmappingsDeleteCall) Kind(kind string) *ProjectsLocationsDomainmappingsDeleteCall {
	c.urlParams_.Set("kind", kind)
	return c
}

// OrphanDependents sets the optional parameter "orphanDependents":
// Deprecated.
// Specifies the cascade behavior on delete.
// Cloud Run only supports cascading behavior, so this must be
// false.
// This attribute is deprecated, and is now replaced with
// PropagationPolicy
// See https://github.com/kubernetes/kubernetes/issues/46659 for more
// info.
func (c *ProjectsLocationsDomainmappingsDeleteCall) OrphanDependents(orphanDependents bool) *ProjectsLocationsDomainmappingsDeleteCall {
	c.urlParams_.Set("orphanDependents", fmt.Sprint(orphanDependents))
	return c
}

// PropagationPolicy sets the optional parameter "propagationPolicy":
// Specifies the propagation policy of delete. Cloud Run currently
// ignores
// this setting, and deletes in the background. Please
// see
// kubernetes.io/docs/concepts/workloads/controllers/garbage-collecti
// on/ for
// more information.
func (c *ProjectsLocationsDomainmappingsDeleteCall) PropagationPolicy(propagationPolicy string) *ProjectsLocationsDomainmappingsDeleteCall {
	c.urlParams_.Set("propagationPolicy", propagationPolicy)
	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 *ProjectsLocationsDomainmappingsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsDomainmappingsDeleteCall {
	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 *ProjectsLocationsDomainmappingsDeleteCall) Context(ctx context.Context) *ProjectsLocationsDomainmappingsDeleteCall {
	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 *ProjectsLocationsDomainmappingsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.domainmappings.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 *ProjectsLocationsDomainmappingsDeleteCall) 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": "Rpc to delete a domain mapping.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/domainmappings/{domainmappingsId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.projects.locations.domainmappings.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "apiVersion": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "kind": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the domain mapping being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/domainmappings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orphanDependents": {
	//       "description": "Deprecated.\nSpecifies the cascade behavior on delete.\nCloud Run only supports cascading behavior, so this must be false.\nThis attribute is deprecated, and is now replaced with PropagationPolicy\nSee https://github.com/kubernetes/kubernetes/issues/46659 for more info.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "propagationPolicy": {
	//       "description": "Specifies the propagation policy of delete. Cloud Run currently ignores\nthis setting, and deletes in the background. Please see\nkubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ for\nmore information.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.domainmappings.get":

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

// Get: Rpc to get information about a domain mapping.
func (r *ProjectsLocationsDomainmappingsService) Get(name string) *ProjectsLocationsDomainmappingsGetCall {
	c := &ProjectsLocationsDomainmappingsGetCall{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 *ProjectsLocationsDomainmappingsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsDomainmappingsGetCall {
	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 *ProjectsLocationsDomainmappingsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsDomainmappingsGetCall {
	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 *ProjectsLocationsDomainmappingsGetCall) Context(ctx context.Context) *ProjectsLocationsDomainmappingsGetCall {
	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 *ProjectsLocationsDomainmappingsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsDomainmappingsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+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 "run.projects.locations.domainmappings.get" call.
// Exactly one of *DomainMapping or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DomainMapping.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 *ProjectsLocationsDomainmappingsGetCall) Do(opts ...googleapi.CallOption) (*DomainMapping, 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 := &DomainMapping{
		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": "Rpc to get information about a domain mapping.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/domainmappings/{domainmappingsId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.domainmappings.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the domain mapping being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/domainmappings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "DomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.domainmappings.list":

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

// List: Rpc to list domain mappings.
func (r *ProjectsLocationsDomainmappingsService) List(parent string) *ProjectsLocationsDomainmappingsListCall {
	c := &ProjectsLocationsDomainmappingsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *ProjectsLocationsDomainmappingsListCall) Continue(continue_ string) *ProjectsLocationsDomainmappingsListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsDomainmappingsListCall) FieldSelector(fieldSelector string) *ProjectsLocationsDomainmappingsListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *ProjectsLocationsDomainmappingsListCall) IncludeUninitialized(includeUninitialized bool) *ProjectsLocationsDomainmappingsListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *ProjectsLocationsDomainmappingsListCall) LabelSelector(labelSelector string) *ProjectsLocationsDomainmappingsListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *ProjectsLocationsDomainmappingsListCall) Limit(limit int64) *ProjectsLocationsDomainmappingsListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *ProjectsLocationsDomainmappingsListCall) ResourceVersion(resourceVersion string) *ProjectsLocationsDomainmappingsListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsDomainmappingsListCall) Watch(watch bool) *ProjectsLocationsDomainmappingsListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *ProjectsLocationsDomainmappingsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsDomainmappingsListCall {
	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 *ProjectsLocationsDomainmappingsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsDomainmappingsListCall {
	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 *ProjectsLocationsDomainmappingsListCall) Context(ctx context.Context) *ProjectsLocationsDomainmappingsListCall {
	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 *ProjectsLocationsDomainmappingsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.domainmappings.list" call.
// Exactly one of *ListDomainMappingsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListDomainMappingsResponse.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 *ProjectsLocationsDomainmappingsListCall) Do(opts ...googleapi.CallOption) (*ListDomainMappingsResponse, 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 := &ListDomainMappingsResponse{
		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": "Rpc to list domain mappings.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/domainmappings",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.domainmappings.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the domain mappings should be\nlisted.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/domainmappings",
	//   "response": {
	//     "$ref": "ListDomainMappingsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.eventtypes.get":

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

// Get: Rpc to get information about an EventType.
func (r *ProjectsLocationsEventtypesService) Get(name string) *ProjectsLocationsEventtypesGetCall {
	c := &ProjectsLocationsEventtypesGetCall{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 *ProjectsLocationsEventtypesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsEventtypesGetCall {
	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 *ProjectsLocationsEventtypesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsEventtypesGetCall {
	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 *ProjectsLocationsEventtypesGetCall) Context(ctx context.Context) *ProjectsLocationsEventtypesGetCall {
	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 *ProjectsLocationsEventtypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsEventtypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+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 "run.projects.locations.eventtypes.get" call.
// Exactly one of *EventType or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *EventType.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 *ProjectsLocationsEventtypesGetCall) Do(opts ...googleapi.CallOption) (*EventType, 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 := &EventType{
		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": "Rpc to get information about an EventType.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/eventtypes/{eventtypesId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.eventtypes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the trigger being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/eventtypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "EventType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.eventtypes.list":

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

// List: Rpc to list EventTypes.
func (r *ProjectsLocationsEventtypesService) List(parent string) *ProjectsLocationsEventtypesListCall {
	c := &ProjectsLocationsEventtypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *ProjectsLocationsEventtypesListCall) Continue(continue_ string) *ProjectsLocationsEventtypesListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsEventtypesListCall) FieldSelector(fieldSelector string) *ProjectsLocationsEventtypesListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *ProjectsLocationsEventtypesListCall) IncludeUninitialized(includeUninitialized bool) *ProjectsLocationsEventtypesListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *ProjectsLocationsEventtypesListCall) LabelSelector(labelSelector string) *ProjectsLocationsEventtypesListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *ProjectsLocationsEventtypesListCall) Limit(limit int64) *ProjectsLocationsEventtypesListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *ProjectsLocationsEventtypesListCall) ResourceVersion(resourceVersion string) *ProjectsLocationsEventtypesListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsEventtypesListCall) Watch(watch bool) *ProjectsLocationsEventtypesListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *ProjectsLocationsEventtypesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsEventtypesListCall {
	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 *ProjectsLocationsEventtypesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsEventtypesListCall {
	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 *ProjectsLocationsEventtypesListCall) Context(ctx context.Context) *ProjectsLocationsEventtypesListCall {
	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 *ProjectsLocationsEventtypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.eventtypes.list" call.
// Exactly one of *ListEventTypesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListEventTypesResponse.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 *ProjectsLocationsEventtypesListCall) Do(opts ...googleapi.CallOption) (*ListEventTypesResponse, 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 := &ListEventTypesResponse{
		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": "Rpc to list EventTypes.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/eventtypes",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.eventtypes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the EventTypes should be\nlisted.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/eventtypes",
	//   "response": {
	//     "$ref": "ListEventTypesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.revisions.delete":

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

// Delete: Rpc to delete a revision.
func (r *ProjectsLocationsRevisionsService) Delete(name string) *ProjectsLocationsRevisionsDeleteCall {
	c := &ProjectsLocationsRevisionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ApiVersion sets the optional parameter "apiVersion": Cloud Run
// currently ignores this parameter.
func (c *ProjectsLocationsRevisionsDeleteCall) ApiVersion(apiVersion string) *ProjectsLocationsRevisionsDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *ProjectsLocationsRevisionsDeleteCall) Kind(kind string) *ProjectsLocationsRevisionsDeleteCall {
	c.urlParams_.Set("kind", kind)
	return c
}

// OrphanDependents sets the optional parameter "orphanDependents":
// Deprecated.
// Specifies the cascade behavior on delete.
// Cloud Run only supports cascading behavior, so this must be
// false.
// This attribute is deprecated, and is now replaced with
// PropagationPolicy
// See https://github.com/kubernetes/kubernetes/issues/46659 for more
// info.
func (c *ProjectsLocationsRevisionsDeleteCall) OrphanDependents(orphanDependents bool) *ProjectsLocationsRevisionsDeleteCall {
	c.urlParams_.Set("orphanDependents", fmt.Sprint(orphanDependents))
	return c
}

// PropagationPolicy sets the optional parameter "propagationPolicy":
// Specifies the propagation policy of delete. Cloud Run currently
// ignores
// this setting, and deletes in the background. Please
// see
// kubernetes.io/docs/concepts/workloads/controllers/garbage-collecti
// on/ for
// more information.
func (c *ProjectsLocationsRevisionsDeleteCall) PropagationPolicy(propagationPolicy string) *ProjectsLocationsRevisionsDeleteCall {
	c.urlParams_.Set("propagationPolicy", propagationPolicy)
	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 *ProjectsLocationsRevisionsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsRevisionsDeleteCall {
	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 *ProjectsLocationsRevisionsDeleteCall) Context(ctx context.Context) *ProjectsLocationsRevisionsDeleteCall {
	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 *ProjectsLocationsRevisionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.revisions.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 *ProjectsLocationsRevisionsDeleteCall) 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": "Rpc to delete a revision.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/revisions/{revisionsId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.projects.locations.revisions.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "apiVersion": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "kind": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the revision being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orphanDependents": {
	//       "description": "Deprecated.\nSpecifies the cascade behavior on delete.\nCloud Run only supports cascading behavior, so this must be false.\nThis attribute is deprecated, and is now replaced with PropagationPolicy\nSee https://github.com/kubernetes/kubernetes/issues/46659 for more info.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "propagationPolicy": {
	//       "description": "Specifies the propagation policy of delete. Cloud Run currently ignores\nthis setting, and deletes in the background. Please see\nkubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ for\nmore information.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.revisions.get":

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

// Get: Rpc to get information about a revision.
func (r *ProjectsLocationsRevisionsService) Get(name string) *ProjectsLocationsRevisionsGetCall {
	c := &ProjectsLocationsRevisionsGetCall{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 *ProjectsLocationsRevisionsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsRevisionsGetCall {
	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 *ProjectsLocationsRevisionsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsRevisionsGetCall {
	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 *ProjectsLocationsRevisionsGetCall) Context(ctx context.Context) *ProjectsLocationsRevisionsGetCall {
	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 *ProjectsLocationsRevisionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsRevisionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+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 "run.projects.locations.revisions.get" call.
// Exactly one of *Revision or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Revision.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 *ProjectsLocationsRevisionsGetCall) Do(opts ...googleapi.CallOption) (*Revision, 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 := &Revision{
		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": "Rpc to get information about a revision.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/revisions/{revisionsId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.revisions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the revision being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/revisions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Revision"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.revisions.list":

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

// List: Rpc to list revisions.
func (r *ProjectsLocationsRevisionsService) List(parent string) *ProjectsLocationsRevisionsListCall {
	c := &ProjectsLocationsRevisionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *ProjectsLocationsRevisionsListCall) Continue(continue_ string) *ProjectsLocationsRevisionsListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsRevisionsListCall) FieldSelector(fieldSelector string) *ProjectsLocationsRevisionsListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *ProjectsLocationsRevisionsListCall) IncludeUninitialized(includeUninitialized bool) *ProjectsLocationsRevisionsListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *ProjectsLocationsRevisionsListCall) LabelSelector(labelSelector string) *ProjectsLocationsRevisionsListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *ProjectsLocationsRevisionsListCall) Limit(limit int64) *ProjectsLocationsRevisionsListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *ProjectsLocationsRevisionsListCall) ResourceVersion(resourceVersion string) *ProjectsLocationsRevisionsListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsRevisionsListCall) Watch(watch bool) *ProjectsLocationsRevisionsListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *ProjectsLocationsRevisionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsRevisionsListCall {
	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 *ProjectsLocationsRevisionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsRevisionsListCall {
	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 *ProjectsLocationsRevisionsListCall) Context(ctx context.Context) *ProjectsLocationsRevisionsListCall {
	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 *ProjectsLocationsRevisionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.revisions.list" call.
// Exactly one of *ListRevisionsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListRevisionsResponse.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 *ProjectsLocationsRevisionsListCall) Do(opts ...googleapi.CallOption) (*ListRevisionsResponse, 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 := &ListRevisionsResponse{
		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": "Rpc to list revisions.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/revisions",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.revisions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the revisions should be listed.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/revisions",
	//   "response": {
	//     "$ref": "ListRevisionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.routes.get":

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

// Get: Rpc to get information about a route.
func (r *ProjectsLocationsRoutesService) Get(name string) *ProjectsLocationsRoutesGetCall {
	c := &ProjectsLocationsRoutesGetCall{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 *ProjectsLocationsRoutesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsRoutesGetCall {
	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 *ProjectsLocationsRoutesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsRoutesGetCall {
	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 *ProjectsLocationsRoutesGetCall) Context(ctx context.Context) *ProjectsLocationsRoutesGetCall {
	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 *ProjectsLocationsRoutesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsRoutesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+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 "run.projects.locations.routes.get" call.
// Exactly one of *Route or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Route.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 *ProjectsLocationsRoutesGetCall) Do(opts ...googleapi.CallOption) (*Route, 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 := &Route{
		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": "Rpc to get information about a route.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/routes/{routesId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.routes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the route being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/routes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Route"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.routes.list":

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

// List: Rpc to list routes.
func (r *ProjectsLocationsRoutesService) List(parent string) *ProjectsLocationsRoutesListCall {
	c := &ProjectsLocationsRoutesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *ProjectsLocationsRoutesListCall) Continue(continue_ string) *ProjectsLocationsRoutesListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsRoutesListCall) FieldSelector(fieldSelector string) *ProjectsLocationsRoutesListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *ProjectsLocationsRoutesListCall) IncludeUninitialized(includeUninitialized bool) *ProjectsLocationsRoutesListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *ProjectsLocationsRoutesListCall) LabelSelector(labelSelector string) *ProjectsLocationsRoutesListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *ProjectsLocationsRoutesListCall) Limit(limit int64) *ProjectsLocationsRoutesListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *ProjectsLocationsRoutesListCall) ResourceVersion(resourceVersion string) *ProjectsLocationsRoutesListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsRoutesListCall) Watch(watch bool) *ProjectsLocationsRoutesListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *ProjectsLocationsRoutesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsRoutesListCall {
	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 *ProjectsLocationsRoutesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsRoutesListCall {
	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 *ProjectsLocationsRoutesListCall) Context(ctx context.Context) *ProjectsLocationsRoutesListCall {
	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 *ProjectsLocationsRoutesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.routes.list" call.
// Exactly one of *ListRoutesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListRoutesResponse.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 *ProjectsLocationsRoutesListCall) Do(opts ...googleapi.CallOption) (*ListRoutesResponse, 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 := &ListRoutesResponse{
		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": "Rpc to list routes.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/routes",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.routes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the routes should be listed.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/routes",
	//   "response": {
	//     "$ref": "ListRoutesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.services.create":

type ProjectsLocationsServicesCreateCall struct {
	s          *APIService
	parent     string
	service    *Service
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Rpc to create a service.
func (r *ProjectsLocationsServicesService) Create(parent string, service *Service) *ProjectsLocationsServicesCreateCall {
	c := &ProjectsLocationsServicesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.service = service
	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 *ProjectsLocationsServicesCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsServicesCreateCall {
	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 *ProjectsLocationsServicesCreateCall) Context(ctx context.Context) *ProjectsLocationsServicesCreateCall {
	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 *ProjectsLocationsServicesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.services.create" call.
// Exactly one of *Service or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Service.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 *ProjectsLocationsServicesCreateCall) Do(opts ...googleapi.CallOption) (*Service, 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 := &Service{
		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": "Rpc to create a service.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/services",
	//   "httpMethod": "POST",
	//   "id": "run.projects.locations.services.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this service should be created.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/services",
	//   "request": {
	//     "$ref": "Service"
	//   },
	//   "response": {
	//     "$ref": "Service"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.services.delete":

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

// Delete: Rpc to delete a service.
// This will cause the Service to stop serving traffic and will delete
// the
// child entities like Routes, Configurations and Revisions.
func (r *ProjectsLocationsServicesService) Delete(name string) *ProjectsLocationsServicesDeleteCall {
	c := &ProjectsLocationsServicesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ApiVersion sets the optional parameter "apiVersion": Cloud Run
// currently ignores this parameter.
func (c *ProjectsLocationsServicesDeleteCall) ApiVersion(apiVersion string) *ProjectsLocationsServicesDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *ProjectsLocationsServicesDeleteCall) Kind(kind string) *ProjectsLocationsServicesDeleteCall {
	c.urlParams_.Set("kind", kind)
	return c
}

// OrphanDependents sets the optional parameter "orphanDependents":
// Deprecated.
// Specifies the cascade behavior on delete.
// Cloud Run only supports cascading behavior, so this must be
// false.
// This attribute is deprecated, and is now replaced with
// PropagationPolicy
// See https://github.com/kubernetes/kubernetes/issues/46659 for more
// info.
func (c *ProjectsLocationsServicesDeleteCall) OrphanDependents(orphanDependents bool) *ProjectsLocationsServicesDeleteCall {
	c.urlParams_.Set("orphanDependents", fmt.Sprint(orphanDependents))
	return c
}

// PropagationPolicy sets the optional parameter "propagationPolicy":
// Specifies the propagation policy of delete. Cloud Run currently
// ignores
// this setting, and deletes in the background. Please
// see
// kubernetes.io/docs/concepts/workloads/controllers/garbage-collecti
// on/ for
// more information.
func (c *ProjectsLocationsServicesDeleteCall) PropagationPolicy(propagationPolicy string) *ProjectsLocationsServicesDeleteCall {
	c.urlParams_.Set("propagationPolicy", propagationPolicy)
	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 *ProjectsLocationsServicesDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsServicesDeleteCall {
	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 *ProjectsLocationsServicesDeleteCall) Context(ctx context.Context) *ProjectsLocationsServicesDeleteCall {
	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 *ProjectsLocationsServicesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.services.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 *ProjectsLocationsServicesDeleteCall) 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": "Rpc to delete a service.\nThis will cause the Service to stop serving traffic and will delete the\nchild entities like Routes, Configurations and Revisions.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/services/{servicesId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.projects.locations.services.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "apiVersion": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "kind": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the service being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orphanDependents": {
	//       "description": "Deprecated.\nSpecifies the cascade behavior on delete.\nCloud Run only supports cascading behavior, so this must be false.\nThis attribute is deprecated, and is now replaced with PropagationPolicy\nSee https://github.com/kubernetes/kubernetes/issues/46659 for more info.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "propagationPolicy": {
	//       "description": "Specifies the propagation policy of delete. Cloud Run currently ignores\nthis setting, and deletes in the background. Please see\nkubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ for\nmore information.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.services.get":

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

// Get: Rpc to get information about a service.
func (r *ProjectsLocationsServicesService) Get(name string) *ProjectsLocationsServicesGetCall {
	c := &ProjectsLocationsServicesGetCall{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 *ProjectsLocationsServicesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsServicesGetCall {
	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 *ProjectsLocationsServicesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsServicesGetCall {
	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 *ProjectsLocationsServicesGetCall) Context(ctx context.Context) *ProjectsLocationsServicesGetCall {
	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 *ProjectsLocationsServicesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsServicesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+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 "run.projects.locations.services.get" call.
// Exactly one of *Service or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Service.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 *ProjectsLocationsServicesGetCall) Do(opts ...googleapi.CallOption) (*Service, 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 := &Service{
		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": "Rpc to get information about a service.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/services/{servicesId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.services.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the service being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Service"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.services.getIamPolicy":

type ProjectsLocationsServicesGetIamPolicyCall struct {
	s            *APIService
	resource     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetIamPolicy: Get the IAM Access Control policy currently in effect
// for the given
// Cloud Run service. This result does not include any inherited
// policies.
func (r *ProjectsLocationsServicesService) GetIamPolicy(resource string) *ProjectsLocationsServicesGetIamPolicyCall {
	c := &ProjectsLocationsServicesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// OptionsRequestedPolicyVersion sets the optional parameter
// "options.requestedPolicyVersion": The policy format version to be
// returned.
//
// Valid values are 0, 1, and 3. Requests specifying an invalid value
// will be
// rejected.
//
// Requests for policies with any conditional bindings must specify
// version 3.
// Policies without any conditional bindings may specify any valid value
// or
// leave the field unset.
func (c *ProjectsLocationsServicesGetIamPolicyCall) OptionsRequestedPolicyVersion(optionsRequestedPolicyVersion int64) *ProjectsLocationsServicesGetIamPolicyCall {
	c.urlParams_.Set("options.requestedPolicyVersion", fmt.Sprint(optionsRequestedPolicyVersion))
	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 *ProjectsLocationsServicesGetIamPolicyCall) Fields(s ...googleapi.Field) *ProjectsLocationsServicesGetIamPolicyCall {
	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 *ProjectsLocationsServicesGetIamPolicyCall) IfNoneMatch(entityTag string) *ProjectsLocationsServicesGetIamPolicyCall {
	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 *ProjectsLocationsServicesGetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsServicesGetIamPolicyCall {
	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 *ProjectsLocationsServicesGetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsServicesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+resource}:getIamPolicy")
	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{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.services.getIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.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 *ProjectsLocationsServicesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, 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 := &Policy{
		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": "Get the IAM Access Control policy currently in effect for the given\nCloud Run service. This result does not include any inherited policies.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/services/{servicesId}:getIamPolicy",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.services.getIamPolicy",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "options.requestedPolicyVersion": {
	//       "description": "Optional. The policy format version to be returned.\n\nValid values are 0, 1, and 3. Requests specifying an invalid value will be\nrejected.\n\nRequests for policies with any conditional bindings must specify version 3.\nPolicies without any conditional bindings may specify any valid value or\nleave the field unset.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy is being requested.\nSee the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+resource}:getIamPolicy",
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.services.list":

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

// List: Rpc to list services.
func (r *ProjectsLocationsServicesService) List(parent string) *ProjectsLocationsServicesListCall {
	c := &ProjectsLocationsServicesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *ProjectsLocationsServicesListCall) Continue(continue_ string) *ProjectsLocationsServicesListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsServicesListCall) FieldSelector(fieldSelector string) *ProjectsLocationsServicesListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *ProjectsLocationsServicesListCall) IncludeUninitialized(includeUninitialized bool) *ProjectsLocationsServicesListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *ProjectsLocationsServicesListCall) LabelSelector(labelSelector string) *ProjectsLocationsServicesListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *ProjectsLocationsServicesListCall) Limit(limit int64) *ProjectsLocationsServicesListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *ProjectsLocationsServicesListCall) ResourceVersion(resourceVersion string) *ProjectsLocationsServicesListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsServicesListCall) Watch(watch bool) *ProjectsLocationsServicesListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *ProjectsLocationsServicesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsServicesListCall {
	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 *ProjectsLocationsServicesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsServicesListCall {
	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 *ProjectsLocationsServicesListCall) Context(ctx context.Context) *ProjectsLocationsServicesListCall {
	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 *ProjectsLocationsServicesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.services.list" call.
// Exactly one of *ListServicesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListServicesResponse.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 *ProjectsLocationsServicesListCall) Do(opts ...googleapi.CallOption) (*ListServicesResponse, 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 := &ListServicesResponse{
		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": "Rpc to list services.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/services",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.services.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the services should be listed.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/services",
	//   "response": {
	//     "$ref": "ListServicesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.services.replaceService":

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

// ReplaceService: Rpc to replace a service.
//
// Only the spec and metadata labels and annotations are modifiable.
// After
// the Update request, Cloud Run will work to make the 'status'
// match the requested 'spec'.
//
// May provide metadata.resourceVersion to enforce update from last read
// for
// optimistic concurrency control.
func (r *ProjectsLocationsServicesService) ReplaceService(name string, service *Service) *ProjectsLocationsServicesReplaceServiceCall {
	c := &ProjectsLocationsServicesReplaceServiceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.service = service
	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 *ProjectsLocationsServicesReplaceServiceCall) Fields(s ...googleapi.Field) *ProjectsLocationsServicesReplaceServiceCall {
	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 *ProjectsLocationsServicesReplaceServiceCall) Context(ctx context.Context) *ProjectsLocationsServicesReplaceServiceCall {
	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 *ProjectsLocationsServicesReplaceServiceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsServicesReplaceServiceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.service)
	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, "v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", 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 "run.projects.locations.services.replaceService" call.
// Exactly one of *Service or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Service.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 *ProjectsLocationsServicesReplaceServiceCall) Do(opts ...googleapi.CallOption) (*Service, 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 := &Service{
		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": "Rpc to replace a service.\n\nOnly the spec and metadata labels and annotations are modifiable. After\nthe Update request, Cloud Run will work to make the 'status'\nmatch the requested 'spec'.\n\nMay provide metadata.resourceVersion to enforce update from last read for\noptimistic concurrency control.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/services/{servicesId}",
	//   "httpMethod": "PUT",
	//   "id": "run.projects.locations.services.replaceService",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the service being replaced. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "request": {
	//     "$ref": "Service"
	//   },
	//   "response": {
	//     "$ref": "Service"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.services.setIamPolicy":

type ProjectsLocationsServicesSetIamPolicyCall struct {
	s                   *APIService
	resource            string
	setiampolicyrequest *SetIamPolicyRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// SetIamPolicy: Sets the IAM Access control policy for the specified
// Service. Overwrites
// any existing policy.
func (r *ProjectsLocationsServicesService) SetIamPolicy(resource string, setiampolicyrequest *SetIamPolicyRequest) *ProjectsLocationsServicesSetIamPolicyCall {
	c := &ProjectsLocationsServicesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.setiampolicyrequest = setiampolicyrequest
	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 *ProjectsLocationsServicesSetIamPolicyCall) Fields(s ...googleapi.Field) *ProjectsLocationsServicesSetIamPolicyCall {
	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 *ProjectsLocationsServicesSetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsServicesSetIamPolicyCall {
	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 *ProjectsLocationsServicesSetIamPolicyCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsServicesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.setiampolicyrequest)
	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, "v1alpha1/{+resource}:setIamPolicy")
	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{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.services.setIamPolicy" call.
// Exactly one of *Policy or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Policy.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 *ProjectsLocationsServicesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, 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 := &Policy{
		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 the IAM Access control policy for the specified Service. Overwrites\nany existing policy.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/services/{servicesId}:setIamPolicy",
	//   "httpMethod": "POST",
	//   "id": "run.projects.locations.services.setIamPolicy",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy is being specified.\nSee the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+resource}:setIamPolicy",
	//   "request": {
	//     "$ref": "SetIamPolicyRequest"
	//   },
	//   "response": {
	//     "$ref": "Policy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.services.testIamPermissions":

type ProjectsLocationsServicesTestIamPermissionsCall struct {
	s                         *APIService
	resource                  string
	testiampermissionsrequest *TestIamPermissionsRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the
// specified Project.
//
// There are no permissions required for making this API call.
func (r *ProjectsLocationsServicesService) TestIamPermissions(resource string, testiampermissionsrequest *TestIamPermissionsRequest) *ProjectsLocationsServicesTestIamPermissionsCall {
	c := &ProjectsLocationsServicesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.testiampermissionsrequest = testiampermissionsrequest
	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 *ProjectsLocationsServicesTestIamPermissionsCall) Fields(s ...googleapi.Field) *ProjectsLocationsServicesTestIamPermissionsCall {
	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 *ProjectsLocationsServicesTestIamPermissionsCall) Context(ctx context.Context) *ProjectsLocationsServicesTestIamPermissionsCall {
	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 *ProjectsLocationsServicesTestIamPermissionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsServicesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.testiampermissionsrequest)
	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, "v1alpha1/{+resource}:testIamPermissions")
	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{
		"resource": c.resource,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.services.testIamPermissions" call.
// Exactly one of *TestIamPermissionsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *TestIamPermissionsResponse.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 *ProjectsLocationsServicesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, 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 := &TestIamPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns permissions that a caller has on the specified Project.\n\nThere are no permissions required for making this API call.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/services/{servicesId}:testIamPermissions",
	//   "httpMethod": "POST",
	//   "id": "run.projects.locations.services.testIamPermissions",
	//   "parameterOrder": [
	//     "resource"
	//   ],
	//   "parameters": {
	//     "resource": {
	//       "description": "REQUIRED: The resource for which the policy detail is being requested.\nSee the operation documentation for the appropriate value for this field.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/services/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+resource}:testIamPermissions",
	//   "request": {
	//     "$ref": "TestIamPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestIamPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.triggers.create":

type ProjectsLocationsTriggersCreateCall struct {
	s          *APIService
	parent     string
	trigger    *Trigger
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a new trigger.
func (r *ProjectsLocationsTriggersService) Create(parent string, trigger *Trigger) *ProjectsLocationsTriggersCreateCall {
	c := &ProjectsLocationsTriggersCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.trigger = trigger
	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 *ProjectsLocationsTriggersCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsTriggersCreateCall {
	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 *ProjectsLocationsTriggersCreateCall) Context(ctx context.Context) *ProjectsLocationsTriggersCreateCall {
	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 *ProjectsLocationsTriggersCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.triggers.create" call.
// Exactly one of *Trigger or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Trigger.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 *ProjectsLocationsTriggersCreateCall) Do(opts ...googleapi.CallOption) (*Trigger, 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 := &Trigger{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a new trigger.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/triggers",
	//   "httpMethod": "POST",
	//   "id": "run.projects.locations.triggers.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this trigger should\nbe created.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/triggers",
	//   "request": {
	//     "$ref": "Trigger"
	//   },
	//   "response": {
	//     "$ref": "Trigger"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.triggers.delete":

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

// Delete: Rpc to delete a trigger.
func (r *ProjectsLocationsTriggersService) Delete(name string) *ProjectsLocationsTriggersDeleteCall {
	c := &ProjectsLocationsTriggersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ApiVersion sets the optional parameter "apiVersion": Cloud Run
// currently ignores this parameter.
func (c *ProjectsLocationsTriggersDeleteCall) ApiVersion(apiVersion string) *ProjectsLocationsTriggersDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *ProjectsLocationsTriggersDeleteCall) Kind(kind string) *ProjectsLocationsTriggersDeleteCall {
	c.urlParams_.Set("kind", kind)
	return c
}

// PropagationPolicy sets the optional parameter "propagationPolicy":
// Specifies the propagation policy of delete. Cloud Run currently
// ignores
// this setting, and deletes in the background. Please
// see
// kubernetes.io/docs/concepts/workloads/controllers/garbage-collecti
// on/ for
// more information.
func (c *ProjectsLocationsTriggersDeleteCall) PropagationPolicy(propagationPolicy string) *ProjectsLocationsTriggersDeleteCall {
	c.urlParams_.Set("propagationPolicy", propagationPolicy)
	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 *ProjectsLocationsTriggersDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsTriggersDeleteCall {
	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 *ProjectsLocationsTriggersDeleteCall) Context(ctx context.Context) *ProjectsLocationsTriggersDeleteCall {
	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 *ProjectsLocationsTriggersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.triggers.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 *ProjectsLocationsTriggersDeleteCall) 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": "Rpc to delete a trigger.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/triggers/{triggersId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.projects.locations.triggers.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "apiVersion": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "kind": {
	//       "description": "Cloud Run currently ignores this parameter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the trigger being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/triggers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "propagationPolicy": {
	//       "description": "Specifies the propagation policy of delete. Cloud Run currently ignores\nthis setting, and deletes in the background. Please see\nkubernetes.io/docs/concepts/workloads/controllers/garbage-collection/ for\nmore information.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.triggers.get":

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

// Get: Rpc to get information about a trigger.
func (r *ProjectsLocationsTriggersService) Get(name string) *ProjectsLocationsTriggersGetCall {
	c := &ProjectsLocationsTriggersGetCall{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 *ProjectsLocationsTriggersGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsTriggersGetCall {
	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 *ProjectsLocationsTriggersGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsTriggersGetCall {
	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 *ProjectsLocationsTriggersGetCall) Context(ctx context.Context) *ProjectsLocationsTriggersGetCall {
	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 *ProjectsLocationsTriggersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsTriggersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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, "v1alpha1/{+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 "run.projects.locations.triggers.get" call.
// Exactly one of *Trigger or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Trigger.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 *ProjectsLocationsTriggersGetCall) Do(opts ...googleapi.CallOption) (*Trigger, 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 := &Trigger{
		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": "Rpc to get information about a trigger.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/triggers/{triggersId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.triggers.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the trigger being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/triggers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "response": {
	//     "$ref": "Trigger"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.triggers.list":

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

// List: Rpc to list triggers.
func (r *ProjectsLocationsTriggersService) List(parent string) *ProjectsLocationsTriggersListCall {
	c := &ProjectsLocationsTriggersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Continue sets the optional parameter "continue": Optional encoded
// string to continue paging.
func (c *ProjectsLocationsTriggersListCall) Continue(continue_ string) *ProjectsLocationsTriggersListCall {
	c.urlParams_.Set("continue", continue_)
	return c
}

// FieldSelector sets the optional parameter "fieldSelector": Allows to
// filter resources based on a specific value for a field name.
// Send this in a query string format. i.e. 'metadata.name%3Dlorem'.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsTriggersListCall) FieldSelector(fieldSelector string) *ProjectsLocationsTriggersListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *ProjectsLocationsTriggersListCall) IncludeUninitialized(includeUninitialized bool) *ProjectsLocationsTriggersListCall {
	c.urlParams_.Set("includeUninitialized", fmt.Sprint(includeUninitialized))
	return c
}

// LabelSelector sets the optional parameter "labelSelector": Allows to
// filter resources based on a label. Supported operations are
// =, !=, exists, in, and notIn.
func (c *ProjectsLocationsTriggersListCall) LabelSelector(labelSelector string) *ProjectsLocationsTriggersListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *ProjectsLocationsTriggersListCall) Limit(limit int64) *ProjectsLocationsTriggersListCall {
	c.urlParams_.Set("limit", fmt.Sprint(limit))
	return c
}

// ResourceVersion sets the optional parameter "resourceVersion": The
// baseline resource version from which the list or watch operation
// should
// start. Not currently used by Cloud Run.
func (c *ProjectsLocationsTriggersListCall) ResourceVersion(resourceVersion string) *ProjectsLocationsTriggersListCall {
	c.urlParams_.Set("resourceVersion", resourceVersion)
	return c
}

// Watch sets the optional parameter "watch": Flag that indicates that
// the client expects to watch this resource as well.
// Not currently used by Cloud Run.
func (c *ProjectsLocationsTriggersListCall) Watch(watch bool) *ProjectsLocationsTriggersListCall {
	c.urlParams_.Set("watch", fmt.Sprint(watch))
	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 *ProjectsLocationsTriggersListCall) Fields(s ...googleapi.Field) *ProjectsLocationsTriggersListCall {
	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 *ProjectsLocationsTriggersListCall) IfNoneMatch(entityTag string) *ProjectsLocationsTriggersListCall {
	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 *ProjectsLocationsTriggersListCall) Context(ctx context.Context) *ProjectsLocationsTriggersListCall {
	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 *ProjectsLocationsTriggersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.projects.locations.triggers.list" call.
// Exactly one of *ListTriggersResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListTriggersResponse.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 *ProjectsLocationsTriggersListCall) Do(opts ...googleapi.CallOption) (*ListTriggersResponse, 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 := &ListTriggersResponse{
		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": "Rpc to list triggers.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/triggers",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.triggers.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "continue": {
	//       "description": "Optional encoded string to continue paging.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "fieldSelector": {
	//       "description": "Allows to filter resources based on a specific value for a field name.\nSend this in a query string format. i.e. 'metadata.name%3Dlorem'.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "includeUninitialized": {
	//       "description": "Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "labelSelector": {
	//       "description": "Allows to filter resources based on a label. Supported operations are\n=, !=, exists, in, and notIn.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "limit": {
	//       "description": "The maximum number of records that should be returned.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "parent": {
	//       "description": "The project ID or project number from which the triggers should\nbe listed.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resourceVersion": {
	//       "description": "The baseline resource version from which the list or watch operation should\nstart. Not currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "watch": {
	//       "description": "Flag that indicates that the client expects to watch this resource as well.\nNot currently used by Cloud Run.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha1/{+parent}/triggers",
	//   "response": {
	//     "$ref": "ListTriggersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.triggers.replaceTrigger":

type ProjectsLocationsTriggersReplaceTriggerCall struct {
	s          *APIService
	name       string
	trigger    *Trigger
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// ReplaceTrigger: Rpc to replace a trigger.
//
// Only the spec and metadata labels and annotations are modifiable.
// After
// the Update request, Cloud Run will work to make the 'status'
// match the requested 'spec'.
//
// May provide metadata.resourceVersion to enforce update from last read
// for
// optimistic concurrency control.
func (r *ProjectsLocationsTriggersService) ReplaceTrigger(name string, trigger *Trigger) *ProjectsLocationsTriggersReplaceTriggerCall {
	c := &ProjectsLocationsTriggersReplaceTriggerCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.trigger = trigger
	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 *ProjectsLocationsTriggersReplaceTriggerCall) Fields(s ...googleapi.Field) *ProjectsLocationsTriggersReplaceTriggerCall {
	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 *ProjectsLocationsTriggersReplaceTriggerCall) Context(ctx context.Context) *ProjectsLocationsTriggersReplaceTriggerCall {
	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 *ProjectsLocationsTriggersReplaceTriggerCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsTriggersReplaceTriggerCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.0-rc1 gdcl/20191012")
	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.trigger)
	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, "v1alpha1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", 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 "run.projects.locations.triggers.replaceTrigger" call.
// Exactly one of *Trigger or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Trigger.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 *ProjectsLocationsTriggersReplaceTriggerCall) Do(opts ...googleapi.CallOption) (*Trigger, 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 := &Trigger{
		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": "Rpc to replace a trigger.\n\nOnly the spec and metadata labels and annotations are modifiable. After\nthe Update request, Cloud Run will work to make the 'status'\nmatch the requested 'spec'.\n\nMay provide metadata.resourceVersion to enforce update from last read for\noptimistic concurrency control.",
	//   "flatPath": "v1alpha1/projects/{projectsId}/locations/{locationsId}/triggers/{triggersId}",
	//   "httpMethod": "PUT",
	//   "id": "run.projects.locations.triggers.replaceTrigger",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the trigger being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/triggers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha1/{+name}",
	//   "request": {
	//     "$ref": "Trigger"
	//   },
	//   "response": {
	//     "$ref": "Trigger"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
