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

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:v1"
const apiName = "run"
const apiVersion = "v1"
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.Autodomainmappings = NewNamespacesAutodomainmappingsService(s)
	rs.Configurations = NewNamespacesConfigurationsService(s)
	rs.Domainmappings = NewNamespacesDomainmappingsService(s)
	rs.Revisions = NewNamespacesRevisionsService(s)
	rs.Routes = NewNamespacesRoutesService(s)
	rs.Services = NewNamespacesServicesService(s)
	return rs
}

type NamespacesService struct {
	s *APIService

	Authorizeddomains *NamespacesAuthorizeddomainsService

	Autodomainmappings *NamespacesAutodomainmappingsService

	Configurations *NamespacesConfigurationsService

	Domainmappings *NamespacesDomainmappingsService

	Revisions *NamespacesRevisionsService

	Routes *NamespacesRoutesService

	Services *NamespacesServicesService
}

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

type NamespacesAuthorizeddomainsService struct {
	s *APIService
}

func NewNamespacesAutodomainmappingsService(s *APIService) *NamespacesAutodomainmappingsService {
	rs := &NamespacesAutodomainmappingsService{s: s}
	return rs
}

type NamespacesAutodomainmappingsService 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 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 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.Autodomainmappings = NewProjectsLocationsAutodomainmappingsService(s)
	rs.Configurations = NewProjectsLocationsConfigurationsService(s)
	rs.Domainmappings = NewProjectsLocationsDomainmappingsService(s)
	rs.Revisions = NewProjectsLocationsRevisionsService(s)
	rs.Routes = NewProjectsLocationsRoutesService(s)
	rs.Services = NewProjectsLocationsServicesService(s)
	return rs
}

type ProjectsLocationsService struct {
	s *APIService

	Authorizeddomains *ProjectsLocationsAuthorizeddomainsService

	Autodomainmappings *ProjectsLocationsAutodomainmappingsService

	Configurations *ProjectsLocationsConfigurationsService

	Domainmappings *ProjectsLocationsDomainmappingsService

	Revisions *ProjectsLocationsRevisionsService

	Routes *ProjectsLocationsRoutesService

	Services *ProjectsLocationsServicesService
}

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

type ProjectsLocationsAuthorizeddomainsService struct {
	s *APIService
}

func NewProjectsLocationsAutodomainmappingsService(s *APIService) *ProjectsLocationsAutodomainmappingsService {
	rs := &ProjectsLocationsAutodomainmappingsService{s: s}
	return rs
}

type ProjectsLocationsAutodomainmappingsService 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 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
}

// Addressable: Information for connecting over HTTP(s).
type Addressable struct {
	Url string `json:"url,omitempty"`

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

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

// AutoDomainMapping: Resource to hold the state and status of a user's
// auto domain mapping.
type AutoDomainMapping struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1".
	ApiVersion string `json:"apiVersion,omitempty"`

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

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

	// Spec: The spec for this AutoDomainMapping.
	Spec *AutoDomainMappingSpec `json:"spec,omitempty"`

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

// AutoDomainMappingSpec: The desired state of the Auto Domain Mapping.
type AutoDomainMappingSpec 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"`

	// ExpansionType: The type of expansion for the auto auto domain
	// mapping.
	//
	// Possible values:
	//   "EXPANSION_TYPE_UNSPECIFIED"
	//   "PREFIX"
	ExpansionType string `json:"expansionType,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"`

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

// AutoDomainMappingStatus: The current state of the Domain Mapping.
type AutoDomainMappingStatus struct {
	// Conditions: Array of observed AutoDomainMappingConditions, indicating
	// the current state
	// of the AutoDomainMapping.
	Conditions []*GoogleCloudRunV1Condition `json:"conditions,omitempty"`

	// ObservedGeneration: ObservedGeneration is the 'Generation' of the
	// AutoDomainMapping 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 *AutoDomainMappingStatus) MarshalJSON() ([]byte, error) {
	type NoMethod AutoDomainMappingStatus
	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)
}

// ConfigMapEnvSource: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// 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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Specify whether the ConfigMap must be defined
	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 for Anthos: supported
//
// Selects a key from a ConfigMap.
type ConfigMapKeySelector struct {
	// Key: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: 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 for Anthos: supported
	//
	// The ConfigMap to select from.
	Name string `json:"name,omitempty"`

	// Optional: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Specify whether the ConfigMap or its key must be defined
	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: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// 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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Name of the config.
	Name string `json:"name,omitempty"`

	// Optional: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ObjectMeta `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)
}

// ConfigurationSpec: ConfigurationSpec holds the desired state of the
// Configuration (from the
// client).
type ConfigurationSpec struct {
	// Template: 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 for
	// Anthos
	// 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.
	Template *RevisionTemplate `json:"template,omitempty"`

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

	// NullFields is a list of field names (e.g. "Template") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field 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 []*GoogleCloudRunV1Condition `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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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
	Args []string `json:"args,omitempty"`

	Command []string `json:"command,omitempty"`

	// Env: (Optional)
	//
	// Cloud Run fully managed: supported
	//
	// Cloud Run for Anthos: supported
	//
	// List of environment variables to set in the container.
	// Cannot be updated.
	Env []*EnvVar `json:"env,omitempty"`

	// EnvFrom: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	EnvFrom []*EnvFromSource `json:"envFrom,omitempty"`

	// Image: Cloud Run fully managed: only supports containers from Google
	// Container
	// Registry
	//
	// Cloud Run for Anthos: supported
	//
	// URL of the Container image.
	// More info: https://kubernetes.io/docs/concepts/containers/images
	Image string `json:"image,omitempty"`

	// ImagePullPolicy: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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
	ImagePullPolicy string `json:"imagePullPolicy,omitempty"`

	// LivenessProbe: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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
	LivenessProbe *Probe `json:"livenessProbe,omitempty"`

	// Name: (Optional)
	//
	// Name of the container specified as a DNS_LABEL.
	Name string `json:"name,omitempty"`

	// Ports: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	Ports []*ContainerPort `json:"ports,omitempty"`

	// ReadinessProbe: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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
	ReadinessProbe *Probe `json:"readinessProbe,omitempty"`

	// Resources: (Optional)
	//
	// Cloud Run fully managed: supported
	//
	// Cloud Run for Anthos: supported
	//
	// Compute Resources required by this container.
	// Cannot be updated.
	// More
	// info:
	// https://kubernetes.io/docs/concepts/storage/persistent-volumes#r
	// esources
	Resources *ResourceRequirements `json:"resources,omitempty"`

	// SecurityContext: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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/
	SecurityContext *SecurityContext `json:"securityContext,omitempty"`

	// TerminationMessagePath: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	TerminationMessagePath string `json:"terminationMessagePath,omitempty"`

	// TerminationMessagePolicy: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	TerminationMessagePolicy string `json:"terminationMessagePolicy,omitempty"`

	// VolumeMounts: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Pod volumes to mount into the container's filesystem.
	// Cannot be updated.
	VolumeMounts []*VolumeMount `json:"volumeMounts,omitempty"`

	// WorkingDir: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	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: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// ContainerPort represents a network port in a single container.
type ContainerPort struct {
	// ContainerPort: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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"`

	// Name: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// If specified, used to specify which protocol to use.
	// Allowed values are "http1" and "h2c".
	Name string `json:"name,omitempty"`

	// Protocol: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Protocol for port. Must be TCP.
	// Defaults to "TCP".
	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/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ObjectMeta `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)
}

// 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 []*GoogleCloudRunV1Condition `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)
}

// EnvFromSource: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// EnvFromSource represents the source of a set of ConfigMaps
type EnvFromSource struct {
	// ConfigMapRef: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// The ConfigMap to select from
	ConfigMapRef *ConfigMapEnvSource `json:"configMapRef,omitempty"`

	// Prefix: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// An optional identifier to prepend to each key in the ConfigMap. Must
	// be a
	// C_IDENTIFIER.
	Prefix string `json:"prefix,omitempty"`

	// SecretRef: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// The Secret to select from
	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: (Optional)
	//
	// 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 "".
	Value string `json:"value,omitempty"`

	// ValueFrom: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Source for the environment variable's value. Cannot be used if value
	// is not
	// empty.
	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 for Anthos: supported
//
// EnvVarSource represents a source for the value of an EnvVar.
type EnvVarSource struct {
	// ConfigMapKeyRef: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Selects a key of a ConfigMap.
	ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty"`

	// SecretKeyRef: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Selects a key of a secret in the pod's namespace
	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)
}

// ExecAction: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// ExecAction describes a "run in container" action.
type ExecAction struct {
	// Command: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	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)
}

// GoogleCloudRunV1Condition: Condition defines a generic condition for
// a Resource
type GoogleCloudRunV1Condition struct {
	// LastTransitionTime: Optional. Last time the condition transitioned
	// from one status to another.
	LastTransitionTime string `json:"lastTransitionTime,omitempty"`

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

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

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

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

	// Type: type 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 common to all resources include:
	// * "Ready": True when the Resource is 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 *GoogleCloudRunV1Condition) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudRunV1Condition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

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

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

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

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

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

// HTTPGetAction: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// HTTPGetAction describes an action based on HTTP Get requests.
type HTTPGetAction struct {
	// Host: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Host name to connect to, defaults to the pod IP. You probably want to
	// set
	// "Host" in httpHeaders instead.
	Host string `json:"host,omitempty"`

	// HttpHeaders: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Custom headers to set in the request. HTTP allows repeated headers.
	HttpHeaders []*HTTPHeader `json:"httpHeaders,omitempty"`

	// Path: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Path to access on the HTTP server.
	Path string `json:"path,omitempty"`

	// Scheme: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Scheme to use for connecting to the host.
	// Defaults to HTTP.
	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: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// HTTPHeader describes a custom header to be used in HTTP probes
type HTTPHeader struct {
	// Name: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// The header field name
	Name string `json:"name,omitempty"`

	// Value: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// Handler defines a specific action that should be taken
type Handler struct {
	// Exec: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// One and only one of the following should be specified.
	// Exec specifies the action to take.
	Exec *ExecAction `json:"exec,omitempty"`

	// HttpGet: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// HTTPGet specifies the http request to perform.
	HttpGet *HTTPGetAction `json:"httpGet,omitempty"`

	// TcpSocket: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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)
}

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

// K8sIoApimachineryPkgApisMetaV1ListMeta: ListMeta describes metadata
// that synthetic resources must have, including
// lists and various status objects. A resource may have only one
// of
// {ObjectMeta, ListMeta}.
type K8sIoApimachineryPkgApisMetaV1ListMeta 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 *K8sIoApimachineryPkgApisMetaV1ListMeta) MarshalJSON() ([]byte, error) {
	type NoMethod K8sIoApimachineryPkgApisMetaV1ListMeta
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// K8sIoApimachineryPkgApisMetaV1ObjectMeta:
// k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta is metadata that
// all
// persisted resources must have, which includes all objects users must
// create.
type K8sIoApimachineryPkgApisMetaV1ObjectMeta struct {
	// Annotations: (Optional)
	//
	// 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
	Annotations map[string]string `json:"annotations,omitempty"`

	// ClusterName: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	ClusterName string `json:"clusterName,omitempty"`

	// CreationTimestamp: (Optional)
	//
	// 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
	CreationTimestamp string `json:"creationTimestamp,omitempty"`

	// DeletionGracePeriodSeconds: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	DeletionGracePeriodSeconds int64 `json:"deletionGracePeriodSeconds,omitempty"`

	// DeletionTimestamp: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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
	DeletionTimestamp string `json:"deletionTimestamp,omitempty"`

	// Finalizers: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	// +patchStrategy=merge
	Finalizers []string `json:"finalizers,omitempty"`

	// GenerateName: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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
	//  string generateName = 2;
	GenerateName string `json:"generateName,omitempty"`

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

	// Labels: (Optional)
	//
	// 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
	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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// List of objects that own this object. If ALL objects in the list
	// have
	// been deleted, this object will be garbage collected.
	OwnerReferences []*K8sIoApimachineryPkgApisMetaV1OwnerReference `json:"ownerReferences,omitempty"`

	// ResourceVersion: (Optional)
	//
	// 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
	ResourceVersion string `json:"resourceVersion,omitempty"`

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

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

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

// K8sIoApimachineryPkgApisMetaV1Status: Status is a return value for
// calls that don't return other objects
type K8sIoApimachineryPkgApisMetaV1Status struct {
	// Code: Suggested HTTP return code for this status, 0 if not
	// set.
	// +optional
	Code int64 `json:"code,omitempty"`

	// Details: Extended data associated with the reason.  Each reason may
	// define its
	// own extended details. This field is optional and the data returned
	// is not guaranteed to conform to any schema except that defined by
	// the reason type.
	// +optional
	Details *K8sIoApimachineryPkgApisMetaV1StatusDetails `json:"details,omitempty"`

	// Message: A human-readable description of the status of this
	// operation.
	// +optional
	Message string `json:"message,omitempty"`

	// Metadata: Standard list metadata.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#types-kinds
	// +optional
	Metadata *K8sIoApimachineryPkgApisMetaV1ListMeta `json:"metadata,omitempty"`

	// Reason: A machine-readable description of why this operation is in
	// the
	// "Failure" status. If this value is empty there
	// is no information available. A Reason clarifies an HTTP status
	// code but does not override it.
	// +optional
	Reason string `json:"reason,omitempty"`

	// Status: Status of the operation.
	// One of: "Success" or "Failure".
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#spec-and-status
	// +optional
	Status string `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. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// K8sIoApimachineryPkgApisMetaV1StatusCause: StatusCause provides more
// information about an api.Status failure, including
// cases when multiple errors are encountered.
type K8sIoApimachineryPkgApisMetaV1StatusCause struct {
	// Field: The field of the resource that has caused this error, as named
	// by its JSON
	// serialization. May include dot and postfix notation for nested
	// attributes.
	// Arrays are zero-indexed.  Fields may appear more than once in an
	// array of
	// causes due to fields having multiple errors.
	// Optional.
	//
	// Examples:
	//   "name" - the field "name" on the current resource
	//   "items[0].name" - the field "name" on the first array entry in
	// "items"
	// +optional
	Field string `json:"field,omitempty"`

	// Message: A human-readable description of the cause of the error.
	// This field may be
	// presented as-is to a reader.
	// +optional
	Message string `json:"message,omitempty"`

	// Reason: A machine-readable description of the cause of the error. If
	// this value is
	// empty there is no information available.
	// +optional
	Reason string `json:"reason,omitempty"`

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

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

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

// K8sIoApimachineryPkgApisMetaV1StatusDetails: StatusDetails is a set
// of additional properties that MAY be set by the
// server to provide additional information about a response. The
// Reason
// field of a Status object defines what attributes will be set.
// Clients
// must ignore fields that do not match the defined type of each
// attribute,
// and should assume that any attribute may be empty, invalid, or
// under
// defined.
type K8sIoApimachineryPkgApisMetaV1StatusDetails struct {
	// Causes: The Causes array includes more details associated with the
	// StatusReason
	// failure. Not all StatusReasons may provide detailed causes.
	// +optional
	Causes []*K8sIoApimachineryPkgApisMetaV1StatusCause `json:"causes,omitempty"`

	// Group: The group attribute of the resource associated with the
	// status
	// StatusReason. +optional
	Group string `json:"group,omitempty"`

	// Kind: The kind attribute of the resource associated with the status
	// StatusReason.
	// On some operations may differ from the requested resource Kind.
	// More
	// info:
	// https://git.k8s.io/community/contributors/devel/api-conventions.
	// md#types-kinds
	// +optional
	Kind string `json:"kind,omitempty"`

	// Name: The name attribute of the resource associated with the status
	// StatusReason
	// (when there is a single name which can be described).
	// +optional
	Name string `json:"name,omitempty"`

	// RetryAfterSeconds: If specified, the time in seconds before the
	// operation should be retried.
	// Some errors may indicate the client must take an alternate action -
	// for
	// those errors this field may indicate how long to wait before taking
	// the
	// alternate action. +optional
	RetryAfterSeconds int64 `json:"retryAfterSeconds,omitempty"`

	// Uid: UID of the resource.
	// (when there is a single resource which can be described).
	// 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. "Causes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// KeyToPath: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// Maps a string key to a path within a volume.
type KeyToPath struct {
	// Key: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// The key to project.
	Key string `json:"key,omitempty"`

	// Mode: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	Mode int64 `json:"mode,omitempty"`

	// Path: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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)
}

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

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

	// Items: List of AutoDomainMappings.
	Items []*AutoDomainMapping `json:"items,omitempty"`

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

	// Metadata: Metadata associated with this AutoDomainMapping list.
	Metadata *K8sIoApimachineryPkgApisMetaV1ListMeta `json:"metadata,omitempty"`

	// RegionDetails: Details for the regions used during a global call
	// including any failures.
	// This is not populated when targeting a specific region.
	RegionDetails map[string]RegionDetails `json:"regionDetails,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 *ListAutoDomainMappingsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListAutoDomainMappingsResponse
	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/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ListMeta `json:"metadata,omitempty"`

	// RegionDetails: Details for the regions used during a global call
	// including any failures.
	// This is not populated when targeting a specific region.
	RegionDetails map[string]RegionDetails `json:"regionDetails,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/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ListMeta `json:"metadata,omitempty"`

	// RegionDetails: Details for the regions used during a global call
	// including any failures.
	// This is not populated when targeting a specific region.
	RegionDetails map[string]RegionDetails `json:"regionDetails,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)
}

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

// ListRevisionsResponse: ListRevisionsResponse is a list of Revision
// resources.
type ListRevisionsResponse struct {
	// ApiVersion: The API version for this call such as
	// "serving.knative.dev/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ListMeta `json:"metadata,omitempty"`

	// RegionDetails: Details for the regions used during a global call
	// including any failures.
	// This is not populated when targeting a specific region.
	RegionDetails map[string]RegionDetails `json:"regionDetails,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/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ListMeta `json:"metadata,omitempty"`

	// RegionDetails: Details for the regions used during a global call
	// including any failures.
	// This is not populated when targeting a specific region.
	RegionDetails map[string]RegionDetails `json:"regionDetails,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/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ListMeta `json:"metadata,omitempty"`

	// RegionDetails: Details for the regions used during a global call
	// including any failures.
	// This is not populated when targeting a specific region.
	RegionDetails map[string]RegionDetails `json:"regionDetails,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)
}

// LocalObjectReference: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// LocalObjectReference contains enough information to let you locate
// the
// referenced object inside the same namespace.
type LocalObjectReference struct {
	// Name: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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"`

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

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

// Policy: Defines an Identity and Access Management (IAM) policy. It is
// used to
// specify access control policies for Cloud Platform resources.
//
//
// A `Policy` consists of a list of `bindings`. A `binding` binds a list
// of
// `members` to a `role`, where the members can be user accounts, Google
// groups,
// Google domains, and service accounts. A `role` is a named list of
// permissions
// defined by IAM.
//
// **JSON Example**
//
//     {
//       "bindings": [
//         {
//           "role": "roles/owner",
//           "members": [
//             "user:mike@example.com",
//             "group:admins@example.com",
//             "domain:google.com",
//
// "serviceAccount:my-other-app@appspot.gserviceaccount.com"
//           ]
//         },
//         {
//           "role": "roles/viewer",
//           "members": ["user:sean@example.com"]
//         }
//       ]
//     }
//
// **YAML Example**
//
//     bindings:
//     - members:
//       - user:mike@example.com
//       - group:admins@example.com
//       - domain:google.com
//       - serviceAccount:my-other-app@appspot.gserviceaccount.com
//       role: roles/owner
//     - members:
//       - user:sean@example.com
//       role: roles/viewer
//
//
// 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`.
	// `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.
	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.
	//
	// Policies with any conditional bindings must specify version 3.
	// Policies
	// without any conditional bindings may specify any valid value or leave
	// the
	// field unset.
	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: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// 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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Minimum consecutive failures for the probe to be considered failed
	// after
	// having succeeded. Defaults to 3. Minimum value is 1.
	FailureThreshold int64 `json:"failureThreshold,omitempty"`

	// Handler: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// The action taken to determine the health of a container
	Handler *Handler `json:"handler,omitempty"`

	// InitialDelaySeconds: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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
	InitialDelaySeconds int64 `json:"initialDelaySeconds,omitempty"`

	// PeriodSeconds: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// How often (in seconds) to perform the probe.
	// Default to 10 seconds. Minimum value is 1.
	PeriodSeconds int64 `json:"periodSeconds,omitempty"`

	// SuccessThreshold: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	SuccessThreshold int64 `json:"successThreshold,omitempty"`

	// TimeoutSeconds: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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
	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)
}

// RegionDetails: Information for a regional call used for a global API.
type RegionDetails struct {
	// Error: The status indicating why the regional call failed
	Error *GoogleRpcStatus `json:"error,omitempty"`

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

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

func (s *RegionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod RegionDetails
	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: (Optional)
	//
	// Cloud Run fully managed: Only memory is supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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"`

	// Requests: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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"`

	// 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.
//
// 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/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ObjectMeta `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)
}

// RevisionSpec: RevisionSpec holds the desired state of the Revision
// (from the client).
type RevisionSpec struct {
	// 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 for Anthos: 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.
	// The runtime contract is documented
	// here:
	// https://github.com/knative/serving/blob/master/docs/runtime-cont
	// ract.md
	Containers []*Container `json:"containers,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"`

	// 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.
	// "ContainerConcurrency") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContainerConcurrency") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field 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. Revision-specific conditions include:
	// * "ResourcesAvailable": True when underlying resources have been
	//    provisioned.
	// * "ContainerHealthy": True when the Revision readiness check
	// completes.
	// * "Active": True when the Revision may receive traffic.
	Conditions []*GoogleCloudRunV1Condition `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.
	// 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.
	Metadata *K8sIoApimachineryPkgApisMetaV1ObjectMeta `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/v1".
	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 *K8sIoApimachineryPkgApisMetaV1ObjectMeta `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)
}

// RouteSpec: RouteSpec holds the desired state of the Route (from the
// client).
type RouteSpec struct {
	// 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. "Traffic") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

// SecretEnvSource: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// 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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Specify whether the Secret must be defined
	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 for Anthos: supported
//
// SecretKeySelector selects a key of a Secret.
type SecretKeySelector struct {
	// Key: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: 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 for Anthos: supported
	//
	// The name of the secret in the pod's namespace to select from.
	Name string `json:"name,omitempty"`

	// Optional: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Specify whether the Secret or its key must be defined
	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: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// 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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Specify whether the Secret or its keys must be defined.
	Optional bool `json:"optional,omitempty"`

	// SecretName: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// 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 {
	// RunAsUser: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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.
	RunAsUser int64 `json:"runAsUser,omitempty"`

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

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

// 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 {
	// 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. "Template") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

// 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.
	// Service-specific conditions include:
	// * "ConfigurationsReady": true when the underlying Configuration is
	// ready.
	// * "RoutesReady": true when the underlying Route is ready.
	// * "Ready": true when both the underlying Route and Configuration
	// are
	// ready.
	Conditions []*GoogleCloudRunV1Condition `json:"conditions,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)
}

// TCPSocketAction: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// TCPSocketAction describes an action based on opening a socket
type TCPSocketAction struct {
	// Host: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Optional: Host name to connect to, defaults to the pod IP.
	Host string `json:"host,omitempty"`

	// Port: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// 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"`

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

// Volume: Cloud Run fully managed: not supported
//
// Cloud Run for Anthos: supported
//
// Volume represents a named volume in a container.
type Volume struct {
	// ConfigMap: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty"`

	// Name: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Volume's name.
	Name string `json:"name,omitempty"`

	// Secret: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	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)
}

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

	// Name: Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// This must match the Name of a Volume.
	Name string `json:"name,omitempty"`

	// ReadOnly: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Only true is accepted.
	// Defaults to true.
	ReadOnly bool `json:"readOnly,omitempty"`

	// SubPath: (Optional)
	//
	// Cloud Run fully managed: not supported
	//
	// Cloud Run for Anthos: supported
	//
	// Path within the volume from which the container's volume should be
	// mounted.
	// Defaults to "" (volume's root).
	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: 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.11.0 gdcl/20190924")
	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/v1/{+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": "List authorized domains.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/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/v1/{+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.autodomainmappings.create":

type NamespacesAutodomainmappingsCreateCall struct {
	s                 *APIService
	parent            string
	autodomainmapping *AutoDomainMapping
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

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

func (c *NamespacesAutodomainmappingsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.autodomainmapping)
	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/v1/{+parent}/autodomainmappings")
	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.autodomainmappings.create" call.
// Exactly one of *AutoDomainMapping or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AutoDomainMapping.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 *NamespacesAutodomainmappingsCreateCall) Do(opts ...googleapi.CallOption) (*AutoDomainMapping, 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 := &AutoDomainMapping{
		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 auto domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/namespaces/{namespacesId}/autodomainmappings",
	//   "httpMethod": "POST",
	//   "id": "run.namespaces.autodomainmappings.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this auto domain mapping should\nbe created.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/domains.cloudrun.com/v1/{+parent}/autodomainmappings",
	//   "request": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "response": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// Delete: Delete an auto domain mapping.
func (r *NamespacesAutodomainmappingsService) Delete(name string) *NamespacesAutodomainmappingsDeleteCall {
	c := &NamespacesAutodomainmappingsDeleteCall{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 *NamespacesAutodomainmappingsDeleteCall) ApiVersion(apiVersion string) *NamespacesAutodomainmappingsDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *NamespacesAutodomainmappingsDeleteCall) Kind(kind string) *NamespacesAutodomainmappingsDeleteCall {
	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 *NamespacesAutodomainmappingsDeleteCall) PropagationPolicy(propagationPolicy string) *NamespacesAutodomainmappingsDeleteCall {
	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 *NamespacesAutodomainmappingsDeleteCall) Fields(s ...googleapi.Field) *NamespacesAutodomainmappingsDeleteCall {
	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 *NamespacesAutodomainmappingsDeleteCall) Context(ctx context.Context) *NamespacesAutodomainmappingsDeleteCall {
	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 *NamespacesAutodomainmappingsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.autodomainmappings.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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 *NamespacesAutodomainmappingsDeleteCall) Do(opts ...googleapi.CallOption) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete an auto domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/namespaces/{namespacesId}/autodomainmappings/{autodomainmappingsId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.namespaces.autodomainmappings.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 auto domain mapping being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/autodomainmappings/[^/]+$",
	//       "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/domains.cloudrun.com/v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

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

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

// Do executes the "run.namespaces.autodomainmappings.get" call.
// Exactly one of *AutoDomainMapping or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AutoDomainMapping.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 *NamespacesAutodomainmappingsGetCall) Do(opts ...googleapi.CallOption) (*AutoDomainMapping, 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 := &AutoDomainMapping{
		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 information about an auto domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/namespaces/{namespacesId}/autodomainmappings/{autodomainmappingsId}",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.autodomainmappings.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the auto domain mapping being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/autodomainmappings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/domains.cloudrun.com/v1/{+name}",
	//   "response": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// List: List auto domain mappings.
func (r *NamespacesAutodomainmappingsService) List(parent string) *NamespacesAutodomainmappingsListCall {
	c := &NamespacesAutodomainmappingsListCall{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 *NamespacesAutodomainmappingsListCall) Continue(continue_ string) *NamespacesAutodomainmappingsListCall {
	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 *NamespacesAutodomainmappingsListCall) FieldSelector(fieldSelector string) *NamespacesAutodomainmappingsListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *NamespacesAutodomainmappingsListCall) IncludeUninitialized(includeUninitialized bool) *NamespacesAutodomainmappingsListCall {
	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 *NamespacesAutodomainmappingsListCall) LabelSelector(labelSelector string) *NamespacesAutodomainmappingsListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *NamespacesAutodomainmappingsListCall) Limit(limit int64) *NamespacesAutodomainmappingsListCall {
	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 *NamespacesAutodomainmappingsListCall) ResourceVersion(resourceVersion string) *NamespacesAutodomainmappingsListCall {
	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 *NamespacesAutodomainmappingsListCall) Watch(watch bool) *NamespacesAutodomainmappingsListCall {
	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 *NamespacesAutodomainmappingsListCall) Fields(s ...googleapi.Field) *NamespacesAutodomainmappingsListCall {
	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 *NamespacesAutodomainmappingsListCall) IfNoneMatch(entityTag string) *NamespacesAutodomainmappingsListCall {
	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 *NamespacesAutodomainmappingsListCall) Context(ctx context.Context) *NamespacesAutodomainmappingsListCall {
	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 *NamespacesAutodomainmappingsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesAutodomainmappingsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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/v1/{+parent}/autodomainmappings")
	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.autodomainmappings.list" call.
// Exactly one of *ListAutoDomainMappingsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListAutoDomainMappingsResponse.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 *NamespacesAutodomainmappingsListCall) Do(opts ...googleapi.CallOption) (*ListAutoDomainMappingsResponse, 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 := &ListAutoDomainMappingsResponse{
		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": "List auto domain mappings.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/namespaces/{namespacesId}/autodomainmappings",
	//   "httpMethod": "GET",
	//   "id": "run.namespaces.autodomainmappings.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 auto domain mappings 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/domains.cloudrun.com/v1/{+parent}/autodomainmappings",
	//   "response": {
	//     "$ref": "ListAutoDomainMappingsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.namespaces.autodomainmappings.replaceAutoDomainMapping":

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

// ReplaceAutoDomainMapping: Replace an auto domain mapping.
//
// 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 *NamespacesAutodomainmappingsService) ReplaceAutoDomainMapping(name string, autodomainmapping *AutoDomainMapping) *NamespacesAutodomainmappingsReplaceAutoDomainMappingCall {
	c := &NamespacesAutodomainmappingsReplaceAutoDomainMappingCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.autodomainmapping = autodomainmapping
	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 *NamespacesAutodomainmappingsReplaceAutoDomainMappingCall) Fields(s ...googleapi.Field) *NamespacesAutodomainmappingsReplaceAutoDomainMappingCall {
	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 *NamespacesAutodomainmappingsReplaceAutoDomainMappingCall) Context(ctx context.Context) *NamespacesAutodomainmappingsReplaceAutoDomainMappingCall {
	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 *NamespacesAutodomainmappingsReplaceAutoDomainMappingCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesAutodomainmappingsReplaceAutoDomainMappingCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.autodomainmapping)
	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/v1/{+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.autodomainmappings.replaceAutoDomainMapping" call.
// Exactly one of *AutoDomainMapping or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AutoDomainMapping.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 *NamespacesAutodomainmappingsReplaceAutoDomainMappingCall) Do(opts ...googleapi.CallOption) (*AutoDomainMapping, 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 := &AutoDomainMapping{
		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": "Replace an auto domain mapping.\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/domains.cloudrun.com/v1/namespaces/{namespacesId}/autodomainmappings/{autodomainmappingsId}",
	//   "httpMethod": "PUT",
	//   "id": "run.namespaces.autodomainmappings.replaceAutoDomainMapping",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the auto domain mapping being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/autodomainmappings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/domains.cloudrun.com/v1/{+name}",
	//   "request": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "response": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

type NamespacesConfigurationsCreateCall struct {
	s             *APIService
	parent        string
	configuration *Configuration
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Create: Create a configuration.
func (r *NamespacesConfigurationsService) Create(parent string, configuration *Configuration) *NamespacesConfigurationsCreateCall {
	c := &NamespacesConfigurationsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.configuration = configuration
	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 *NamespacesConfigurationsCreateCall) Fields(s ...googleapi.Field) *NamespacesConfigurationsCreateCall {
	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 *NamespacesConfigurationsCreateCall) Context(ctx context.Context) *NamespacesConfigurationsCreateCall {
	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 *NamespacesConfigurationsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesConfigurationsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.configuration)
	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/v1/{+parent}/configurations")
	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.configurations.create" 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 *NamespacesConfigurationsCreateCall) 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": "Create a configuration.",
	//   "flatPath": "apis/serving.knative.dev/v1/namespaces/{namespacesId}/configurations",
	//   "httpMethod": "POST",
	//   "id": "run.namespaces.configurations.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this configuration should be\ncreated.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1/{+parent}/configurations",
	//   "request": {
	//     "$ref": "Configuration"
	//   },
	//   "response": {
	//     "$ref": "Configuration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// Delete: delete a configuration.
// This will cause the configuration to delete all child revisions.
// Prior to
// calling this, any route referencing the configuration (or
// revision
// from the configuration) must be deleted.
func (r *NamespacesConfigurationsService) Delete(name string) *NamespacesConfigurationsDeleteCall {
	c := &NamespacesConfigurationsDeleteCall{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 *NamespacesConfigurationsDeleteCall) ApiVersion(apiVersion string) *NamespacesConfigurationsDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *NamespacesConfigurationsDeleteCall) Kind(kind string) *NamespacesConfigurationsDeleteCall {
	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 *NamespacesConfigurationsDeleteCall) PropagationPolicy(propagationPolicy string) *NamespacesConfigurationsDeleteCall {
	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 *NamespacesConfigurationsDeleteCall) Fields(s ...googleapi.Field) *NamespacesConfigurationsDeleteCall {
	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 *NamespacesConfigurationsDeleteCall) Context(ctx context.Context) *NamespacesConfigurationsDeleteCall {
	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 *NamespacesConfigurationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.configurations.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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 *NamespacesConfigurationsDeleteCall) Do(opts ...googleapi.CallOption) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "delete a configuration.\nThis will cause the configuration to delete all child revisions. Prior to\ncalling this, any route referencing the configuration (or revision\nfrom the configuration) must be deleted.",
	//   "flatPath": "apis/serving.knative.dev/v1/namespaces/{namespacesId}/configurations/{configurationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.namespaces.configurations.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 configuration being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/configurations/[^/]+$",
	//       "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/serving.knative.dev/v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// 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: 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.11.0 gdcl/20190924")
	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/v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a configuration.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+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: 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.11.0 gdcl/20190924")
	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/v1/{+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": "List configurations.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+parent}/configurations",
	//   "response": {
	//     "$ref": "ListConfigurationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// ReplaceConfiguration: Replace a configuration.
//
// 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 *NamespacesConfigurationsService) ReplaceConfiguration(name string, configuration *Configuration) *NamespacesConfigurationsReplaceConfigurationCall {
	c := &NamespacesConfigurationsReplaceConfigurationCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.configuration = configuration
	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 *NamespacesConfigurationsReplaceConfigurationCall) Fields(s ...googleapi.Field) *NamespacesConfigurationsReplaceConfigurationCall {
	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 *NamespacesConfigurationsReplaceConfigurationCall) Context(ctx context.Context) *NamespacesConfigurationsReplaceConfigurationCall {
	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 *NamespacesConfigurationsReplaceConfigurationCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesConfigurationsReplaceConfigurationCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.configuration)
	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/v1/{+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.configurations.replaceConfiguration" 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 *NamespacesConfigurationsReplaceConfigurationCall) 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": "Replace a configuration.\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/v1/namespaces/{namespacesId}/configurations/{configurationsId}",
	//   "httpMethod": "PUT",
	//   "id": "run.namespaces.configurations.replaceConfiguration",
	//   "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/v1/{+name}",
	//   "request": {
	//     "$ref": "Configuration"
	//   },
	//   "response": {
	//     "$ref": "Configuration"
	//   },
	//   "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: Create 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.11.0 gdcl/20190924")
	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/v1/{+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": "Create a new domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/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/v1/{+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: 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
}

// 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.11.0 gdcl/20190924")
	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/v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.domainmappings.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete a domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/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"
	//     },
	//     "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/v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	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/v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a domain mapping.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/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/v1/{+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: 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.11.0 gdcl/20190924")
	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/v1/{+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": "List domain mappings.",
	//   "flatPath": "apis/domains.cloudrun.com/v1/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/v1/{+parent}/domainmappings",
	//   "response": {
	//     "$ref": "ListDomainMappingsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

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

func (c *NamespacesDomainmappingsReplaceDomainMappingCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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/v1/{+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.domainmappings.replaceDomainMapping" 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 *NamespacesDomainmappingsReplaceDomainMappingCall) 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": "Replace a domain mapping.\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/domains.cloudrun.com/v1/namespaces/{namespacesId}/domainmappings/{domainmappingsId}",
	//   "httpMethod": "PUT",
	//   "id": "run.namespaces.domainmappings.replaceDomainMapping",
	//   "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/v1/{+name}",
	//   "request": {
	//     "$ref": "DomainMapping"
	//   },
	//   "response": {
	//     "$ref": "DomainMapping"
	//   },
	//   "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: 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
}

// 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.11.0 gdcl/20190924")
	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/v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.revisions.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete a revision.",
	//   "flatPath": "apis/serving.knative.dev/v1/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"
	//     },
	//     "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/v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	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/v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a revision.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+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: 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.11.0 gdcl/20190924")
	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/v1/{+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": "List revisions.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+parent}/revisions",
	//   "response": {
	//     "$ref": "ListRevisionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

type NamespacesRoutesCreateCall struct {
	s          *APIService
	parent     string
	route      *Route
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Create a route.
func (r *NamespacesRoutesService) Create(parent string, route *Route) *NamespacesRoutesCreateCall {
	c := &NamespacesRoutesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.route = route
	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 *NamespacesRoutesCreateCall) Fields(s ...googleapi.Field) *NamespacesRoutesCreateCall {
	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 *NamespacesRoutesCreateCall) Context(ctx context.Context) *NamespacesRoutesCreateCall {
	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 *NamespacesRoutesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesRoutesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.route)
	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/v1/{+parent}/routes")
	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.routes.create" 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 *NamespacesRoutesCreateCall) 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": "Create a route.",
	//   "flatPath": "apis/serving.knative.dev/v1/namespaces/{namespacesId}/routes",
	//   "httpMethod": "POST",
	//   "id": "run.namespaces.routes.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this route should be created.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1/{+parent}/routes",
	//   "request": {
	//     "$ref": "Route"
	//   },
	//   "response": {
	//     "$ref": "Route"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// Delete: Delete a route.
// This will cause the route to stop serving traffic.
func (r *NamespacesRoutesService) Delete(name string) *NamespacesRoutesDeleteCall {
	c := &NamespacesRoutesDeleteCall{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 *NamespacesRoutesDeleteCall) ApiVersion(apiVersion string) *NamespacesRoutesDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *NamespacesRoutesDeleteCall) Kind(kind string) *NamespacesRoutesDeleteCall {
	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 *NamespacesRoutesDeleteCall) PropagationPolicy(propagationPolicy string) *NamespacesRoutesDeleteCall {
	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 *NamespacesRoutesDeleteCall) Fields(s ...googleapi.Field) *NamespacesRoutesDeleteCall {
	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 *NamespacesRoutesDeleteCall) Context(ctx context.Context) *NamespacesRoutesDeleteCall {
	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 *NamespacesRoutesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "run.namespaces.routes.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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 *NamespacesRoutesDeleteCall) Do(opts ...googleapi.CallOption) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete a route.\nThis will cause the route to stop serving traffic.",
	//   "flatPath": "apis/serving.knative.dev/v1/namespaces/{namespacesId}/routes/{routesId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.namespaces.routes.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 route being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/routes/[^/]+$",
	//       "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/serving.knative.dev/v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	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/v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a route.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+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: 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.11.0 gdcl/20190924")
	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/v1/{+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": "List routes.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+parent}/routes",
	//   "response": {
	//     "$ref": "ListRoutesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

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

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

// ReplaceRoute: Replace a route.
//
// 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 *NamespacesRoutesService) ReplaceRoute(name string, route *Route) *NamespacesRoutesReplaceRouteCall {
	c := &NamespacesRoutesReplaceRouteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.route = route
	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 *NamespacesRoutesReplaceRouteCall) Fields(s ...googleapi.Field) *NamespacesRoutesReplaceRouteCall {
	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 *NamespacesRoutesReplaceRouteCall) Context(ctx context.Context) *NamespacesRoutesReplaceRouteCall {
	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 *NamespacesRoutesReplaceRouteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *NamespacesRoutesReplaceRouteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.route)
	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/v1/{+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.routes.replaceRoute" 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 *NamespacesRoutesReplaceRouteCall) 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": "Replace a route.\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/v1/namespaces/{namespacesId}/routes/{routesId}",
	//   "httpMethod": "PUT",
	//   "id": "run.namespaces.routes.replaceRoute",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the route being replaced. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^namespaces/[^/]+/routes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "apis/serving.knative.dev/v1/{+name}",
	//   "request": {
	//     "$ref": "Route"
	//   },
	//   "response": {
	//     "$ref": "Route"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	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/v1/{+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": "Create a service.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+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: 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
}

// 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.11.0 gdcl/20190924")
	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/v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.namespaces.services.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "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/v1/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"
	//     },
	//     "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/v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	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/v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a service.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+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: 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.11.0 gdcl/20190924")
	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/v1/{+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": "List services.",
	//   "flatPath": "apis/serving.knative.dev/v1/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/v1/{+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: 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.11.0 gdcl/20190924")
	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/v1/{+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": "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/v1/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/v1/{+name}",
	//   "request": {
	//     "$ref": "Service"
	//   },
	//   "response": {
	//     "$ref": "Service"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.get":

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

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

func (c *ProjectsLocationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.get" call.
// Exactly one of *Location or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Location.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 *ProjectsLocationsGetCall) Do(opts ...googleapi.CallOption) (*Location, 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 := &Location{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets information about a location.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Resource name for the location.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Location"
	//   },
	//   "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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/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": "v1/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": "v1/{+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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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": "List authorized domains.",
	//   "flatPath": "v1/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": "v1/{+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.autodomainmappings.create":

type ProjectsLocationsAutodomainmappingsCreateCall struct {
	s                 *APIService
	parent            string
	autodomainmapping *AutoDomainMapping
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

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

func (c *ProjectsLocationsAutodomainmappingsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.autodomainmapping)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/autodomainmappings")
	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.autodomainmappings.create" call.
// Exactly one of *AutoDomainMapping or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AutoDomainMapping.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 *ProjectsLocationsAutodomainmappingsCreateCall) Do(opts ...googleapi.CallOption) (*AutoDomainMapping, 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 := &AutoDomainMapping{
		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 auto domain mapping.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}/autodomainmappings",
	//   "httpMethod": "POST",
	//   "id": "run.projects.locations.autodomainmappings.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this auto domain mapping should\nbe created.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/autodomainmappings",
	//   "request": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "response": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.autodomainmappings.delete":

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

// Delete: Delete an auto domain mapping.
func (r *ProjectsLocationsAutodomainmappingsService) Delete(name string) *ProjectsLocationsAutodomainmappingsDeleteCall {
	c := &ProjectsLocationsAutodomainmappingsDeleteCall{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 *ProjectsLocationsAutodomainmappingsDeleteCall) ApiVersion(apiVersion string) *ProjectsLocationsAutodomainmappingsDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *ProjectsLocationsAutodomainmappingsDeleteCall) Kind(kind string) *ProjectsLocationsAutodomainmappingsDeleteCall {
	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 *ProjectsLocationsAutodomainmappingsDeleteCall) PropagationPolicy(propagationPolicy string) *ProjectsLocationsAutodomainmappingsDeleteCall {
	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 *ProjectsLocationsAutodomainmappingsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsAutodomainmappingsDeleteCall {
	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 *ProjectsLocationsAutodomainmappingsDeleteCall) Context(ctx context.Context) *ProjectsLocationsAutodomainmappingsDeleteCall {
	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 *ProjectsLocationsAutodomainmappingsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsAutodomainmappingsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.autodomainmappings.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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 *ProjectsLocationsAutodomainmappingsDeleteCall) Do(opts ...googleapi.CallOption) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete an auto domain mapping.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}/autodomainmappings/{autodomainmappingsId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.projects.locations.autodomainmappings.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 auto domain mapping being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/autodomainmappings/[^/]+$",
	//       "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": "v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.autodomainmappings.get":

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

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

func (c *ProjectsLocationsAutodomainmappingsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.autodomainmappings.get" call.
// Exactly one of *AutoDomainMapping or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AutoDomainMapping.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 *ProjectsLocationsAutodomainmappingsGetCall) Do(opts ...googleapi.CallOption) (*AutoDomainMapping, 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 := &AutoDomainMapping{
		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 information about an auto domain mapping.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}/autodomainmappings/{autodomainmappingsId}",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.autodomainmappings.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the auto domain mapping being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/autodomainmappings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.autodomainmappings.list":

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

// List: List auto domain mappings.
func (r *ProjectsLocationsAutodomainmappingsService) List(parent string) *ProjectsLocationsAutodomainmappingsListCall {
	c := &ProjectsLocationsAutodomainmappingsListCall{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 *ProjectsLocationsAutodomainmappingsListCall) Continue(continue_ string) *ProjectsLocationsAutodomainmappingsListCall {
	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 *ProjectsLocationsAutodomainmappingsListCall) FieldSelector(fieldSelector string) *ProjectsLocationsAutodomainmappingsListCall {
	c.urlParams_.Set("fieldSelector", fieldSelector)
	return c
}

// IncludeUninitialized sets the optional parameter
// "includeUninitialized": Not currently used by Cloud Run.
func (c *ProjectsLocationsAutodomainmappingsListCall) IncludeUninitialized(includeUninitialized bool) *ProjectsLocationsAutodomainmappingsListCall {
	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 *ProjectsLocationsAutodomainmappingsListCall) LabelSelector(labelSelector string) *ProjectsLocationsAutodomainmappingsListCall {
	c.urlParams_.Set("labelSelector", labelSelector)
	return c
}

// Limit sets the optional parameter "limit": The maximum number of
// records that should be returned.
func (c *ProjectsLocationsAutodomainmappingsListCall) Limit(limit int64) *ProjectsLocationsAutodomainmappingsListCall {
	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 *ProjectsLocationsAutodomainmappingsListCall) ResourceVersion(resourceVersion string) *ProjectsLocationsAutodomainmappingsListCall {
	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 *ProjectsLocationsAutodomainmappingsListCall) Watch(watch bool) *ProjectsLocationsAutodomainmappingsListCall {
	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 *ProjectsLocationsAutodomainmappingsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsAutodomainmappingsListCall {
	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 *ProjectsLocationsAutodomainmappingsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsAutodomainmappingsListCall {
	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 *ProjectsLocationsAutodomainmappingsListCall) Context(ctx context.Context) *ProjectsLocationsAutodomainmappingsListCall {
	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 *ProjectsLocationsAutodomainmappingsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsAutodomainmappingsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/autodomainmappings")
	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.autodomainmappings.list" call.
// Exactly one of *ListAutoDomainMappingsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListAutoDomainMappingsResponse.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 *ProjectsLocationsAutodomainmappingsListCall) Do(opts ...googleapi.CallOption) (*ListAutoDomainMappingsResponse, 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 := &ListAutoDomainMappingsResponse{
		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": "List auto domain mappings.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}/autodomainmappings",
	//   "httpMethod": "GET",
	//   "id": "run.projects.locations.autodomainmappings.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 auto domain mappings 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": "v1/{+parent}/autodomainmappings",
	//   "response": {
	//     "$ref": "ListAutoDomainMappingsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.autodomainmappings.replaceAutoDomainMapping":

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

// ReplaceAutoDomainMapping: Replace an auto domain mapping.
//
// 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 *ProjectsLocationsAutodomainmappingsService) ReplaceAutoDomainMapping(name string, autodomainmapping *AutoDomainMapping) *ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall {
	c := &ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.autodomainmapping = autodomainmapping
	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 *ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall) Fields(s ...googleapi.Field) *ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall {
	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 *ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall) Context(ctx context.Context) *ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall {
	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 *ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.autodomainmapping)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	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.autodomainmappings.replaceAutoDomainMapping" call.
// Exactly one of *AutoDomainMapping or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AutoDomainMapping.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 *ProjectsLocationsAutodomainmappingsReplaceAutoDomainMappingCall) Do(opts ...googleapi.CallOption) (*AutoDomainMapping, 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 := &AutoDomainMapping{
		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": "Replace an auto domain mapping.\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": "v1/projects/{projectsId}/locations/{locationsId}/autodomainmappings/{autodomainmappingsId}",
	//   "httpMethod": "PUT",
	//   "id": "run.projects.locations.autodomainmappings.replaceAutoDomainMapping",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the auto domain mapping being retrieved. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/autodomainmappings/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "response": {
	//     "$ref": "AutoDomainMapping"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.configurations.create":

type ProjectsLocationsConfigurationsCreateCall struct {
	s             *APIService
	parent        string
	configuration *Configuration
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Create: Create a configuration.
func (r *ProjectsLocationsConfigurationsService) Create(parent string, configuration *Configuration) *ProjectsLocationsConfigurationsCreateCall {
	c := &ProjectsLocationsConfigurationsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.configuration = configuration
	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 *ProjectsLocationsConfigurationsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsConfigurationsCreateCall {
	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 *ProjectsLocationsConfigurationsCreateCall) Context(ctx context.Context) *ProjectsLocationsConfigurationsCreateCall {
	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 *ProjectsLocationsConfigurationsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsConfigurationsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.configuration)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/configurations")
	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.configurations.create" 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 *ProjectsLocationsConfigurationsCreateCall) 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": "Create a configuration.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}/configurations",
	//   "httpMethod": "POST",
	//   "id": "run.projects.locations.configurations.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this configuration should be\ncreated.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/configurations",
	//   "request": {
	//     "$ref": "Configuration"
	//   },
	//   "response": {
	//     "$ref": "Configuration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.configurations.delete":

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

// Delete: delete a configuration.
// This will cause the configuration to delete all child revisions.
// Prior to
// calling this, any route referencing the configuration (or
// revision
// from the configuration) must be deleted.
func (r *ProjectsLocationsConfigurationsService) Delete(name string) *ProjectsLocationsConfigurationsDeleteCall {
	c := &ProjectsLocationsConfigurationsDeleteCall{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 *ProjectsLocationsConfigurationsDeleteCall) ApiVersion(apiVersion string) *ProjectsLocationsConfigurationsDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *ProjectsLocationsConfigurationsDeleteCall) Kind(kind string) *ProjectsLocationsConfigurationsDeleteCall {
	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 *ProjectsLocationsConfigurationsDeleteCall) PropagationPolicy(propagationPolicy string) *ProjectsLocationsConfigurationsDeleteCall {
	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 *ProjectsLocationsConfigurationsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsConfigurationsDeleteCall {
	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 *ProjectsLocationsConfigurationsDeleteCall) Context(ctx context.Context) *ProjectsLocationsConfigurationsDeleteCall {
	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 *ProjectsLocationsConfigurationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsConfigurationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.configurations.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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 *ProjectsLocationsConfigurationsDeleteCall) Do(opts ...googleapi.CallOption) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "delete a configuration.\nThis will cause the configuration to delete all child revisions. Prior to\ncalling this, any route referencing the configuration (or revision\nfrom the configuration) must be deleted.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}/configurations/{configurationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.projects.locations.configurations.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 configuration being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/configurations/[^/]+$",
	//       "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": "v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// 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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a configuration.",
	//   "flatPath": "v1/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": "v1/{+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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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": "List configurations.",
	//   "flatPath": "v1/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": "v1/{+parent}/configurations",
	//   "response": {
	//     "$ref": "ListConfigurationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.configurations.replaceConfiguration":

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

// ReplaceConfiguration: Replace a configuration.
//
// 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 *ProjectsLocationsConfigurationsService) ReplaceConfiguration(name string, configuration *Configuration) *ProjectsLocationsConfigurationsReplaceConfigurationCall {
	c := &ProjectsLocationsConfigurationsReplaceConfigurationCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.configuration = configuration
	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 *ProjectsLocationsConfigurationsReplaceConfigurationCall) Fields(s ...googleapi.Field) *ProjectsLocationsConfigurationsReplaceConfigurationCall {
	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 *ProjectsLocationsConfigurationsReplaceConfigurationCall) Context(ctx context.Context) *ProjectsLocationsConfigurationsReplaceConfigurationCall {
	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 *ProjectsLocationsConfigurationsReplaceConfigurationCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsConfigurationsReplaceConfigurationCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.configuration)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	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.configurations.replaceConfiguration" 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 *ProjectsLocationsConfigurationsReplaceConfigurationCall) 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": "Replace a configuration.\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": "v1/projects/{projectsId}/locations/{locationsId}/configurations/{configurationsId}",
	//   "httpMethod": "PUT",
	//   "id": "run.projects.locations.configurations.replaceConfiguration",
	//   "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": "v1/{+name}",
	//   "request": {
	//     "$ref": "Configuration"
	//   },
	//   "response": {
	//     "$ref": "Configuration"
	//   },
	//   "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: Create 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.11.0 gdcl/20190924")
	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, "v1/{+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": "Create a new domain mapping.",
	//   "flatPath": "v1/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": "v1/{+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: 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
}

// 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.domainmappings.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete a domain mapping.",
	//   "flatPath": "v1/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"
	//     },
	//     "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": "v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a domain mapping.",
	//   "flatPath": "v1/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": "v1/{+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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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": "List domain mappings.",
	//   "flatPath": "v1/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": "v1/{+parent}/domainmappings",
	//   "response": {
	//     "$ref": "ListDomainMappingsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.domainmappings.replaceDomainMapping":

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

// ReplaceDomainMapping: Replace a domain mapping.
//
// 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 *ProjectsLocationsDomainmappingsService) ReplaceDomainMapping(name string, domainmapping *DomainMapping) *ProjectsLocationsDomainmappingsReplaceDomainMappingCall {
	c := &ProjectsLocationsDomainmappingsReplaceDomainMappingCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsLocationsDomainmappingsReplaceDomainMappingCall) Fields(s ...googleapi.Field) *ProjectsLocationsDomainmappingsReplaceDomainMappingCall {
	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 *ProjectsLocationsDomainmappingsReplaceDomainMappingCall) Context(ctx context.Context) *ProjectsLocationsDomainmappingsReplaceDomainMappingCall {
	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 *ProjectsLocationsDomainmappingsReplaceDomainMappingCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsDomainmappingsReplaceDomainMappingCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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, "v1/{+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.domainmappings.replaceDomainMapping" 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 *ProjectsLocationsDomainmappingsReplaceDomainMappingCall) 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": "Replace a domain mapping.\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": "v1/projects/{projectsId}/locations/{locationsId}/domainmappings/{domainmappingsId}",
	//   "httpMethod": "PUT",
	//   "id": "run.projects.locations.domainmappings.replaceDomainMapping",
	//   "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": "v1/{+name}",
	//   "request": {
	//     "$ref": "DomainMapping"
	//   },
	//   "response": {
	//     "$ref": "DomainMapping"
	//   },
	//   "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: 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
}

// 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.revisions.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete a revision.",
	//   "flatPath": "v1/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"
	//     },
	//     "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": "v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a revision.",
	//   "flatPath": "v1/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": "v1/{+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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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": "List revisions.",
	//   "flatPath": "v1/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": "v1/{+parent}/revisions",
	//   "response": {
	//     "$ref": "ListRevisionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.routes.create":

type ProjectsLocationsRoutesCreateCall struct {
	s          *APIService
	parent     string
	route      *Route
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Create a route.
func (r *ProjectsLocationsRoutesService) Create(parent string, route *Route) *ProjectsLocationsRoutesCreateCall {
	c := &ProjectsLocationsRoutesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.route = route
	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 *ProjectsLocationsRoutesCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsRoutesCreateCall {
	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 *ProjectsLocationsRoutesCreateCall) Context(ctx context.Context) *ProjectsLocationsRoutesCreateCall {
	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 *ProjectsLocationsRoutesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsRoutesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.route)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/routes")
	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.routes.create" 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 *ProjectsLocationsRoutesCreateCall) 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": "Create a route.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}/routes",
	//   "httpMethod": "POST",
	//   "id": "run.projects.locations.routes.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "The project ID or project number in which this route should be created.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/routes",
	//   "request": {
	//     "$ref": "Route"
	//   },
	//   "response": {
	//     "$ref": "Route"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.routes.delete":

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

// Delete: Delete a route.
// This will cause the route to stop serving traffic.
func (r *ProjectsLocationsRoutesService) Delete(name string) *ProjectsLocationsRoutesDeleteCall {
	c := &ProjectsLocationsRoutesDeleteCall{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 *ProjectsLocationsRoutesDeleteCall) ApiVersion(apiVersion string) *ProjectsLocationsRoutesDeleteCall {
	c.urlParams_.Set("apiVersion", apiVersion)
	return c
}

// Kind sets the optional parameter "kind": Cloud Run currently ignores
// this parameter.
func (c *ProjectsLocationsRoutesDeleteCall) Kind(kind string) *ProjectsLocationsRoutesDeleteCall {
	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 *ProjectsLocationsRoutesDeleteCall) PropagationPolicy(propagationPolicy string) *ProjectsLocationsRoutesDeleteCall {
	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 *ProjectsLocationsRoutesDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsRoutesDeleteCall {
	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 *ProjectsLocationsRoutesDeleteCall) Context(ctx context.Context) *ProjectsLocationsRoutesDeleteCall {
	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 *ProjectsLocationsRoutesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsRoutesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.routes.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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 *ProjectsLocationsRoutesDeleteCall) Do(opts ...googleapi.CallOption) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete a route.\nThis will cause the route to stop serving traffic.",
	//   "flatPath": "v1/projects/{projectsId}/locations/{locationsId}/routes/{routesId}",
	//   "httpMethod": "DELETE",
	//   "id": "run.projects.locations.routes.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 route being deleted. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/routes/[^/]+$",
	//       "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": "v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a route.",
	//   "flatPath": "v1/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": "v1/{+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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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": "List routes.",
	//   "flatPath": "v1/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": "v1/{+parent}/routes",
	//   "response": {
	//     "$ref": "ListRoutesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "run.projects.locations.routes.replaceRoute":

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

// ReplaceRoute: Replace a route.
//
// 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 *ProjectsLocationsRoutesService) ReplaceRoute(name string, route *Route) *ProjectsLocationsRoutesReplaceRouteCall {
	c := &ProjectsLocationsRoutesReplaceRouteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.route = route
	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 *ProjectsLocationsRoutesReplaceRouteCall) Fields(s ...googleapi.Field) *ProjectsLocationsRoutesReplaceRouteCall {
	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 *ProjectsLocationsRoutesReplaceRouteCall) Context(ctx context.Context) *ProjectsLocationsRoutesReplaceRouteCall {
	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 *ProjectsLocationsRoutesReplaceRouteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsRoutesReplaceRouteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20190924")
	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.route)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	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.routes.replaceRoute" 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 *ProjectsLocationsRoutesReplaceRouteCall) 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": "Replace a route.\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": "v1/projects/{projectsId}/locations/{locationsId}/routes/{routesId}",
	//   "httpMethod": "PUT",
	//   "id": "run.projects.locations.routes.replaceRoute",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the route being replaced. If needed, replace\n{namespace_id} with the project ID.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/routes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "Route"
	//   },
	//   "response": {
	//     "$ref": "Route"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	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, "v1/{+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": "Create a service.",
	//   "flatPath": "v1/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": "v1/{+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: 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
}

// 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "run.projects.locations.services.delete" call.
// Exactly one of *K8sIoApimachineryPkgApisMetaV1Status or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *K8sIoApimachineryPkgApisMetaV1Status.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) (*K8sIoApimachineryPkgApisMetaV1Status, 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 := &K8sIoApimachineryPkgApisMetaV1Status{
		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": "Delete a service.\nThis will cause the Service to stop serving traffic and will delete the\nchild entities like Routes, Configurations and Revisions.",
	//   "flatPath": "v1/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"
	//     },
	//     "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": "v1/{+name}",
	//   "response": {
	//     "$ref": "K8sIoApimachineryPkgApisMetaV1Status"
	//   },
	//   "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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "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": "Get information about a service.",
	//   "flatPath": "v1/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": "v1/{+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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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": "v1/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": "v1/{+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: 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.11.0 gdcl/20190924")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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": "List services.",
	//   "flatPath": "v1/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": "v1/{+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: 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.11.0 gdcl/20190924")
	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, "v1/{+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": "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": "v1/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": "v1/{+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.11.0 gdcl/20190924")
	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, "v1/{+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": "v1/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": "v1/{+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.11.0 gdcl/20190924")
	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, "v1/{+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": "v1/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": "v1/{+resource}:testIamPermissions",
	//   "request": {
	//     "$ref": "TestIamPermissionsRequest"
	//   },
	//   "response": {
	//     "$ref": "TestIamPermissionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
