// Copyright 2023 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 integrations provides access to the Application Integration API.
//
// For product documentation, see: https://cloud.google.com/application-integration
//
// # Creating a client
//
// Usage example:
//
//	import "google.golang.org/api/integrations/v1alpha"
//	...
//	ctx := context.Background()
//	integrationsService, err := integrations.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:
//
//	integrationsService, err := integrations.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, ...)
//	integrationsService, err := integrations.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package integrations // import "google.golang.org/api/integrations/v1alpha"

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

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

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

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

// OAuth2 scopes used by this API.
const (
	// See, edit, configure, and delete your Google Cloud data and see the
	// email address for your Google Account.
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

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

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

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

	Callback *CallbackService

	ConnectorPlatformRegions *ConnectorPlatformRegionsService

	Projects *ProjectsService
}

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

func NewCallbackService(s *Service) *CallbackService {
	rs := &CallbackService{s: s}
	return rs
}

type CallbackService struct {
	s *Service
}

func NewConnectorPlatformRegionsService(s *Service) *ConnectorPlatformRegionsService {
	rs := &ConnectorPlatformRegionsService{s: s}
	return rs
}

type ConnectorPlatformRegionsService struct {
	s *Service
}

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

type ProjectsService struct {
	s *Service

	Locations *ProjectsLocationsService
}

func NewProjectsLocationsService(s *Service) *ProjectsLocationsService {
	rs := &ProjectsLocationsService{s: s}
	rs.AppsScriptProjects = NewProjectsLocationsAppsScriptProjectsService(s)
	rs.AuthConfigs = NewProjectsLocationsAuthConfigsService(s)
	rs.Certificates = NewProjectsLocationsCertificatesService(s)
	rs.Connections = NewProjectsLocationsConnectionsService(s)
	rs.Integrations = NewProjectsLocationsIntegrationsService(s)
	rs.Products = NewProjectsLocationsProductsService(s)
	rs.SfdcInstances = NewProjectsLocationsSfdcInstancesService(s)
	return rs
}

type ProjectsLocationsService struct {
	s *Service

	AppsScriptProjects *ProjectsLocationsAppsScriptProjectsService

	AuthConfigs *ProjectsLocationsAuthConfigsService

	Certificates *ProjectsLocationsCertificatesService

	Connections *ProjectsLocationsConnectionsService

	Integrations *ProjectsLocationsIntegrationsService

	Products *ProjectsLocationsProductsService

	SfdcInstances *ProjectsLocationsSfdcInstancesService
}

func NewProjectsLocationsAppsScriptProjectsService(s *Service) *ProjectsLocationsAppsScriptProjectsService {
	rs := &ProjectsLocationsAppsScriptProjectsService{s: s}
	return rs
}

type ProjectsLocationsAppsScriptProjectsService struct {
	s *Service
}

func NewProjectsLocationsAuthConfigsService(s *Service) *ProjectsLocationsAuthConfigsService {
	rs := &ProjectsLocationsAuthConfigsService{s: s}
	return rs
}

type ProjectsLocationsAuthConfigsService struct {
	s *Service
}

func NewProjectsLocationsCertificatesService(s *Service) *ProjectsLocationsCertificatesService {
	rs := &ProjectsLocationsCertificatesService{s: s}
	return rs
}

type ProjectsLocationsCertificatesService struct {
	s *Service
}

func NewProjectsLocationsConnectionsService(s *Service) *ProjectsLocationsConnectionsService {
	rs := &ProjectsLocationsConnectionsService{s: s}
	rs.RuntimeActionSchemas = NewProjectsLocationsConnectionsRuntimeActionSchemasService(s)
	rs.RuntimeEntitySchemas = NewProjectsLocationsConnectionsRuntimeEntitySchemasService(s)
	return rs
}

type ProjectsLocationsConnectionsService struct {
	s *Service

	RuntimeActionSchemas *ProjectsLocationsConnectionsRuntimeActionSchemasService

	RuntimeEntitySchemas *ProjectsLocationsConnectionsRuntimeEntitySchemasService
}

func NewProjectsLocationsConnectionsRuntimeActionSchemasService(s *Service) *ProjectsLocationsConnectionsRuntimeActionSchemasService {
	rs := &ProjectsLocationsConnectionsRuntimeActionSchemasService{s: s}
	return rs
}

type ProjectsLocationsConnectionsRuntimeActionSchemasService struct {
	s *Service
}

func NewProjectsLocationsConnectionsRuntimeEntitySchemasService(s *Service) *ProjectsLocationsConnectionsRuntimeEntitySchemasService {
	rs := &ProjectsLocationsConnectionsRuntimeEntitySchemasService{s: s}
	return rs
}

type ProjectsLocationsConnectionsRuntimeEntitySchemasService struct {
	s *Service
}

func NewProjectsLocationsIntegrationsService(s *Service) *ProjectsLocationsIntegrationsService {
	rs := &ProjectsLocationsIntegrationsService{s: s}
	rs.Executions = NewProjectsLocationsIntegrationsExecutionsService(s)
	rs.Versions = NewProjectsLocationsIntegrationsVersionsService(s)
	return rs
}

type ProjectsLocationsIntegrationsService struct {
	s *Service

	Executions *ProjectsLocationsIntegrationsExecutionsService

	Versions *ProjectsLocationsIntegrationsVersionsService
}

func NewProjectsLocationsIntegrationsExecutionsService(s *Service) *ProjectsLocationsIntegrationsExecutionsService {
	rs := &ProjectsLocationsIntegrationsExecutionsService{s: s}
	rs.Suspensions = NewProjectsLocationsIntegrationsExecutionsSuspensionsService(s)
	return rs
}

type ProjectsLocationsIntegrationsExecutionsService struct {
	s *Service

	Suspensions *ProjectsLocationsIntegrationsExecutionsSuspensionsService
}

func NewProjectsLocationsIntegrationsExecutionsSuspensionsService(s *Service) *ProjectsLocationsIntegrationsExecutionsSuspensionsService {
	rs := &ProjectsLocationsIntegrationsExecutionsSuspensionsService{s: s}
	return rs
}

type ProjectsLocationsIntegrationsExecutionsSuspensionsService struct {
	s *Service
}

func NewProjectsLocationsIntegrationsVersionsService(s *Service) *ProjectsLocationsIntegrationsVersionsService {
	rs := &ProjectsLocationsIntegrationsVersionsService{s: s}
	return rs
}

type ProjectsLocationsIntegrationsVersionsService struct {
	s *Service
}

func NewProjectsLocationsProductsService(s *Service) *ProjectsLocationsProductsService {
	rs := &ProjectsLocationsProductsService{s: s}
	rs.AuthConfigs = NewProjectsLocationsProductsAuthConfigsService(s)
	rs.Certificates = NewProjectsLocationsProductsCertificatesService(s)
	rs.Integrations = NewProjectsLocationsProductsIntegrationsService(s)
	rs.Integrationtemplates = NewProjectsLocationsProductsIntegrationtemplatesService(s)
	rs.SfdcInstances = NewProjectsLocationsProductsSfdcInstancesService(s)
	return rs
}

type ProjectsLocationsProductsService struct {
	s *Service

	AuthConfigs *ProjectsLocationsProductsAuthConfigsService

	Certificates *ProjectsLocationsProductsCertificatesService

	Integrations *ProjectsLocationsProductsIntegrationsService

	Integrationtemplates *ProjectsLocationsProductsIntegrationtemplatesService

	SfdcInstances *ProjectsLocationsProductsSfdcInstancesService
}

func NewProjectsLocationsProductsAuthConfigsService(s *Service) *ProjectsLocationsProductsAuthConfigsService {
	rs := &ProjectsLocationsProductsAuthConfigsService{s: s}
	return rs
}

type ProjectsLocationsProductsAuthConfigsService struct {
	s *Service
}

func NewProjectsLocationsProductsCertificatesService(s *Service) *ProjectsLocationsProductsCertificatesService {
	rs := &ProjectsLocationsProductsCertificatesService{s: s}
	return rs
}

type ProjectsLocationsProductsCertificatesService struct {
	s *Service
}

func NewProjectsLocationsProductsIntegrationsService(s *Service) *ProjectsLocationsProductsIntegrationsService {
	rs := &ProjectsLocationsProductsIntegrationsService{s: s}
	rs.Executions = NewProjectsLocationsProductsIntegrationsExecutionsService(s)
	rs.Versions = NewProjectsLocationsProductsIntegrationsVersionsService(s)
	return rs
}

type ProjectsLocationsProductsIntegrationsService struct {
	s *Service

	Executions *ProjectsLocationsProductsIntegrationsExecutionsService

	Versions *ProjectsLocationsProductsIntegrationsVersionsService
}

func NewProjectsLocationsProductsIntegrationsExecutionsService(s *Service) *ProjectsLocationsProductsIntegrationsExecutionsService {
	rs := &ProjectsLocationsProductsIntegrationsExecutionsService{s: s}
	rs.Suspensions = NewProjectsLocationsProductsIntegrationsExecutionsSuspensionsService(s)
	return rs
}

type ProjectsLocationsProductsIntegrationsExecutionsService struct {
	s *Service

	Suspensions *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsService
}

func NewProjectsLocationsProductsIntegrationsExecutionsSuspensionsService(s *Service) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsService {
	rs := &ProjectsLocationsProductsIntegrationsExecutionsSuspensionsService{s: s}
	return rs
}

type ProjectsLocationsProductsIntegrationsExecutionsSuspensionsService struct {
	s *Service
}

func NewProjectsLocationsProductsIntegrationsVersionsService(s *Service) *ProjectsLocationsProductsIntegrationsVersionsService {
	rs := &ProjectsLocationsProductsIntegrationsVersionsService{s: s}
	return rs
}

type ProjectsLocationsProductsIntegrationsVersionsService struct {
	s *Service
}

func NewProjectsLocationsProductsIntegrationtemplatesService(s *Service) *ProjectsLocationsProductsIntegrationtemplatesService {
	rs := &ProjectsLocationsProductsIntegrationtemplatesService{s: s}
	rs.Versions = NewProjectsLocationsProductsIntegrationtemplatesVersionsService(s)
	return rs
}

type ProjectsLocationsProductsIntegrationtemplatesService struct {
	s *Service

	Versions *ProjectsLocationsProductsIntegrationtemplatesVersionsService
}

func NewProjectsLocationsProductsIntegrationtemplatesVersionsService(s *Service) *ProjectsLocationsProductsIntegrationtemplatesVersionsService {
	rs := &ProjectsLocationsProductsIntegrationtemplatesVersionsService{s: s}
	return rs
}

type ProjectsLocationsProductsIntegrationtemplatesVersionsService struct {
	s *Service
}

func NewProjectsLocationsProductsSfdcInstancesService(s *Service) *ProjectsLocationsProductsSfdcInstancesService {
	rs := &ProjectsLocationsProductsSfdcInstancesService{s: s}
	rs.SfdcChannels = NewProjectsLocationsProductsSfdcInstancesSfdcChannelsService(s)
	return rs
}

type ProjectsLocationsProductsSfdcInstancesService struct {
	s *Service

	SfdcChannels *ProjectsLocationsProductsSfdcInstancesSfdcChannelsService
}

func NewProjectsLocationsProductsSfdcInstancesSfdcChannelsService(s *Service) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsService {
	rs := &ProjectsLocationsProductsSfdcInstancesSfdcChannelsService{s: s}
	return rs
}

type ProjectsLocationsProductsSfdcInstancesSfdcChannelsService struct {
	s *Service
}

func NewProjectsLocationsSfdcInstancesService(s *Service) *ProjectsLocationsSfdcInstancesService {
	rs := &ProjectsLocationsSfdcInstancesService{s: s}
	rs.SfdcChannels = NewProjectsLocationsSfdcInstancesSfdcChannelsService(s)
	return rs
}

type ProjectsLocationsSfdcInstancesService struct {
	s *Service

	SfdcChannels *ProjectsLocationsSfdcInstancesSfdcChannelsService
}

func NewProjectsLocationsSfdcInstancesSfdcChannelsService(s *Service) *ProjectsLocationsSfdcInstancesSfdcChannelsService {
	rs := &ProjectsLocationsSfdcInstancesSfdcChannelsService{s: s}
	return rs
}

type ProjectsLocationsSfdcInstancesSfdcChannelsService struct {
	s *Service
}

// CrmlogErrorCode: Registered ids for errors, as "oneof" enums. Each
// task or logical grouping of tasks may share the same enum.
type CrmlogErrorCode struct {
	// Possible values:
	//   "COMMON_ERROR_CODE_UNSPECIFIED"
	//   "INVALID_CREDENTIALS"
	//   "REQUIRED_FIELDS_MISSING"
	//   "INVALID_FIELDS"
	//   "BACKEND"
	//   "GENERAL"
	//   "INTERNAL"
	//   "IO_ERROR"
	//   "NOT_FOUND"
	//   "EVENT_BUS"
	//   "ALREADY_EXISTS"
	//   "CONCORD"
	//   "CONVERSION"
	//   "FLUME"
	//   "PERMISSION"
	//   "SALES_FORCE"
	//   "SPANNER"
	//   "UNIMPLEMENTED"
	//   "RELTIO"
	//   "WORKFLOW_NOT_FOUND"
	//   "QUOTA_THROTTLED"
	//   "QUOTA_ENQUEUED"
	//   "INVALID_QUOTA_CONFIGURATION"
	//   "TASK_NOT_FOUND"
	//   "EXECUTION_TIMEOUT"
	//   "INVALID_EVENT_EXECUTION_STATE"
	//   "INVALID_ATTRIBUTE"
	//   "MISSING_ATTRIBUTE"
	//   "CLIENT_UNAUTHORIZED_FOR_WORKFLOW"
	//   "INVALID_PARAMETER"
	//   "MISSING_PARAMETER"
	//   "UNAUTHROIZED_WORKFLOW_EDITOR_ACTION"
	//   "FAILED_PRECONDITION"
	//   "INVALID_CLIENT"
	//   "MISSING_CLIENT"
	//   "INVALID_WORKFLOW"
	//   "MISSING_QUOTA_CONFIGURATION"
	//   "UNHANDLED_TASK_ERROR"
	//   "SCRIPT_TASK_RUNTIME_ERROR"
	//   "RPC"
	//   "INVALID_PROTO"
	//   "UNHANDLED_EVENTBUS_ERROR"
	//   "INVALID_TASK_STATE"
	//   "TYPED_TASK_INVALID_INPUT_OPERATION"
	//   "TYPED_TASK_INVALID_OUTPUT_OPERATION"
	//   "VALIDATION_ERROR"
	//   "RESUME_ERROR"
	//   "APPS_SCRIPT_EXECUTION_ERROR"
	//   "INVALID_VECTOR_USER"
	//   "INFORMATICA"
	//   "RETRYABLE_TASK_ERROR"
	//   "INVALID_TENANT"
	//   "WRONG_TENANT"
	//   "INFORMATICA_BACKEND_UNAVAILABLE"
	//   "RPC_PERMISSION_DENIED"
	//   "SYNC_EVENTBUS_EXECUTION_TIMEOUT" - SYNC_EVENTBUS_EXECUTION_TIMEOUT
	// is for eventbus internal use only.
	//   "ASYNC_EVENTBUS_EXECUTION_TIMEOUT" -
	// ASYNC_EVENTBUS_EXECUTION_TIMEOUT is for eventbus internal use only.
	// This error will be counted as server availability error.
	//   "NOT_SUPPORTED_DATA_TYPE"
	//   "UNSANITIZED_USER_INPUT"
	//   "TRANSFORM_EXPRESSION_EVALUATION_ERROR"
	//   "HTTP_EXCEPTION"
	//   "EXECUTION_CANCELLED"
	CommonErrorCode string `json:"commonErrorCode,omitempty"`

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

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

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

type EnterpriseCrmEventbusAuthconfigAuthConfigTaskParam struct {
	// AllowedCredentialTypes: Defines the credential types to be supported
	// as Task may restrict specific types to use, e.g. Cloud SQL Task will
	// use username/password type only.
	//
	// Possible values:
	//   "CREDENTIAL_TYPE_UNSPECIFIED"
	//   "USERNAME_AND_PASSWORD" - Regular username/password pair.
	//   "API_KEY" - API key.
	//   "OAUTH2_AUTHORIZATION_CODE" - OAuth 2.0 Authorization Code Grant
	// Type.
	//   "OAUTH2_IMPLICIT" - OAuth 2.0 Implicit Grant Type.
	//   "OAUTH2_CLIENT_CREDENTIALS" - OAuth 2.0 Client Credentials Grant
	// Type.
	//   "OAUTH2_RESOURCE_OWNER_CREDENTIALS" - OAuth 2.0 Resource Owner
	// Credentials Grant Type.
	//   "JWT" - JWT Token.
	//   "AUTH_TOKEN" - Auth Token, e.g. bearer token.
	//   "SERVICE_ACCOUNT" - Service Account which can be used to generate
	// token for authentication.
	//   "CLIENT_CERTIFICATE_ONLY" - Client Certificate only.
	//   "OIDC_TOKEN" - Google OIDC ID Token
	AllowedCredentialTypes []string `json:"allowedCredentialTypes,omitempty"`

	AllowedServiceAccountInContext bool `json:"allowedServiceAccountInContext,omitempty"`

	// AuthConfigId: UUID of the AuthConfig.
	AuthConfigId string `json:"authConfigId,omitempty"`

	// Scope: A space-delimited list of requested scope permissions.
	Scope string `json:"scope,omitempty"`

	UseServiceAccountInContext bool `json:"useServiceAccountInContext,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoAddress: Email address along with optional
// name and tokens. These tokens will be substituted for the variables
// in the form of [{var_name}], where var_name could be any string of no
// more than 32 bytes.
type EnterpriseCrmEventbusProtoAddress struct {
	// Email: Required.
	Email string `json:"email,omitempty"`

	Name string `json:"name,omitempty"`

	Tokens []*EnterpriseCrmEventbusProtoToken `json:"tokens,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoAttributes: Attributes are additional
// options that can be associated with each event property. For more
// information, see
type EnterpriseCrmEventbusProtoAttributes struct {
	// DataType: Things like URL, Email, Currency, Timestamp (rather than
	// string, int64...)
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "EMAIL"
	//   "URL"
	//   "CURRENCY"
	//   "TIMESTAMP"
	//   "DOMAIN_NAME" - Domain is a web url string with one top-level
	// private domain and a suffix (for example: google.com, walmart.com)
	DataType string `json:"dataType,omitempty"`

	// DefaultValue: Used to define defaults.
	DefaultValue *EnterpriseCrmEventbusProtoValueType `json:"defaultValue,omitempty"`

	// IsRequired: Required for event execution. The validation will be done
	// by the event bus when the event is triggered.
	IsRequired bool `json:"isRequired,omitempty"`

	// IsSearchable: Used to indicate if a ParameterEntry should be
	// converted to ParamIndexes for ST-Spanner full-text search.
	// DEPRECATED: use searchable.
	IsSearchable bool `json:"isSearchable,omitempty"`

	// LogSettings: See
	LogSettings *EnterpriseCrmEventbusProtoLogSettings `json:"logSettings,omitempty"`

	// Possible values:
	//   "UNSPECIFIED"
	//   "YES" - If yes, the parameter key and value will be full-text
	// indexed. In a proto, this value will propagate to all children whose
	// searchable is unspecified.
	//   "NO" - If no, the parameter key and value will not be full-text
	// indexed. In a proto, this value will propagate to all children whose
	// searchable is unspecified.
	Searchable string `json:"searchable,omitempty"`

	// TaskVisibility: List of tasks that can view this property, if empty
	// then all.
	TaskVisibility []string `json:"taskVisibility,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoBaseAlertConfigErrorEnumList: List of error
// enums for alerts.
type EnterpriseCrmEventbusProtoBaseAlertConfigErrorEnumList struct {
	EnumStrings []string `json:"enumStrings,omitempty"`

	// Possible values:
	//   "DEFAULT_INCLUSIVE"
	//   "EXCLUSIVE"
	FilterType string `json:"filterType,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoBaseAlertConfigThresholdValue: The
// threshold value of the metric, above or below which the alert should
// be triggered. See EventAlertConfig or TaskAlertConfig for the
// different alert metric types in each case. For the *RATE metrics, one
// or both of these fields may be set. Zero is the default value and can
// be left at that. For *PERCENTILE_DURATION metrics, one or both of
// these fields may be set, and also, the duration threshold value
// should be specified in the threshold_duration_ms member below. For
// *AVERAGE_DURATION metrics, these fields should not be set at all. A
// different member, threshold_duration_ms, must be set in the
// EventAlertConfig or the TaskAlertConfig.
type EnterpriseCrmEventbusProtoBaseAlertConfigThresholdValue struct {
	Absolute int64 `json:"absolute,omitempty,string"`

	Percentage int64 `json:"percentage,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoBaseFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "NOW_IN_MILLIS"
	//   "INT_LIST"
	//   "ENVIRONMENT"
	//   "GET_EXECUTION_ID"
	//   "GET_INTEGRATION_NAME"
	//   "GET_REGION"
	//   "GET_UUID"
	//   "GET_PROJECT_ID"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoBaseValue struct {
	// BaseFunction: Start with a function that does not build on existing
	// values. Eg. CurrentTime, Min, Max, Exists, etc.
	BaseFunction *EnterpriseCrmEventbusProtoFunction `json:"baseFunction,omitempty"`

	// LiteralValue: Start with a literal value.
	LiteralValue *EnterpriseCrmEventbusProtoParameterValueType `json:"literalValue,omitempty"`

	// ReferenceValue: Start with a reference value to dereference.
	ReferenceValue string `json:"referenceValue,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoBooleanArrayFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "GET"
	//   "APPEND"
	//   "SIZE"
	//   "TO_SET"
	//   "APPEND_ALL"
	//   "TO_JSON"
	//   "SET"
	//   "REMOVE"
	//   "REMOVE_AT"
	//   "CONTAINS"
	//   "FOR_EACH"
	//   "FILTER"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoBooleanFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "TO_JSON"
	//   "NOT"
	//   "AND"
	//   "NAND"
	//   "OR"
	//   "XOR"
	//   "NOR"
	//   "XNOR"
	//   "TO_STRING"
	//   "EQUALS"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoBooleanParameterArray struct {
	BooleanValues []bool `json:"booleanValues,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoBuganizerNotification struct {
	// AssigneeEmailAddress: Whom to assign the new bug. Optional.
	AssigneeEmailAddress string `json:"assigneeEmailAddress,omitempty"`

	// ComponentId: ID of the buganizer component within which to create a
	// new issue. Required.
	ComponentId int64 `json:"componentId,omitempty,string"`

	// TemplateId: ID of the buganizer template to use. Optional.
	TemplateId int64 `json:"templateId,omitempty,string"`

	// Title: Title of the issue to be created. Required.
	Title string `json:"title,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoCloudKmsConfig struct {
	// GcpProjectId: Optional. The id of GCP project where the KMS key is
	// stored. If not provided, assume the key is stored in the same GCP
	// project defined in Client (tag 14).
	GcpProjectId string `json:"gcpProjectId,omitempty"`

	// KeyName: A Cloud KMS key is a named object containing one or more key
	// versions, along with metadata for the key. A key exists on exactly
	// one key ring tied to a specific location.
	KeyName string `json:"keyName,omitempty"`

	// KeyRingName: A key ring organizes keys in a specific Google Cloud
	// location and allows you to manage access control on groups of keys. A
	// key ring's name does not need to be unique across a Google Cloud
	// project, but must be unique within a given location.
	KeyRingName string `json:"keyRingName,omitempty"`

	// KeyVersionName: Optional. Each version of a key contains key material
	// used for encryption or signing. A key's version is represented by an
	// integer, starting at 1. To decrypt data or verify a signature, you
	// must use the same key version that was used to encrypt or sign the
	// data.
	KeyVersionName string `json:"keyVersionName,omitempty"`

	// LocationName: Location name of the key ring, e.g. "us-west1".
	LocationName string `json:"locationName,omitempty"`

	// ServiceAccount: Optional. The service account used for authentication
	// of this KMS key. If this is not provided, the service account in
	// Client.clientSource will be used.
	ServiceAccount string `json:"serviceAccount,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoCloudSchedulerConfig: Cloud Scheduler
// Trigger configuration
type EnterpriseCrmEventbusProtoCloudSchedulerConfig struct {
	// CronTab: Required. The cron tab of cloud scheduler trigger.
	CronTab string `json:"cronTab,omitempty"`

	// ErrorMessage: Optional. When the job was deleted from Pantheon UI,
	// error_message will be populated when Get/List integrations
	ErrorMessage string `json:"errorMessage,omitempty"`

	// Location: Required. The location where associated cloud scheduler job
	// will be created
	Location string `json:"location,omitempty"`

	// ServiceAccountEmail: Required. Service account used by Cloud
	// Scheduler to trigger the integration at scheduled time
	ServiceAccountEmail string `json:"serviceAccountEmail,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoCombinedCondition: This message recursively
// combines constituent conditions using logical AND.
type EnterpriseCrmEventbusProtoCombinedCondition struct {
	// Conditions: A set of individual constituent conditions.
	Conditions []*EnterpriseCrmEventbusProtoCondition `json:"conditions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Conditions") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EnterpriseCrmEventbusProtoCombinedCondition) MarshalJSON() ([]byte, error) {
	type NoMethod EnterpriseCrmEventbusProtoCombinedCondition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnterpriseCrmEventbusProtoCondition: Condition that uses `operator`
// to evaluate the key against the value.
type EnterpriseCrmEventbusProtoCondition struct {
	// EventPropertyKey: Key that's evaluated against the `value`. Please
	// note the data type of the runtime value associated with the key
	// should match the data type of `value`, else an
	// IllegalArgumentException is thrown.
	EventPropertyKey string `json:"eventPropertyKey,omitempty"`

	// Operator: Operator used to evaluate the condition. Please note that
	// an operator with an inappropriate key/value operand will result in
	// IllegalArgumentException, e.g. CONTAINS with boolean key/value pair.
	//
	// Possible values:
	//   "UNSET"
	//   "EQUALS"
	//   "CONTAINS"
	//   "LESS_THAN"
	//   "GREATER_THAN"
	//   "EXISTS"
	//   "DOES_NOT_EXIST"
	//   "IS_EMPTY"
	//   "IS_NOT_EMPTY"
	Operator string `json:"operator,omitempty"`

	// Value: Value that's checked for the key.
	Value *EnterpriseCrmEventbusProtoValueType `json:"value,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoConditionResult: Contains the combined
// condition calculation results.
type EnterpriseCrmEventbusProtoConditionResult struct {
	// CurrentTaskNumber: the current task number.
	CurrentTaskNumber string `json:"currentTaskNumber,omitempty"`

	// NextTaskNumber: the next task number.
	NextTaskNumber string `json:"nextTaskNumber,omitempty"`

	// Result: the result comes out after evaluate the combined condition.
	// True if there's no combined condition specified.
	Result bool `json:"result,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoConnectorsConnection struct {
	// ConnectionName: Connection name Format:
	// projects/{project}/locations/{location}/connections/{connection}
	ConnectionName string `json:"connectionName,omitempty"`

	// ConnectorVersion: Connector version Format:
	// projects/{project}/locations/{location}/providers/{provider}/connector
	// s/{connector}/versions/{version}
	ConnectorVersion string `json:"connectorVersion,omitempty"`

	// ServiceName: Service name Format:
	// projects/{project}/locations/{location}/namespaces/{namespace}/service
	// s/{service}
	ServiceName string `json:"serviceName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoConnectorsGenericConnectorTaskConfig struct {
	// Connection: User-selected connection.
	Connection *EnterpriseCrmEventbusProtoConnectorsConnection `json:"connection,omitempty"`

	// Operation: Operation to perform using the configured connection.
	//
	// Possible values:
	//   "OPERATION_UNSPECIFIED"
	//   "EXECUTE_ACTION"
	//   "LIST_ENTITIES"
	//   "GET_ENTITY"
	//   "CREATE_ENTITY"
	//   "UPDATE_ENTITY"
	//   "DELETE_ENTITY"
	Operation string `json:"operation,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoCoordinate: Represents two-dimensional
// positions.
type EnterpriseCrmEventbusProtoCoordinate struct {
	X int64 `json:"x,omitempty"`

	Y int64 `json:"y,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoCustomSuspensionRequest struct {
	// PostToQueueWithTriggerIdRequest: Request to fire an event containing
	// the SuspensionInfo message.
	PostToQueueWithTriggerIdRequest *GoogleInternalCloudCrmEventbusV3PostToQueueWithTriggerIdRequest `json:"postToQueueWithTriggerIdRequest,omitempty"`

	// SuspensionInfoEventParameterKey: In the fired event, set the
	// SuspensionInfo message as the value for this key.
	SuspensionInfoEventParameterKey string `json:"suspensionInfoEventParameterKey,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoDoubleArray struct {
	Values []float64 `json:"values,omitempty"`

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

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

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

func (s *EnterpriseCrmEventbusProtoDoubleArray) UnmarshalJSON(data []byte) error {
	type NoMethod EnterpriseCrmEventbusProtoDoubleArray
	var s1 struct {
		Values []gensupport.JSONFloat64 `json:"values"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Values = make([]float64, len(s1.Values))
	for i := range s1.Values {
		s.Values[i] = float64(s1.Values[i])
	}
	return nil
}

type EnterpriseCrmEventbusProtoDoubleArrayFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "GET"
	//   "APPEND"
	//   "SIZE"
	//   "SUM"
	//   "AVG"
	//   "MAX"
	//   "MIN"
	//   "TO_SET"
	//   "APPEND_ALL"
	//   "TO_JSON"
	//   "SET"
	//   "REMOVE"
	//   "REMOVE_AT"
	//   "CONTAINS"
	//   "FOR_EACH"
	//   "FILTER"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoDoubleFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "TO_JSON"
	//   "TO_STRING"
	//   "ADD"
	//   "SUBTRACT"
	//   "MULTIPLY"
	//   "DIVIDE"
	//   "EXPONENT"
	//   "ROUND"
	//   "FLOOR"
	//   "CEIL"
	//   "GREATER_THAN"
	//   "LESS_THAN"
	//   "EQUALS"
	//   "GREATER_THAN_EQUALS"
	//   "LESS_THAN_EQUALS"
	//   "MOD"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoDoubleParameterArray struct {
	DoubleValues []float64 `json:"doubleValues,omitempty"`

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

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

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

func (s *EnterpriseCrmEventbusProtoDoubleParameterArray) UnmarshalJSON(data []byte) error {
	type NoMethod EnterpriseCrmEventbusProtoDoubleParameterArray
	var s1 struct {
		DoubleValues []gensupport.JSONFloat64 `json:"doubleValues"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DoubleValues = make([]float64, len(s1.DoubleValues))
	for i := range s1.DoubleValues {
		s.DoubleValues[i] = float64(s1.DoubleValues[i])
	}
	return nil
}

// EnterpriseCrmEventbusProtoErrorDetail: An error, warning, or
// information message associated with a workflow.
type EnterpriseCrmEventbusProtoErrorDetail struct {
	// ErrorCode: The associated error-code, which can be a common or
	// internal code.
	ErrorCode *CrmlogErrorCode `json:"errorCode,omitempty"`

	// ErrorMessage: The full text of the error message, including any
	// parameters that were thrown along with the exception.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// Severity: The severity of the error: ERROR|WARN|INFO.
	//
	// Possible values:
	//   "SEVERITY_UNSPECIFIED"
	//   "ERROR"
	//   "WARN"
	//   "INFO"
	Severity string `json:"severity,omitempty"`

	// TaskNumber: The task try-number, in which, the error occurred. If
	// zero, the error happened at the event level.
	TaskNumber int64 `json:"taskNumber,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoEventBusProperties: LINT.IfChange This
// message is used for storing key value pair properties for each Event
// / Task in the EventBus.
type EnterpriseCrmEventbusProtoEventBusProperties struct {
	// Properties: An unordered list of property entries.
	Properties []*EnterpriseCrmEventbusProtoPropertyEntry `json:"properties,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoEventExecutionDetails: Contains the details
// of the execution info of this event: this includes the tasks
// execution details plus the event execution statistics. Next available
// id: 10
type EnterpriseCrmEventbusProtoEventExecutionDetails struct {
	EventAttemptStats []*EnterpriseCrmEventbusProtoEventExecutionDetailsEventAttemptStats `json:"eventAttemptStats,omitempty"`

	EventExecutionSnapshot []*EnterpriseCrmEventbusProtoEventExecutionSnapshot `json:"eventExecutionSnapshot,omitempty"`

	// Possible values:
	//   "UNSPECIFIED"
	//   "ON_HOLD" - Event is received and waiting for the execution. This
	// happens when firing the event via "postToQueue" or "schedule".
	//   "IN_PROCESS" - Event is under processing.
	//   "SUCCEEDED" - Event execution successfully finished. There's no
	// more change after this state.
	//   "FAILED" - Event execution failed. There's no more change after
	// this state.
	//   "CANCELED" - Event execution canceled by user. There's no more
	// change after this state.
	//   "RETRY_ON_HOLD" - Event execution failed and waiting for retry.
	//   "SUSPENDED" - Event execution suspended and waiting for manual
	// intervention.
	EventExecutionState string `json:"eventExecutionState,omitempty"`

	// EventRetriesFromBeginningCount: Indicates the number of times the
	// execution has restarted from the beginning.
	EventRetriesFromBeginningCount int64 `json:"eventRetriesFromBeginningCount,omitempty"`

	// LogFilePath: The log file path (aka. cns address) for this event.
	LogFilePath string `json:"logFilePath,omitempty"`

	// NetworkAddress: The network address (aka. bns address) that indicates
	// where the event executor is running.
	NetworkAddress string `json:"networkAddress,omitempty"`

	// NextExecutionTime: Next scheduled execution time in case the
	// execution status was RETRY_ON_HOLD.
	NextExecutionTime int64 `json:"nextExecutionTime,omitempty,string"`

	// RyeLockUnheldCount: Used internally and shouldn't be exposed to
	// users. A counter for the cron job to record how many times this event
	// is in in_process state but don't have a lock consecutively/
	RyeLockUnheldCount int64 `json:"ryeLockUnheldCount,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoEventExecutionDetailsEventAttemptStats struct {
	// EndTime: The end time of the event execution for current attempt.
	EndTime int64 `json:"endTime,omitempty,string"`

	// StartTime: The start time of the event execution for current attempt.
	// This could be in the future if it's been scheduled.
	StartTime int64 `json:"startTime,omitempty,string"`

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

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

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

// EnterpriseCrmEventbusProtoEventExecutionSnapshot: Contains the
// snapshot of the event execution for a given checkpoint. Next
// available id: 13
type EnterpriseCrmEventbusProtoEventExecutionSnapshot struct {
	// CheckpointTaskNumber: Indicates "right after which checkpoint task's
	// execution" this snapshot is taken.
	CheckpointTaskNumber string `json:"checkpointTaskNumber,omitempty"`

	// ConditionResults: All of the computed conditions that been
	// calculated.
	ConditionResults []*EnterpriseCrmEventbusProtoConditionResult `json:"conditionResults,omitempty"`

	// DiffParams: The parameters in Event object that differs from last
	// snapshot.
	DiffParams *EnterpriseCrmEventbusProtoEventParameters `json:"diffParams,omitempty"`

	// EventExecutionInfoId: Points to the event execution info this
	// snapshot belongs to.
	EventExecutionInfoId string `json:"eventExecutionInfoId,omitempty"`

	// EventExecutionSnapshotId: Auto-generated. Used as primary key for
	// EventExecutionSnapshots table.
	EventExecutionSnapshotId string `json:"eventExecutionSnapshotId,omitempty"`

	EventExecutionSnapshotMetadata *EnterpriseCrmEventbusProtoEventExecutionSnapshotEventExecutionSnapshotMetadata `json:"eventExecutionSnapshotMetadata,omitempty"`

	// EventParams: The parameters in Event object.
	EventParams *EnterpriseCrmEventbusProtoEventParameters `json:"eventParams,omitempty"`

	// ExceedMaxSize: indicate whether snapshot exceeded maximum size before
	// clean up
	ExceedMaxSize bool `json:"exceedMaxSize,omitempty"`

	// SnapshotTime: Indicates when this snapshot is taken.
	SnapshotTime int64 `json:"snapshotTime,omitempty,string"`

	// TaskExecutionDetails: All of the task execution details at the given
	// point of time.
	TaskExecutionDetails []*EnterpriseCrmEventbusProtoTaskExecutionDetails `json:"taskExecutionDetails,omitempty"`

	// TaskName: The task name associated with this snapshot. Could be
	// empty.
	TaskName string `json:"taskName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoEventExecutionSnapshotEventExecutionSnapshotMetadata struct {
	// EventAttemptNum: the event attempt number this snapshot belongs to.
	EventAttemptNum int64 `json:"eventAttemptNum,omitempty"`

	// TaskAttemptNum: the task attempt number this snapshot belongs to.
	// Could be empty.
	TaskAttemptNum int64 `json:"taskAttemptNum,omitempty"`

	// TaskLabel: the task label associated with this snapshot. Could be
	// empty.
	TaskLabel string `json:"taskLabel,omitempty"`

	// TaskName: the task name associated with this snapshot. Could be
	// empty.
	TaskName string `json:"taskName,omitempty"`

	// TaskNumber: The task number associated with this snapshot. Could be
	// empty.
	TaskNumber string `json:"taskNumber,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoEventParameters: LINT.IfChange This message
// is used for processing and persisting (when applicable) key value
// pair parameters for each event in the event bus. Please see
type EnterpriseCrmEventbusProtoEventParameters struct {
	// Parameters: Parameters are a part of Event and can be used to
	// communicate between different tasks that are part of the same
	// integration execution.
	Parameters []*EnterpriseCrmEventbusProtoParameterEntry `json:"parameters,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoExecutionTraceInfo: Message that helps
// aggregate all sub-executions triggered by one execution and keeps
// track of child-parent relationships.
type EnterpriseCrmEventbusProtoExecutionTraceInfo struct {
	// ParentEventExecutionInfoId: Parent event execution info id that
	// triggers the current execution through SubWorkflowExecutorTask.
	ParentEventExecutionInfoId string `json:"parentEventExecutionInfoId,omitempty"`

	// TraceId: Used to aggregate ExecutionTraceInfo.
	TraceId string `json:"traceId,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoExternalTraffic: Represents external
// traffic type and id.
type EnterpriseCrmEventbusProtoExternalTraffic struct {
	// GcpProjectId: User’s GCP project id the traffic is referring to.
	GcpProjectId string `json:"gcpProjectId,omitempty"`

	// GcpProjectNumber: User’s GCP project number the traffic is
	// referring to.
	GcpProjectNumber string `json:"gcpProjectNumber,omitempty"`

	// Location: Location for the user's request.
	Location string `json:"location,omitempty"`

	// Source:
	// LINT.ThenChange(//depot/google3/enterprise/crm/eventbus/proto/product.
	// proto:product,
	// //depot/google3/java/com/google/enterprise/crm/integrationplatform/api
	// /utils/ConverterUtils.java:source_to_product)
	//
	// Possible values:
	//   "SOURCE_UNSPECIFIED"
	//   "APIGEE"
	//   "SECURITY"
	Source string `json:"source,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoFailurePolicy: Policy that defines the task
// retry logic and failure type. If no FailurePolicy is defined for a
// task, all its dependent tasks will not be executed (i.e, a
// `retry_strategy` of NONE will be applied).
type EnterpriseCrmEventbusProtoFailurePolicy struct {
	// IntervalInSeconds: Required if retry_strategy is FIXED_INTERVAL or
	// LINEAR/EXPONENTIAL_BACKOFF/RESTART_WORKFLOW_WITH_BACKOFF. Defines the
	// initial interval for backoff.
	IntervalInSeconds int64 `json:"intervalInSeconds,omitempty,string"`

	// MaxNumRetries: Required if retry_strategy is FIXED_INTERVAL or
	// LINEAR/EXPONENTIAL_BACKOFF/RESTART_WORKFLOW_WITH_BACKOFF. Defines the
	// number of times the task will be retried if failed.
	MaxNumRetries int64 `json:"maxNumRetries,omitempty"`

	// RetryStrategy: Defines what happens to the task upon failure.
	//
	// Possible values:
	//   "UNSPECIFIED"
	//   "IGNORE" - Ignores the failure of this task. The rest of the
	// workflow will be executed Assuming this task succeeded.
	//   "NONE" - Causes a permanent failure of the task. However, if the
	// last task(s) of event was successfully completed despite the failure
	// of this task, it has no impact on the workflow.
	//   "FATAL" - Causes a permanent failure of the event. It is different
	// from NONE because this will mark the event as FAILED by shutting down
	// the event execution.
	//   "FIXED_INTERVAL" - The task will be retried from the failed task
	// onwards after a fixed delay. A max-retry count is required to be
	// specified with this strategy. A jitter is added to each exponential
	// interval so that concurrently failing tasks of the same type do not
	// end up retrying after the exact same exponential interval.
	// Max_num_retries and interval_in_seconds must be specified.
	//   "LINEAR_BACKOFF" - The task will be retried from the failed task
	// onwards after a fixed delay that linearly increases with each retry
	// attempt. A jitter is added to each exponential interval so that
	// concurrently failing tasks of the same type do not end up retrying
	// after the exact same exponential interval. A max-retry count is
	// required to be specified with this strategy. Max_num_retries and
	// interval_in_seconds must be specified.
	//   "EXPONENTIAL_BACKOFF" - The task will be retried after an
	// exponentially increasing period of time with each failure. A jitter
	// is added to each exponential interval so that concurrently failing
	// tasks of the same type do not end up retrying after the exact same
	// exponential interval. A max-retry count is required to be specified
	// with this strategy. `max_num_retries` and `interval_in_seconds` must
	// be specified.
	//   "RESTART_WORKFLOW_WITH_BACKOFF" - The entire workflow will be
	// restarted with the initial parameters that were set when the event
	// was fired. A max-retry count is required to be specified with this
	// strategy. `max_num_retries` and `interval_in_seconds` must be
	// specified.
	RetryStrategy string `json:"retryStrategy,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoField: Information about the value and type
// of the field.
type EnterpriseCrmEventbusProtoField struct {
	// Cardinality: By default, if the cardinality is unspecified the field
	// is considered required while mapping.
	//
	// Possible values:
	//   "UNSPECIFIED" - For fields with unspecified cardinality.
	//   "OPTIONAL" - If field cardinality is set to optional, ignore errors
	// if input field value is null or the reference_key is not found.
	Cardinality string `json:"cardinality,omitempty"`

	// DefaultValue: This holds the default values for the fields. This
	// value is supplied by user so may or may not contain PII or SPII data.
	DefaultValue *EnterpriseCrmEventbusProtoParameterValueType `json:"defaultValue,omitempty"`

	// FieldType: Specifies the data type of the field.
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "STRING_VALUE"
	//   "INT_VALUE"
	//   "DOUBLE_VALUE"
	//   "BOOLEAN_VALUE"
	//   "PROTO_VALUE"
	//   "SERIALIZED_OBJECT_VALUE"
	//   "STRING_ARRAY"
	//   "INT_ARRAY"
	//   "DOUBLE_ARRAY"
	//   "PROTO_ARRAY"
	//   "PROTO_ENUM"
	//   "BOOLEAN_ARRAY"
	//   "PROTO_ENUM_ARRAY"
	//   "BYTES" - BYTES and BYTES_ARRAY data types are not allowed for
	// top-level params. They're only meant to support protobufs with BYTES
	// (sub)fields.
	//   "BYTES_ARRAY"
	//   "NON_SERIALIZABLE_OBJECT"
	//   "JSON_VALUE"
	FieldType string `json:"fieldType,omitempty"`

	// ProtoDefPath: Optional. The fully qualified proto name (e.g.
	// enterprise.crm.storage.Account). Required for output field of type
	// PROTO_VALUE or PROTO_ARRAY. For e.g., if input field_type is BYTES
	// and output field_type is PROTO_VALUE, then fully qualified proto type
	// url should be provided to parse the input bytes. If field_type is
	// *_ARRAY, then all the converted protos are of the same type.
	ProtoDefPath string `json:"protoDefPath,omitempty"`

	// ReferenceKey: This holds the reference key of the workflow or task
	// parameter. 1. Any workflow parameter, for e.g. $workflowParam1$. 2.
	// Any task input or output parameter, for e.g. $task1_param1$. 3. Any
	// workflow or task parameters with subfield references, for e.g.,
	// $task1_param1.employee.id$
	ReferenceKey string `json:"referenceKey,omitempty"`

	// TransformExpression: This is the transform expression to fetch the
	// input field value. for e.g. $param1$.CONCAT('test'). Keep points - 1.
	// Only input field can have a transform expression. 2. If a transform
	// expression is provided, reference_key will be ignored. 3. If no value
	// is returned after evaluation of transform expression, default_value
	// can be mapped if provided. 4. The field_type should be the type of
	// the final object returned after the transform expression is
	// evaluated. Scrubs the transform expression before logging as value
	// provided by user so may or may not contain PII or SPII data.
	TransformExpression *EnterpriseCrmEventbusProtoTransformExpression `json:"transformExpression,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoFieldMappingConfig: Field Mapping Config to
// map multiple output fields values from input fields values.
type EnterpriseCrmEventbusProtoFieldMappingConfig struct {
	MappedFields []*EnterpriseCrmEventbusProtoMappedField `json:"mappedFields,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoFunction struct {
	// FunctionType: The name of the function to perform.
	FunctionType *EnterpriseCrmEventbusProtoFunctionType `json:"functionType,omitempty"`

	// Parameters: List of parameters required for the transformation.
	Parameters []*EnterpriseCrmEventbusProtoTransformExpression `json:"parameters,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoFunctionType struct {
	// BaseFunction: LINT.IfChange
	BaseFunction *EnterpriseCrmEventbusProtoBaseFunction `json:"baseFunction,omitempty"`

	BooleanArrayFunction *EnterpriseCrmEventbusProtoBooleanArrayFunction `json:"booleanArrayFunction,omitempty"`

	BooleanFunction *EnterpriseCrmEventbusProtoBooleanFunction `json:"booleanFunction,omitempty"`

	DoubleArrayFunction *EnterpriseCrmEventbusProtoDoubleArrayFunction `json:"doubleArrayFunction,omitempty"`

	DoubleFunction *EnterpriseCrmEventbusProtoDoubleFunction `json:"doubleFunction,omitempty"`

	IntArrayFunction *EnterpriseCrmEventbusProtoIntArrayFunction `json:"intArrayFunction,omitempty"`

	IntFunction *EnterpriseCrmEventbusProtoIntFunction `json:"intFunction,omitempty"`

	// JsonFunction:
	// LINT.ThenChange(//depot/google3/alkali/apps/integrationplatform/client
	// /workflow_editor/utils/transform_function.ts)
	JsonFunction *EnterpriseCrmEventbusProtoJsonFunction `json:"jsonFunction,omitempty"`

	ProtoArrayFunction *EnterpriseCrmEventbusProtoProtoArrayFunction `json:"protoArrayFunction,omitempty"`

	ProtoFunction *EnterpriseCrmEventbusProtoProtoFunction `json:"protoFunction,omitempty"`

	StringArrayFunction *EnterpriseCrmEventbusProtoStringArrayFunction `json:"stringArrayFunction,omitempty"`

	StringFunction *EnterpriseCrmEventbusProtoStringFunction `json:"stringFunction,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoIntArray struct {
	Values googleapi.Int64s `json:"values,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoIntArrayFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "GET"
	//   "APPEND"
	//   "SIZE"
	//   "SUM"
	//   "AVG"
	//   "MAX"
	//   "MIN"
	//   "TO_SET"
	//   "APPEND_ALL"
	//   "TO_JSON"
	//   "SET"
	//   "REMOVE"
	//   "REMOVE_AT"
	//   "CONTAINS"
	//   "FOR_EACH"
	//   "FILTER"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoIntFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "ADD"
	//   "SUBTRACT"
	//   "MULTIPLY"
	//   "DIVIDE"
	//   "EXPONENT"
	//   "GREATER_THAN_EQUAL_TO"
	//   "GREATER_THAN"
	//   "LESS_THAN_EQUAL_TO"
	//   "LESS_THAN"
	//   "TO_DOUBLE"
	//   "TO_STRING"
	//   "EQUALS"
	//   "TO_JSON"
	//   "MOD"
	//   "EPOCH_TO_HUMAN_READABLE_TIME"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoIntParameterArray struct {
	IntValues googleapi.Int64s `json:"intValues,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoJsonFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "GET_PROPERTY"
	//   "GET_ELEMENT"
	//   "APPEND_ELEMENT"
	//   "SIZE"
	//   "SET_PROPERTY"
	//   "FLATTEN"
	//   "FLATTEN_ONCE"
	//   "MERGE"
	//   "TO_STRING"
	//   "TO_INT"
	//   "TO_DOUBLE"
	//   "TO_BOOLEAN"
	//   "TO_PROTO"
	//   "TO_STRING_ARRAY"
	//   "TO_INT_ARRAY"
	//   "TO_DOUBLE_ARRAY"
	//   "TO_PROTO_ARRAY"
	//   "TO_BOOLEAN_ARRAY"
	//   "REMOVE_PROPERTY"
	//   "RESOLVE_TEMPLATE"
	//   "EQUALS"
	//   "FOR_EACH"
	//   "FILTER_ELEMENTS" - next id: 24
	FunctionName string `json:"functionName,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoLogSettings: The LogSettings define the
// logging attributes for an event property. These attributes are used
// to map the property to the parameter in the log proto. Also used to
// define scrubbing/truncation behavior and PII information.
type EnterpriseCrmEventbusProtoLogSettings struct {
	// LogFieldName: The name of corresponding logging field of the event
	// property. If omitted, assumes the same name as the event property
	// key.
	LogFieldName string `json:"logFieldName,omitempty"`

	// SanitizeOptions: Contains the scrubbing options, such as whether to
	// scrub, obfuscate, etc.
	SanitizeOptions *EnterpriseCrmLoggingGwsSanitizeOptions `json:"sanitizeOptions,omitempty"`

	// Possible values:
	//   "SEED_PERIOD_UNSPECIFIED"
	//   "DAY" - Sanitized values remain constant for the day of the event.
	//   "WEEK" - Sanitized values remain constant for the week of the
	// event; may cross month boundaries.
	//   "MONTH" - Sanitized values remain constant for the month of the
	// event.
	SeedPeriod string `json:"seedPeriod,omitempty"`

	// Possible values:
	//   "SEED_SCOPE_UNSPECIFIED"
	//   "EVENT_NAME" - Hash computations include the event name.
	//   "TIME_PERIOD" - Hash computations include a time period.
	//   "PARAM_NAME" - Hash computations include the param name.
	SeedScope string `json:"seedScope,omitempty"`

	// ShorteningLimits: Contains the field limits for shortening, such as
	// max string length and max array length.
	ShorteningLimits *EnterpriseCrmLoggingGwsFieldLimits `json:"shorteningLimits,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoLoopMetadata struct {
	// CurrentIterationCount: Starting from 1, not 0.
	CurrentIterationCount int64 `json:"currentIterationCount,omitempty,string"`

	// CurrentIterationDetail: Needs to be set by the loop impl class before
	// each iteration. The abstract loop class will append the request and
	// response to it. Eg. The foreach Loop will clean up and set it as the
	// current iteration element at the start of each loop. The post request
	// and response will be appended to the value once they are available.
	CurrentIterationDetail string `json:"currentIterationDetail,omitempty"`

	// ErrorMsg: Add the error message when loops fail.
	ErrorMsg string `json:"errorMsg,omitempty"`

	// FailureLocation: Indicates where in the loop logic did it error out.
	//
	// Possible values:
	//   "UNKNOWN" - No error or Unknown.
	//   "SUBWORKFLOW" - Subworkflow failed while firing/running.
	//   "PARAM_OVERRIDING" - Param overrides failed.
	//   "PARAM_AGGREGATING" - Param aggregation failed.
	//   "SETTING_ITERATION_ELEMENT" - Setting for loop current element
	// failed.
	//   "GETTING_LIST_TO_ITERATE" - Getting the list to iterate.
	//   "CONDITION_EVALUATION" - Evaluating the while loop condition.
	//   "BUILDING_REQUEST" - Building the iteration request
	FailureLocation string `json:"failureLocation,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoMappedField: Mapped field is a pair of
// input field and output field.
type EnterpriseCrmEventbusProtoMappedField struct {
	// InputField: The input field being mapped from.
	InputField *EnterpriseCrmEventbusProtoField `json:"inputField,omitempty"`

	// OutputField: The output field being mapped to.
	OutputField *EnterpriseCrmEventbusProtoField `json:"outputField,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoNextTask: The task that is next in line to
// be executed, if the condition specified evaluated to true.
type EnterpriseCrmEventbusProtoNextTask struct {
	// CombinedConditions: Combined condition for this task to become an
	// eligible next task. Each of these combined_conditions are joined with
	// logical OR. DEPRECATED: use `condition`
	CombinedConditions []*EnterpriseCrmEventbusProtoCombinedCondition `json:"combinedConditions,omitempty"`

	// Condition: Standard filter expression for this task to become an
	// eligible next task.
	Condition string `json:"condition,omitempty"`

	// Description: User-provided description intended to give more business
	// context about the next task edge or condition.
	Description string `json:"description,omitempty"`

	// Label: User-provided label that is attached to this edge in the UI.
	Label string `json:"label,omitempty"`

	// TaskConfigId: ID of the next task.
	TaskConfigId string `json:"taskConfigId,omitempty"`

	// TaskNumber: Task number of the next task.
	TaskNumber string `json:"taskNumber,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoNextTeardownTask: The teardown task that is
// next in line to be executed. We support only sequential execution of
// teardown tasks (i.e. no branching).
type EnterpriseCrmEventbusProtoNextTeardownTask struct {
	// Name: Required. Name of the next teardown task.
	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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EnterpriseCrmEventbusProtoNextTeardownTask) MarshalJSON() ([]byte, error) {
	type NoMethod EnterpriseCrmEventbusProtoNextTeardownTask
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnterpriseCrmEventbusProtoNodeIdentifier: Represents a node
// identifier (type + id). Next highest id: 3
type EnterpriseCrmEventbusProtoNodeIdentifier struct {
	// ElementIdentifier: Configuration of the edge.
	ElementIdentifier string `json:"elementIdentifier,omitempty"`

	// ElementType: Destination node where the edge ends. It can only be a
	// task config.
	//
	// Possible values:
	//   "UNKNOWN_TYPE"
	//   "TASK_CONFIG"
	//   "TRIGGER_CONFIG"
	ElementType string `json:"elementType,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoNotification struct {
	BuganizerNotification *EnterpriseCrmEventbusProtoBuganizerNotification `json:"buganizerNotification,omitempty"`

	EmailAddress *EnterpriseCrmEventbusProtoAddress `json:"emailAddress,omitempty"`

	EscalatorQueue string `json:"escalatorQueue,omitempty"`

	PubsubTopic string `json:"pubsubTopic,omitempty"`

	// Request: If the out-of-the-box email/pubsub notifications are not
	// suitable and custom logic is required, fire a workflow containing all
	// info needed to notify users to resume execution.
	Request *EnterpriseCrmEventbusProtoCustomSuspensionRequest `json:"request,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoParamSpecEntryConfig struct {
	// DescriptivePhrase: A short phrase to describe what this parameter
	// contains.
	DescriptivePhrase string `json:"descriptivePhrase,omitempty"`

	// HelpText: Detailed help text for this parameter containing
	// information not provided elsewhere. For example, instructions on how
	// to migrate from a deprecated parameter.
	HelpText string `json:"helpText,omitempty"`

	// HideDefaultValue: Whether the default value is hidden in the UI.
	HideDefaultValue bool `json:"hideDefaultValue,omitempty"`

	// Possible values:
	//   "DEFAULT" - A single-line input for strings, a numeric input box
	// for numbers, or a checkbox for booleans.
	//   "STRING_MULTI_LINE" - A multi-line input box for longer
	// strings/string templates.
	//   "NUMBER_SLIDER" - A slider to select a numerical value. The default
	// range is [0, 100].
	//   "BOOLEAN_TOGGLE" - A toggle button for boolean parameters.
	InputDisplayOption string `json:"inputDisplayOption,omitempty"`

	// IsHidden: Whether this field is hidden in the UI.
	IsHidden bool `json:"isHidden,omitempty"`

	// Label: A user-friendly label for the parameter.
	Label string `json:"label,omitempty"`

	// Possible values:
	//   "DEFAULT_NOT_PARAMETER_NAME" - This field is not a parameter name.
	//   "IS_PARAMETER_NAME" - If this field is a string and this option is
	// selected, the field will be interpreted as a parameter name. Users
	// will be able to choose a variable using the autocomplete, but the
	// name will be stored as a literal string.
	//   "KEY_IS_PARAMETER_NAME" - If this field is a ParameterMap and this
	// option is selected, the map's keys will be interpreted as parameter
	// names. Ignored if this field is not a ParameterMap.
	//   "VALUE_IS_PARAMETER_NAME" - If this field is a ParameterMap and
	// this option is selected, the map's values will be interpreted as
	// parameter names. Ignored if this field is not a ParameterMap.
	ParameterNameOption string `json:"parameterNameOption,omitempty"`

	// SubSectionLabel: A user-friendly label for subSection under which the
	// parameter will be displayed.
	SubSectionLabel string `json:"subSectionLabel,omitempty"`

	// UiPlaceholderText: Placeholder text which will appear in the UI input
	// form for this parameter.
	UiPlaceholderText string `json:"uiPlaceholderText,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoParamSpecEntryProtoDefinition struct {
	// FullName: The fully-qualified proto name. This message, for example,
	// would be
	// "enterprise.crm.eventbus.proto.ParamSpecEntry.ProtoDefinition".
	FullName string `json:"fullName,omitempty"`

	// Path: Path to the proto file that contains the message type's
	// definition.
	Path string `json:"path,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoParamSpecEntryValidationRule struct {
	DoubleRange *EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleDoubleRange `json:"doubleRange,omitempty"`

	IntRange *EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleIntRange `json:"intRange,omitempty"`

	StringRegex *EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleStringRegex `json:"stringRegex,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleDoubleRange:
// Range used to validate doubles and floats.
type EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleDoubleRange struct {
	// Max: The inclusive maximum of the acceptable range.
	Max float64 `json:"max,omitempty"`

	// Min: The inclusive minimum of the acceptable range.
	Min float64 `json:"min,omitempty"`

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

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

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

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

// EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleIntRange: Range
// used to validate longs and ints.
type EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleIntRange struct {
	// Max: The inclusive maximum of the acceptable range.
	Max int64 `json:"max,omitempty,string"`

	// Min: The inclusive minimum of the acceptable range.
	Min int64 `json:"min,omitempty,string"`

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

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

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

// EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleStringRegex:
// Rule used to validate strings.
type EnterpriseCrmEventbusProtoParamSpecEntryValidationRuleStringRegex struct {
	// Exclusive: Whether the regex matcher is applied exclusively (if true,
	// matching values will be rejected).
	Exclusive bool `json:"exclusive,omitempty"`

	// Regex: The regex applied to the input value(s).
	Regex string `json:"regex,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoParameterEntry: Key-value pair of EventBus
// parameters.
type EnterpriseCrmEventbusProtoParameterEntry struct {
	// Key: Key is used to retrieve the corresponding parameter value. This
	// should be unique for a given fired event. These parameters must be
	// predefined in the integration definition.
	Key string `json:"key,omitempty"`

	// Value: Values for the defined keys. Each value can either be string,
	// int, double or any proto message.
	Value *EnterpriseCrmEventbusProtoParameterValueType `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EnterpriseCrmEventbusProtoParameterEntry) MarshalJSON() ([]byte, error) {
	type NoMethod EnterpriseCrmEventbusProtoParameterEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnterpriseCrmEventbusProtoParameterMap: A generic multi-map that
// holds key value pairs. They keys and values can be of any type,
// unless specified.
type EnterpriseCrmEventbusProtoParameterMap struct {
	Entries []*EnterpriseCrmEventbusProtoParameterMapEntry `json:"entries,omitempty"`

	// KeyType: Option to specify key value type for all entries of the map.
	// If provided then field types for all entries must conform to this.
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "STRING_VALUE"
	//   "INT_VALUE"
	//   "DOUBLE_VALUE"
	//   "BOOLEAN_VALUE"
	//   "PROTO_VALUE"
	//   "SERIALIZED_OBJECT_VALUE"
	//   "STRING_ARRAY"
	//   "INT_ARRAY"
	//   "DOUBLE_ARRAY"
	//   "PROTO_ARRAY"
	//   "PROTO_ENUM"
	//   "BOOLEAN_ARRAY"
	//   "PROTO_ENUM_ARRAY"
	//   "BYTES" - BYTES and BYTES_ARRAY data types are not allowed for
	// top-level params. They're only meant to support protobufs with BYTES
	// (sub)fields.
	//   "BYTES_ARRAY"
	//   "NON_SERIALIZABLE_OBJECT"
	//   "JSON_VALUE"
	KeyType string `json:"keyType,omitempty"`

	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "STRING_VALUE"
	//   "INT_VALUE"
	//   "DOUBLE_VALUE"
	//   "BOOLEAN_VALUE"
	//   "PROTO_VALUE"
	//   "SERIALIZED_OBJECT_VALUE"
	//   "STRING_ARRAY"
	//   "INT_ARRAY"
	//   "DOUBLE_ARRAY"
	//   "PROTO_ARRAY"
	//   "PROTO_ENUM"
	//   "BOOLEAN_ARRAY"
	//   "PROTO_ENUM_ARRAY"
	//   "BYTES" - BYTES and BYTES_ARRAY data types are not allowed for
	// top-level params. They're only meant to support protobufs with BYTES
	// (sub)fields.
	//   "BYTES_ARRAY"
	//   "NON_SERIALIZABLE_OBJECT"
	//   "JSON_VALUE"
	ValueType string `json:"valueType,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoParameterMapEntry: Entry is a pair of key
// and value.
type EnterpriseCrmEventbusProtoParameterMapEntry struct {
	Key *EnterpriseCrmEventbusProtoParameterMapField `json:"key,omitempty"`

	Value *EnterpriseCrmEventbusProtoParameterMapField `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EnterpriseCrmEventbusProtoParameterMapEntry) MarshalJSON() ([]byte, error) {
	type NoMethod EnterpriseCrmEventbusProtoParameterMapEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnterpriseCrmEventbusProtoParameterMapField: Field represents either
// the key or value in an entry.
type EnterpriseCrmEventbusProtoParameterMapField struct {
	// LiteralValue: Passing a literal value.
	LiteralValue *EnterpriseCrmEventbusProtoParameterValueType `json:"literalValue,omitempty"`

	// ReferenceKey: Referencing one of the WF variables.
	ReferenceKey string `json:"referenceKey,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoParameterValueType: LINT.IfChange To
// support various types of parameter values. Next available id: 14
type EnterpriseCrmEventbusProtoParameterValueType struct {
	BooleanArray *EnterpriseCrmEventbusProtoBooleanParameterArray `json:"booleanArray,omitempty"`

	BooleanValue bool `json:"booleanValue,omitempty"`

	DoubleArray *EnterpriseCrmEventbusProtoDoubleParameterArray `json:"doubleArray,omitempty"`

	DoubleValue float64 `json:"doubleValue,omitempty"`

	IntArray *EnterpriseCrmEventbusProtoIntParameterArray `json:"intArray,omitempty"`

	IntValue int64 `json:"intValue,omitempty,string"`

	ProtoArray *EnterpriseCrmEventbusProtoProtoParameterArray `json:"protoArray,omitempty"`

	ProtoValue googleapi.RawMessage `json:"protoValue,omitempty"`

	SerializedObjectValue *EnterpriseCrmEventbusProtoSerializedObjectParameter `json:"serializedObjectValue,omitempty"`

	StringArray *EnterpriseCrmEventbusProtoStringParameterArray `json:"stringArray,omitempty"`

	StringValue string `json:"stringValue,omitempty"`

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

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

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

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

// EnterpriseCrmEventbusProtoPropertyEntry: Key-value pair of EventBus
// property.
type EnterpriseCrmEventbusProtoPropertyEntry struct {
	// Key: Key is used to retrieve the corresponding property value. This
	// should be unique for a given fired event. The Tasks should be aware
	// of the keys used while firing the events for them to be able to
	// retrieve the values.
	Key string `json:"key,omitempty"`

	// Value: Values for the defined keys. Each value can either be string,
	// int, double or any proto message.
	Value *EnterpriseCrmEventbusProtoValueType `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EnterpriseCrmEventbusProtoPropertyEntry) MarshalJSON() ([]byte, error) {
	type NoMethod EnterpriseCrmEventbusProtoPropertyEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type EnterpriseCrmEventbusProtoProtoArrayFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "GET"
	//   "APPEND"
	//   "SIZE"
	//   "TO_SET"
	//   "APPEND_ALL"
	//   "TO_JSON"
	//   "SET"
	//   "REMOVE"
	//   "REMOVE_AT"
	//   "CONTAINS"
	//   "FOR_EACH"
	//   "FILTER"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoProtoFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "GET_STRING_SUBFIELD"
	//   "GET_INT_SUBFIELD"
	//   "GET_DOUBLE_SUBFIELD"
	//   "GET_BOOLEAN_SUBFIELD"
	//   "GET_STRING_ARRAY_SUBFIELD"
	//   "GET_INT_ARRAY_SUBFIELD"
	//   "GET_DOUBLE_ARRAY_SUBFIELD"
	//   "GET_BOOLEAN_ARRAY_SUBFIELD"
	//   "GET_PROTO_ARRAY_SUBFIELD"
	//   "GET_PROTO_SUBFIELD"
	//   "TO_JSON"
	//   "GET_BYTES_SUBFIELD_AS_UTF_8_STRING"
	//   "GET_BYTES_SUBFIELD_AS_PROTO"
	//   "EQUALS"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoProtoParameterArray struct {
	ProtoValues []googleapi.RawMessage `json:"protoValues,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoScatterResponse struct {
	// ErrorMsg: The error message of the failure if applicable.
	ErrorMsg string `json:"errorMsg,omitempty"`

	// ExecutionIds: The execution ids of each Subworkflow fired by this
	// scatter.
	ExecutionIds []string `json:"executionIds,omitempty"`

	// IsSuccessful: If execution is sync, this is true if the execution
	// passed and false if it failed. If the execution is async, this is
	// true if the WF was fired off successfully, and false if it failed to
	// execute. The success or failure of the subworkflows executed are not
	// captured.
	IsSuccessful bool `json:"isSuccessful,omitempty"`

	// ResponseParams: A list of all the response parameters in the
	// aggregtorMap stored with the remapped key.
	ResponseParams []*EnterpriseCrmEventbusProtoParameterEntry `json:"responseParams,omitempty"`

	// ScatterElement: The element that was scattered for this execution.
	ScatterElement *EnterpriseCrmEventbusProtoParameterValueType `json:"scatterElement,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoSerializedObjectParameter struct {
	ObjectValue string `json:"objectValue,omitempty"`

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

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

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

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

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

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

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

type EnterpriseCrmEventbusProtoStringArrayFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "GET"
	//   "APPEND"
	//   "SIZE"
	//   "TO_SET"
	//   "APPEND_ALL"
	//   "TO_JSON"
	//   "SET"
	//   "REMOVE"
	//   "REMOVE_AT"
	//   "CONTAINS"
	//   "FOR_EACH"
	//   "FILTER"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoStringFunction struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "CONCAT"
	//   "TO_UPPERCASE"
	//   "TO_LOWERCASE"
	//   "CONTAINS"
	//   "SPLIT"
	//   "LENGTH"
	//   "EQUALS"
	//   "TO_INT"
	//   "TO_DOUBLE"
	//   "TO_BOOLEAN"
	//   "TO_BASE_64"
	//   "TO_JSON"
	//   "EQUALS_IGNORE_CASE"
	//   "REPLACE_ALL"
	//   "SUBSTRING"
	//   "RESOLVE_TEMPLATE"
	//   "DECODE_BASE64_STRING"
	FunctionName string `json:"functionName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoStringParameterArray struct {
	StringValues []string `json:"stringValues,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoSuccessPolicy: Policy that dictates the
// behavior for the task after it completes successfully.
type EnterpriseCrmEventbusProtoSuccessPolicy struct {
	// FinalState: State to which the execution snapshot status will be set
	// if the task succeeds.
	//
	// Possible values:
	//   "UNSPECIFIED"
	//   "SUCCEEDED" - The default behavior, where successful tasks will be
	// marked as SUCCEEDED.
	//   "SUSPENDED" - Sets the state to SUSPENDED after executing. This is
	// required for SuspensionTask; event execution will continue once the
	// user calls ResolveSuspensions with the event_execution_info_id and
	// the task number.
	FinalState string `json:"finalState,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoSuspensionAuthPermissions: LINT.IfChange
type EnterpriseCrmEventbusProtoSuspensionAuthPermissions struct {
	// GaiaIdentity: Represents a Gaia identity for a person or service
	// account.
	GaiaIdentity *EnterpriseCrmEventbusProtoSuspensionAuthPermissionsGaiaIdentity `json:"gaiaIdentity,omitempty"`

	GoogleGroup *EnterpriseCrmEventbusProtoSuspensionAuthPermissionsGaiaIdentity `json:"googleGroup,omitempty"`

	LoasRole string `json:"loasRole,omitempty"`

	MdbGroup string `json:"mdbGroup,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoSuspensionAuthPermissionsGaiaIdentity struct {
	EmailAddress string `json:"emailAddress,omitempty"`

	GaiaId int64 `json:"gaiaId,omitempty,string"`

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

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

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

type EnterpriseCrmEventbusProtoSuspensionConfig struct {
	// CustomMessage: Optional information to provide recipients of the
	// suspension in addition to the resolution URL, typically containing
	// relevant parameter values from the originating workflow.
	CustomMessage string `json:"customMessage,omitempty"`

	Notifications []*EnterpriseCrmEventbusProtoNotification `json:"notifications,omitempty"`

	// SuspensionExpiration: Indicates the next steps when no external
	// actions happen on the suspension.
	SuspensionExpiration *EnterpriseCrmEventbusProtoSuspensionExpiration `json:"suspensionExpiration,omitempty"`

	// WhoMayResolve: Identities able to resolve this suspension.
	WhoMayResolve []*EnterpriseCrmEventbusProtoSuspensionAuthPermissions `json:"whoMayResolve,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoSuspensionExpiration struct {
	// ExpireAfterMs: Milliseconds after which the suspension expires, if no
	// action taken.
	ExpireAfterMs int64 `json:"expireAfterMs,omitempty"`

	// LiftWhenExpired: Whether the suspension will be REJECTED or LIFTED
	// upon expiration. REJECTED is the default behavior.
	LiftWhenExpired bool `json:"liftWhenExpired,omitempty"`

	// RemindAfterMs: Milliseconds after which the previous suspension
	// action reminder, if any, is sent using the selected notification
	// option, for a suspension which is still PENDING_UNSPECIFIED.
	RemindAfterMs int64 `json:"remindAfterMs,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoSuspensionResolutionInfo struct {
	Audit *EnterpriseCrmEventbusProtoSuspensionResolutionInfoAudit `json:"audit,omitempty"`

	// ClientId: The event data user sends as request.
	ClientId string `json:"clientId,omitempty"`

	// CloudKmsConfig: KMS info, used by cmek/gmek integration
	CloudKmsConfig *EnterpriseCrmEventbusProtoCloudKmsConfig `json:"cloudKmsConfig,omitempty"`

	// CreatedTimestamp: Auto-generated.
	CreatedTimestamp string `json:"createdTimestamp,omitempty"`

	// EncryptedSuspensionResolutionInfo: Encrypted SuspensionResolutionInfo
	EncryptedSuspensionResolutionInfo string `json:"encryptedSuspensionResolutionInfo,omitempty"`

	// EventExecutionInfoId: Required. ID of the associated execution.
	EventExecutionInfoId string `json:"eventExecutionInfoId,omitempty"`

	// ExternalTraffic: The origin of the suspension for periodic
	// notifications.
	ExternalTraffic *EnterpriseCrmEventbusProtoExternalTraffic `json:"externalTraffic,omitempty"`

	// LastModifiedTimestamp: Auto-generated.
	LastModifiedTimestamp string `json:"lastModifiedTimestamp,omitempty"`

	// Product: Which Google product the suspension belongs to. If not set,
	// the suspension belongs to Integration Platform by default.
	//
	// Possible values:
	//   "UNSPECIFIED_PRODUCT"
	//   "IP"
	//   "APIGEE"
	//   "SECURITY"
	Product string `json:"product,omitempty"`

	// Possible values:
	//   "PENDING_UNSPECIFIED"
	//   "REJECTED"
	//   "LIFTED"
	//   "CANCELED"
	Status string `json:"status,omitempty"`

	SuspensionConfig *EnterpriseCrmEventbusProtoSuspensionConfig `json:"suspensionConfig,omitempty"`

	// SuspensionId: Primary key for the SuspensionResolutionInfoTable.
	SuspensionId string `json:"suspensionId,omitempty"`

	// TaskNumber: Required. Task number of the associated SuspensionTask.
	TaskNumber string `json:"taskNumber,omitempty"`

	// WorkflowName: Required. The name of the originating workflow.
	WorkflowName string `json:"workflowName,omitempty"`

	// WrappedDek: Wrapped dek
	WrappedDek string `json:"wrappedDek,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoSuspensionResolutionInfoAudit struct {
	ResolvedBy string `json:"resolvedBy,omitempty"`

	ResolvedByCpi string `json:"resolvedByCpi,omitempty"`

	Timestamp string `json:"timestamp,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoTaskAlertConfig: Message to be used to
// configure alerting in the {@code TaskConfig} protos for tasks in an
// event.
type EnterpriseCrmEventbusProtoTaskAlertConfig struct {
	// AggregationPeriod: The period over which the metric value should be
	// aggregated and evaluated. Format is , where integer should be a
	// positive integer and unit should be one of (s,m,h,d,w) meaning
	// (second, minute, hour, day, week).
	AggregationPeriod string `json:"aggregationPeriod,omitempty"`

	// AlertDisabled: Set to false by default. When set to true, the metrics
	// are not aggregated or pushed to Monarch for this workflow alert.
	AlertDisabled bool `json:"alertDisabled,omitempty"`

	// AlertName: A name to identify this alert. This will be displayed in
	// the alert subject. If set, this name should be unique in within the
	// scope of the containing workflow.
	AlertName string `json:"alertName,omitempty"`

	// ClientId: Client associated with this alert configuration. Must be a
	// client enabled in one of the containing workflow's triggers.
	ClientId string `json:"clientId,omitempty"`

	// DurationThresholdMs: Should be specified only for
	// TASK_AVERAGE_DURATION and TASK_PERCENTILE_DURATION metrics. This
	// member should be used to specify what duration value the metrics
	// should exceed for the alert to trigger.
	DurationThresholdMs int64 `json:"durationThresholdMs,omitempty,string"`

	ErrorEnumList *EnterpriseCrmEventbusProtoBaseAlertConfigErrorEnumList `json:"errorEnumList,omitempty"`

	// Possible values:
	//   "METRIC_TYPE_UNSPECIFIED" - The default value. Metric type should
	// always be set to one of the other non-default values, otherwise it
	// will result in an INVALID_ARGUMENT error.
	//   "TASK_ERROR_RATE" - Specifies alerting on the rate of errors
	// (potentially for a specific set of enum values) for the enclosing
	// TaskConfig.
	//   "TASK_WARNING_RATE" - Specifies alerting on the rate of warnings
	// (potentially for a specific set of enum values) for the enclosing
	// TaskConfig. Warnings use the same enum values as errors.
	//   "TASK_RATE" - Specifies alerting on the number of instances for the
	// enclosing TaskConfig executed in the given aggregation_period.
	//   "TASK_AVERAGE_DURATION" - Specifies alerting on the average
	// duration of execution for the enclosing task.
	//   "TASK_PERCENTILE_DURATION" - Specifies alerting on the duration of
	// a particular percentile of task executions. E.g. If 10% or more of
	// the task executions have durations above 5 seconds, alert.
	MetricType string `json:"metricType,omitempty"`

	// NumAggregationPeriods: For how many contiguous aggregation periods
	// should the expected min or max be violated for the alert to be fired.
	NumAggregationPeriods int64 `json:"numAggregationPeriods,omitempty"`

	// OnlyFinalAttempt: Only count final task attempts, not retries.
	OnlyFinalAttempt bool `json:"onlyFinalAttempt,omitempty"`

	// PlaybookUrl: Link to a playbook for resolving the issue that
	// triggered this alert.
	PlaybookUrl string `json:"playbookUrl,omitempty"`

	// ThresholdType: The threshold type for which this alert is being
	// configured. If value falls below expected_min or exceeds
	// expected_max, an alert will be fired.
	//
	// Possible values:
	//   "UNSPECIFIED_THRESHOLD_TYPE"
	//   "EXPECTED_MIN" - Note that this field will only trigger alerts if
	// the workflow specifying it runs at least once in 24 hours (which is
	// our in-memory retention period for monarch streams). Also note that
	// `aggregation_period` for this alert configuration must be less than
	// 24 hours.
	//   "EXPECTED_MAX"
	ThresholdType string `json:"thresholdType,omitempty"`

	// ThresholdValue: The metric value, above or below which the alert
	// should be triggered.
	ThresholdValue *EnterpriseCrmEventbusProtoBaseAlertConfigThresholdValue `json:"thresholdValue,omitempty"`

	WarningEnumList *EnterpriseCrmEventbusProtoBaseAlertConfigErrorEnumList `json:"warningEnumList,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoTaskExecutionDetails: Contains the details
// of the execution of this task. Next available id: 11
type EnterpriseCrmEventbusProtoTaskExecutionDetails struct {
	TaskAttemptStats []*EnterpriseCrmEventbusProtoTaskExecutionDetailsTaskAttemptStats `json:"taskAttemptStats,omitempty"`

	// Possible values:
	//   "UNSPECIFIED"
	//   "PENDING_EXECUTION" - Task is waiting for its precondition tasks to
	// finish to start the execution.
	//   "IN_PROCESS" - Task is under processing.
	//   "SUCCEED" - Task execution successfully finished. There's no more
	// change after this state.
	//   "FAILED" - Task execution failed. There's no more change after this
	// state.
	//   "FATAL" - Task execution failed and cause the whole event execution
	// to fail immediately. There's no more change after this state.
	//   "RETRY_ON_HOLD" - Task execution failed and waiting for retry.
	//   "SKIPPED" - Task execution skipped. This happens when its
	// precondition wasn't met, or the event execution been canceled before
	// reach to the task. There's no more changes after this state.
	//   "CANCELED" - Task execution canceled when in progress. This happens
	// when event execution been canceled or any other task fall in fatal
	// state.
	//   "PENDING_ROLLBACK" - Task is waiting for its dependency tasks'
	// rollback to finish to start its rollback.
	//   "ROLLBACK_IN_PROCESS" - Task is rolling back.
	//   "ROLLEDBACK" - Task is rolled back. This is the state we will set
	// regardless of rollback succeeding or failing.
	//   "SUSPENDED" - Task is a SuspensionTask which has executed once,
	// creating a pending suspension.
	TaskExecutionState string `json:"taskExecutionState,omitempty"`

	// TaskNumber: Pointer to the task config it used for execution.
	TaskNumber string `json:"taskNumber,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoTaskExecutionDetailsTaskAttemptStats struct {
	// EndTime: The end time of the task execution for current attempt.
	EndTime int64 `json:"endTime,omitempty,string"`

	// StartTime: The start time of the task execution for current attempt.
	// This could be in the future if it's been scheduled.
	StartTime int64 `json:"startTime,omitempty,string"`

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

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

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

// EnterpriseCrmEventbusProtoTaskMetadata: TaskMetadata are attributes
// that are associated to every common Task we have.
type EnterpriseCrmEventbusProtoTaskMetadata struct {
	// ActiveTaskName: The new task name to replace the current task if it
	// is deprecated. Otherwise, it is the same as the current task name.
	ActiveTaskName string `json:"activeTaskName,omitempty"`

	Admins []*EnterpriseCrmEventbusProtoTaskMetadataAdmin `json:"admins,omitempty"`

	// Possible values:
	//   "UNSPECIFIED_CATEGORY"
	//   "CUSTOM"
	//   "FLOW_CONTROL"
	//   "DATA_MANIPULATION"
	//   "SCRIPTING"
	//   "CONNECTOR"
	//   "HIDDEN" - Internal IP tasks that should not be available in the
	// UI.
	//   "CLOUD_SYSTEMS" - Tasks that are relevant to cloud systems teams
	// and typically
	//   "CUSTOM_TASK_TEMPLATE" - include connecting to Vector salesforce,
	// CRM Hub Spanner etc. Task entities that derive from a custom task
	// template.
	//   "TASK_RECOMMENDATIONS" - Category to show task recommendations
	Category string `json:"category,omitempty"`

	// CodeSearchLink: The Code Search link to the Task Java file.
	CodeSearchLink string `json:"codeSearchLink,omitempty"`

	// DefaultJsonValidationOption: Controls whether JSON workflow
	// parameters are validated against provided schemas before and/or after
	// this task's execution.
	//
	// Possible values:
	//   "UNSPECIFIED_JSON_VALIDATION_OPTION" - As per the default behavior,
	// no validation will be run. Will not override any option set in a
	// Task.
	//   "SKIP" - Do not run any validation against JSON schemas.
	//   "PRE_EXECUTION" - Validate all potential input JSON parameters
	// against schemas specified in WorkflowParameters.
	//   "POST_EXECUTION" - Validate all potential output JSON parameters
	// against schemas specified in WorkflowParameters.
	//   "PRE_POST_EXECUTION" - Perform both PRE_EXECUTION and
	// POST_EXECUTION validations.
	DefaultJsonValidationOption string `json:"defaultJsonValidationOption,omitempty"`

	// DefaultSpec: Contains the initial configuration of the task with
	// default values set. For now, The string should be compatible to an
	// ASCII-proto format.
	DefaultSpec string `json:"defaultSpec,omitempty"`

	// Description: In a few sentences, describe the purpose and usage of
	// the task.
	Description string `json:"description,omitempty"`

	// DescriptiveName: The string name to show on the task list on the
	// Workflow editor screen. This should be a very short, one to two words
	// name for the task. (e.g. "Send Mail")
	DescriptiveName string `json:"descriptiveName,omitempty"`

	// DocMarkdown: Snippet of markdown documentation to embed in the RHP
	// for this task.
	DocMarkdown string `json:"docMarkdown,omitempty"`

	// Possible values:
	//   "UNSPECIFIED_EXTERNAL_CATEGORY"
	//   "CORE"
	//   "CONNECTORS"
	//   "EXTERNAL_HTTP" - HTTP tasks, e.g. rest api call task
	//   "EXTERNAL_INTEGRATION_SERVICES" - Integration services, e.g.
	// connector task
	//   "EXTERNAL_CUSTOMER_ACTIONS" - Customer ations, e.g. email task
	//   "EXTERNAL_FLOW_CONTROL" - Flow control, e.g. while loop task
	//   "EXTERNAL_WORKSPACE" - Workspace tasks, e.g. list drive task
	//   "EXTERNAL_SECURITY" - Security, e.g. kms related tasks
	//   "EXTERNAL_DATABASES" - Database operation tasks, e.g. read
	// firestore info tasks
	//   "EXTERNAL_ANALYTICS" - Analytics tasks, e.g. dataflow creattion
	// tasks
	//   "EXTERNAL_BYOC" - BYOC tasks
	//   "EXTERNAL_BYOT" - BYOT tasks
	//   "EXTERNAL_ARTIFICIAL_INTELIGENCE" - AI related tasks.
	//   "EXTERNAL_DATA_MANIPULATION" - Data manipulation related tasks,
	// e.g. data mapping task
	ExternalCategory string `json:"externalCategory,omitempty"`

	// ExternalCategorySequence: Sequence with which the task in specific
	// category to be displayed in task discovery panel for external users.
	ExternalCategorySequence int64 `json:"externalCategorySequence,omitempty"`

	// ExternalDocHtml: External-facing documention embedded in the RHP for
	// this task.
	ExternalDocHtml string `json:"externalDocHtml,omitempty"`

	// ExternalDocLink: Doc link for external-facing documentation (separate
	// from g3doc).
	ExternalDocLink string `json:"externalDocLink,omitempty"`

	// ExternalDocMarkdown: DEPRECATED: Use external_doc_html.
	ExternalDocMarkdown string `json:"externalDocMarkdown,omitempty"`

	// G3DocLink: URL to the associated G3 Doc for the task if available
	G3DocLink string `json:"g3DocLink,omitempty"`

	// IconLink: URL to gstatic image icon for this task. This icon shows up
	// on the task list panel along with the task name in the Workflow
	// Editor screen. Use the 24p, 2x, gray color icon image format.
	IconLink string `json:"iconLink,omitempty"`

	// IsDeprecated: The deprecation status of the current task. Default
	// value is false;
	IsDeprecated bool `json:"isDeprecated,omitempty"`

	// Name: The actual class name or the annotated name of the task. Task
	// Author should initialize this field with value from the getName()
	// method of the Task class.
	Name string `json:"name,omitempty"`

	// StandaloneExternalDocHtml: External-facing documention for standalone
	// IP in pantheon embedded in the RHP for this task. Non null only if
	// different from external_doc_html
	StandaloneExternalDocHtml string `json:"standaloneExternalDocHtml,omitempty"`

	// Status: Allows author to indicate if the task is ready to use or not.
	// If not set, then it will default to INACTIVE.
	//
	// Possible values:
	//   "UNSPECIFIED_STATUS" - Default value. Actual Task Status should
	// always be set to either INACTIVE or ACTIVE. If none is specified at
	// runtime, it will be set to INACTIVE.
	//   "DEFAULT_INACTIVE" - Still in-progress or incomplete, and not
	// intended for use.
	//   "ACTIVE" - Available for use.
	Status string `json:"status,omitempty"`

	// Possible values:
	//   "UNSPECIFIED_SYSTEM"
	//   "GENERIC"
	//   "BUGANIZER"
	//   "SALESFORCE"
	//   "CLOUD_SQL"
	//   "PLX"
	//   "SHEETS"
	//   "GOOGLE_GROUPS"
	//   "EMAIL"
	//   "SPANNER"
	//   "DATA_BRIDGE"
	System string `json:"system,omitempty"`

	// Tags: A set of tags that pertain to a particular task. This can be
	// used to improve the searchability of tasks with several names ("REST
	// Caller" vs. "Call REST Endpoint") or to help users find tasks based
	// on related words.
	Tags []string `json:"tags,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoTaskMetadataAdmin: Admins are owners of a
// Task, and have all permissions on a particular task identified by the
// task name. By default, Eventbus periodically scans all task metadata
// and syncs (adds) any new admins defined here to Zanzibar.
type EnterpriseCrmEventbusProtoTaskMetadataAdmin struct {
	GoogleGroupEmail string `json:"googleGroupEmail,omitempty"`

	UserEmail string `json:"userEmail,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoTaskUiConfig: Task authors would use this
// type to configure the UI for a particular task by specifying what UI
// config modules should be included to compose the UI. Learn more about
// config module framework:
type EnterpriseCrmEventbusProtoTaskUiConfig struct {
	// TaskUiModuleConfigs: Configurations of included config modules.
	TaskUiModuleConfigs []*EnterpriseCrmEventbusProtoTaskUiModuleConfig `json:"taskUiModuleConfigs,omitempty"`

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

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

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

// EnterpriseCrmEventbusProtoTaskUiModuleConfig: Task author would use
// this type to configure a config module.
type EnterpriseCrmEventbusProtoTaskUiModuleConfig struct {
	// ModuleId: ID of the config module.
	//
	// Possible values:
	//   "UNSPECIFIED_TASK_MODULE" - Default
	//   "LABEL" - Supports editing label of a task config.
	//   "ERROR_HANDLING" - Supports editing error handling settings such as
	// retry strategy.
	//   "TASK_PARAM_TABLE" - Supports adding, removing and editing task
	// parameter values in a table with little assistance or restriction.
	//   "TASK_PARAM_FORM" - Supports editing values of declared input
	// parameters of a task. Think of it as a "strongly typed" upgrade to
	// the TASK_PARAM_TABLE.
	//   "PRECONDITION" - Supports editing preconditions of a task config.
	//   "SCRIPT_EDITOR" - Supports adding, editing, and deleting the
	// scripts associated with a script task, as well as modifying the
	// input/output parameters.
	//   "RPC" - Supports editing task parameters associated with an
	// RPC/stubby task.
	//   "TASK_SUMMARY" - Contains readonly task information, including
	// input/output type info.
	//   "SUSPENSION" - Configures a SuspensionTask.
	//   "RPC_TYPED" - Configures a GenericStubbyTypedTask.
	//   "SUB_WORKFLOW" - Configures a SubWorkflowExecutorTask.
	//   "APPS_SCRIPT_NAVIGATOR" - Supports navigating to Apps Script editor
	//   "SUB_WORKFLOW_FOR_EACH_LOOP" - Configures a
	// SubWorkflowForEachLoopTask.
	//   "FIELD_MAPPING" - Configures a FieldMappingTask.
	//   "README" - Contains embedded in-product documentation for a task.
	//   "REST_CALLER" - UI widget for the rest caller task.
	//   "SUB_WORKFLOW_SCATTER_GATHER" - Configures a
	// SubWorkflowScatterGatherTask.
	//   "CLOUD_SQL" - Configures a CloudSql Task.
	//   "GENERIC_CONNECTOR_TASK" - Configure a GenericConnectorTask.
	ModuleId string `json:"moduleId,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoTeardown struct {
	// TeardownTaskConfigs: Required.
	TeardownTaskConfigs []*EnterpriseCrmEventbusProtoTeardownTaskConfig `json:"teardownTaskConfigs,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoTeardownTaskConfig struct {
	// CreatorEmail: The creator's email address.
	CreatorEmail string `json:"creatorEmail,omitempty"`

	// Name: Required. Unique identifier of the teardown task within this
	// Config. We use this field as the identifier to find next teardown
	// tasks.
	Name string `json:"name,omitempty"`

	NextTeardownTask *EnterpriseCrmEventbusProtoNextTeardownTask `json:"nextTeardownTask,omitempty"`

	// Parameters: The parameters the user can pass to this task.
	Parameters *EnterpriseCrmEventbusProtoEventParameters `json:"parameters,omitempty"`

	Properties *EnterpriseCrmEventbusProtoEventBusProperties `json:"properties,omitempty"`

	// TeardownTaskImplementationClassName: Required. Implementation class
	// name.
	TeardownTaskImplementationClassName string `json:"teardownTaskImplementationClassName,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoToken struct {
	Name string `json:"name,omitempty"`

	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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EnterpriseCrmEventbusProtoToken) MarshalJSON() ([]byte, error) {
	type NoMethod EnterpriseCrmEventbusProtoToken
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type EnterpriseCrmEventbusProtoTransformExpression struct {
	// InitialValue: Initial value upon which to perform transformations.
	InitialValue *EnterpriseCrmEventbusProtoBaseValue `json:"initialValue,omitempty"`

	// TransformationFunctions: Transformations to be applied sequentially.
	TransformationFunctions []*EnterpriseCrmEventbusProtoFunction `json:"transformationFunctions,omitempty"`

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

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

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

type EnterpriseCrmEventbusProtoTriggerCriteria struct {
	// Condition: Required. Standard filter expression, when true the
	// workflow will be executed. If there's no
	// trigger_criteria_task_implementation_class_name specified, the
	// condition will be validated directly.
	Condition string `json:"condition,omitempty"`

	// Parameters: Optional. To be used in TaskConfig for the implementation
	// class.
	Parameters *EnterpriseCrmEventbusProtoEventParameters `json:"parameters,omitempty"`

	// TriggerCriteriaTaskImplementationClassName: Optional. Implementation
	// class name. The class should implement the “TypedTask” interface.
	TriggerCriteriaTaskImplementationClassName string `json:"triggerCriteriaTaskImplementationClassName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Condition") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EnterpriseCrmEventbusProtoTriggerCriteria) MarshalJSON() ([]byte, error) {
	type NoMethod EnterpriseCrmEventbusProtoTriggerCriteria
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnterpriseCrmEventbusProtoValueType: Used for define type for values.
// Currently supported value types include int, string, double, array,
// and any proto message.
type EnterpriseCrmEventbusProtoValueType struct {
	BooleanValue bool `json:"booleanValue,omitempty"`

	DoubleArray *EnterpriseCrmEventbusProtoDoubleArray `json:"doubleArray,omitempty"`

	DoubleValue float64 `json:"doubleValue,omitempty"`

	IntArray *EnterpriseCrmEventbusProtoIntArray `json:"intArray,omitempty"`

	IntValue int64 `json:"intValue,omitempty,string"`

	ProtoValue googleapi.RawMessage `json:"protoValue,omitempty"`

	StringArray *EnterpriseCrmEventbusProtoStringArray `json:"stringArray,omitempty"`

	StringValue string `json:"stringValue,omitempty"`

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

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

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

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

// EnterpriseCrmEventbusProtoWorkflowAlertConfig: Message to be used to
// configure custom alerting in the {@code EventConfig} protos for an
// event.
type EnterpriseCrmEventbusProtoWorkflowAlertConfig struct {
	// AggregationPeriod: For an EXPECTED_MIN threshold, this
	// aggregation_period must be lesser than 24 hours.
	AggregationPeriod string `json:"aggregationPeriod,omitempty"`

	// AlertDisabled: Set to false by default. When set to true, the metrics
	// are not aggregated or pushed to Monarch for this workflow alert.
	AlertDisabled bool `json:"alertDisabled,omitempty"`

	// AlertName: A name to identify this alert. This will be displayed in
	// the alert subject. If set, this name should be unique within the
	// scope of the workflow.
	AlertName string `json:"alertName,omitempty"`

	// ClientId: Client associated with this alert configuration.
	ClientId string `json:"clientId,omitempty"`

	// DurationThresholdMs: Should be specified only for *AVERAGE_DURATION
	// and *PERCENTILE_DURATION metrics. This member should be used to
	// specify what duration value the metrics should exceed for the alert
	// to trigger.
	DurationThresholdMs int64 `json:"durationThresholdMs,omitempty,string"`

	ErrorEnumList *EnterpriseCrmEventbusProtoBaseAlertConfigErrorEnumList `json:"errorEnumList,omitempty"`

	// Possible values:
	//   "METRIC_TYPE_UNSPECIFIED" - The default value. Metric type should
	// always be set to one of the other non-default values, otherwise it
	// will result in an INVALID_ARGUMENT error.
	//   "EVENT_ERROR_RATE" - Specifies alerting on the rate of errors for
	// the enclosing workflow.
	//   "EVENT_WARNING_RATE" - Specifies alerting on the rate of warnings
	// for the enclosing workflow. Warnings use the same enum values as
	// errors.
	//   "TASK_ERROR_RATE" - Specifies alerting on the rate of errors for
	// any task in the enclosing workflow.
	//   "TASK_WARNING_RATE" - Specifies alerting on the rate of warnings
	// for any task in the enclosing workflow.
	//   "TASK_RATE" - Specifies alerting on the rate of executions over all
	// tasks in the enclosing workflow.
	//   "EVENT_RATE" - Specifies alerting on the number of events executed
	// in the given aggregation_period.
	//   "EVENT_AVERAGE_DURATION" - Specifies alerting on the average
	// duration of executions for this workflow.
	//   "EVENT_PERCENTILE_DURATION" - Specifies alerting on the duration
	// value of a particular percentile of workflow executions. E.g. If 10%
	// or more of the workflow executions have durations above 5 seconds,
	// alert.
	//   "TASK_AVERAGE_DURATION" - Specifies alerting on the average
	// duration of any task in the enclosing workflow,
	//   "TASK_PERCENTILE_DURATION" - Specifies alerting on the duration
	// value of a particular percentile of any task executions within the
	// enclosing workflow. E.g. If 10% or more of the task executions in the
	// workflow have durations above 5 seconds, alert.
	MetricType string `json:"metricType,omitempty"`

	// NumAggregationPeriods: For how many contiguous aggregation periods
	// should the expected min or max be violated for the alert to be fired.
	NumAggregationPeriods int64 `json:"numAggregationPeriods,omitempty"`

	// OnlyFinalAttempt: For either events or tasks, depending on the type
	// of alert, count only final attempts, not retries.
	OnlyFinalAttempt bool `json:"onlyFinalAttempt,omitempty"`

	// PlaybookUrl: Link to a playbook for resolving the issue that
	// triggered this alert.
	PlaybookUrl string `json:"playbookUrl,omitempty"`

	// ThresholdType: The threshold type, whether lower(expected_min) or
	// upper(expected_max), for which this alert is being configured. If
	// value falls below expected_min or exceeds expected_max, an alert will
	// be fired.
	//
	// Possible values:
	//   "UNSPECIFIED_THRESHOLD_TYPE"
	//   "EXPECTED_MIN" - Note that this field will only trigger alerts if
	// the workflow specifying it runs at least once in 24 hours (which is
	// our in-memory retention period for monarch streams). Also note that
	// `aggregation_period` for this alert configuration must be less than
	// 24 hours.
	//   "EXPECTED_MAX"
	ThresholdType string `json:"thresholdType,omitempty"`

	// ThresholdValue: The metric value, above or below which the alert
	// should be triggered.
	ThresholdValue *EnterpriseCrmEventbusProtoBaseAlertConfigThresholdValue `json:"thresholdValue,omitempty"`

	WarningEnumList *EnterpriseCrmEventbusProtoBaseAlertConfigErrorEnumList `json:"warningEnumList,omitempty"`

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

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

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

// EnterpriseCrmEventbusStats: Stats for the requested dimensions: QPS,
// duration, and error/warning rate
type EnterpriseCrmEventbusStats struct {
	// Dimensions: Dimensions that these stats have been aggregated on.
	Dimensions *EnterpriseCrmEventbusStatsDimensions `json:"dimensions,omitempty"`

	// DurationInSeconds: Average duration in seconds.
	DurationInSeconds float64 `json:"durationInSeconds,omitempty"`

	// ErrorRate: Average error rate.
	ErrorRate float64 `json:"errorRate,omitempty"`

	// Qps: Queries per second.
	Qps float64 `json:"qps,omitempty"`

	// WarningRate: Average warning rate.
	WarningRate float64 `json:"warningRate,omitempty"`

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

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

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

func (s *EnterpriseCrmEventbusStats) UnmarshalJSON(data []byte) error {
	type NoMethod EnterpriseCrmEventbusStats
	var s1 struct {
		DurationInSeconds gensupport.JSONFloat64 `json:"durationInSeconds"`
		ErrorRate         gensupport.JSONFloat64 `json:"errorRate"`
		Qps               gensupport.JSONFloat64 `json:"qps"`
		WarningRate       gensupport.JSONFloat64 `json:"warningRate"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DurationInSeconds = float64(s1.DurationInSeconds)
	s.ErrorRate = float64(s1.ErrorRate)
	s.Qps = float64(s1.Qps)
	s.WarningRate = float64(s1.WarningRate)
	return nil
}

type EnterpriseCrmEventbusStatsDimensions struct {
	ClientId string `json:"clientId,omitempty"`

	// EnumFilterType: Whether to include or exclude the enums matching the
	// regex.
	//
	// Possible values:
	//   "DEFAULT_INCLUSIVE"
	//   "EXCLUSIVE"
	EnumFilterType string `json:"enumFilterType,omitempty"`

	ErrorEnumString string `json:"errorEnumString,omitempty"`

	// Possible values:
	//   "UNSPECIFIED"
	//   "FINAL" - Task has completed successfully or has depleted all retry
	// attempts.
	//   "RETRYABLE" - Task has failed but may be retried.
	//   "CANCELED" - Task has been deliberately canceled.
	RetryAttempt string `json:"retryAttempt,omitempty"`

	TaskName string `json:"taskName,omitempty"`

	TaskNumber string `json:"taskNumber,omitempty"`

	// TriggerId: Stats have been or will be aggregated on set fields for
	// any semantically-meaningful combination.
	TriggerId string `json:"triggerId,omitempty"`

	WarningEnumString string `json:"warningEnumString,omitempty"`

	WorkflowId string `json:"workflowId,omitempty"`

	WorkflowName string `json:"workflowName,omitempty"`

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

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

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

type EnterpriseCrmFrontendsEventbusProtoBooleanParameterArray struct {
	BooleanValues []bool `json:"booleanValues,omitempty"`

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

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

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

type EnterpriseCrmFrontendsEventbusProtoDoubleParameterArray struct {
	DoubleValues []float64 `json:"doubleValues,omitempty"`

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

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

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

func (s *EnterpriseCrmFrontendsEventbusProtoDoubleParameterArray) UnmarshalJSON(data []byte) error {
	type NoMethod EnterpriseCrmFrontendsEventbusProtoDoubleParameterArray
	var s1 struct {
		DoubleValues []gensupport.JSONFloat64 `json:"doubleValues"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DoubleValues = make([]float64, len(s1.DoubleValues))
	for i := range s1.DoubleValues {
		s.DoubleValues[i] = float64(s1.DoubleValues[i])
	}
	return nil
}

// EnterpriseCrmFrontendsEventbusProtoEventExecutionDetails: Contains
// the details of the execution info of this event: this includes the
// tasks execution details plus the event execution statistics. Next
// available id: 10
type EnterpriseCrmFrontendsEventbusProtoEventExecutionDetails struct {
	EventAttemptStats []*EnterpriseCrmEventbusProtoEventExecutionDetailsEventAttemptStats `json:"eventAttemptStats,omitempty"`

	// EventExecutionSnapshot: After snapshot migration, this field will no
	// longer be populated, but old execution snapshots will still be
	// accessible.
	EventExecutionSnapshot []*EnterpriseCrmFrontendsEventbusProtoEventExecutionSnapshot `json:"eventExecutionSnapshot,omitempty"`

	// EventExecutionState: The execution state of this event.
	//
	// Possible values:
	//   "UNSPECIFIED"
	//   "ON_HOLD" - Event is received and waiting for the execution. This
	// happens when firing the event via "postToQueue" or "schedule".
	//   "IN_PROCESS" - Event is under processing.
	//   "SUCCEEDED" - Event execution successfully finished. There's no
	// more change after this state.
	//   "FAILED" - Event execution failed. There's no more change after
	// this state.
	//   "CANCELED" - Event execution canceled by user. There's no more
	// change after this state.
	//   "RETRY_ON_HOLD" - Event execution failed and waiting for retry.
	//   "SUSPENDED" - Event execution suspended and waiting for manual
	// intervention.
	EventExecutionState string `json:"eventExecutionState,omitempty"`

	// EventRetriesFromBeginningCount: Indicates the number of times the
	// execution has restarted from the beginning.
	EventRetriesFromBeginningCount int64 `json:"eventRetriesFromBeginningCount,omitempty"`

	// LogFilePath: The log file path (aka. cns address) for this event.
	LogFilePath string `json:"logFilePath,omitempty"`

	// NetworkAddress: The network address (aka. bns address) that indicates
	// where the event executor is running.
	NetworkAddress string `json:"networkAddress,omitempty"`

	// NextExecutionTime: Next scheduled execution time in case the
	// execution status was RETRY_ON_HOLD.
	NextExecutionTime int64 `json:"nextExecutionTime,omitempty,string"`

	// RyeLockUnheldCount: Used internally and shouldn't be exposed to
	// users. A counter for the cron job to record how many times this event
	// is in in_process state but don't have a lock consecutively/
	RyeLockUnheldCount int64 `json:"ryeLockUnheldCount,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoEventExecutionInfo: Contains all
// the execution details for a workflow instance. Next available id: 24
type EnterpriseCrmFrontendsEventbusProtoEventExecutionInfo struct {
	// ClientId: The event data user sends as request.
	ClientId string `json:"clientId,omitempty"`

	// CreateTime: Auto-generated.
	CreateTime int64 `json:"createTime,omitempty,string"`

	// ErrorCode: Final error-code if event failed.
	ErrorCode *CrmlogErrorCode `json:"errorCode,omitempty"`

	// Errors: Errors, warnings, and informationals associated with the
	// workflow/task. The order in which the errors were added by the
	// workflow/task is maintained.
	Errors []*EnterpriseCrmEventbusProtoErrorDetail `json:"errors,omitempty"`

	// EventExecutionDetails: The execution info about this event.
	EventExecutionDetails *EnterpriseCrmFrontendsEventbusProtoEventExecutionDetails `json:"eventExecutionDetails,omitempty"`

	// EventExecutionInfoId: Auto-generated primary key.
	EventExecutionInfoId string `json:"eventExecutionInfoId,omitempty"`

	// ExecutionTraceInfo: Execution trace info to aggregate parent-child
	// executions.
	ExecutionTraceInfo *EnterpriseCrmEventbusProtoExecutionTraceInfo `json:"executionTraceInfo,omitempty"`

	// LastModifiedTime: Auto-generated.
	LastModifiedTime int64 `json:"lastModifiedTime,omitempty,string"`

	// PostMethod: The ways user posts this event.
	//
	// Possible values:
	//   "UNSPECIFIED"
	//   "POST"
	//   "POST_TO_QUEUE"
	//   "SCHEDULE"
	//   "POST_BY_EVENT_CONFIG_ID"
	//   "POST_WITH_EVENT_DETAILS"
	PostMethod string `json:"postMethod,omitempty"`

	// Product: Which Google product the execution_info belongs to. If not
	// set, the execution_info belongs to Integration Platform by default.
	//
	// Possible values:
	//   "UNSPECIFIED_PRODUCT"
	//   "IP"
	//   "APIGEE"
	//   "SECURITY"
	Product string `json:"product,omitempty"`

	// RequestId: Optional. This is used to de-dup incoming request.
	RequestId string `json:"requestId,omitempty"`

	// RequestParams: Event parameters come in as part of the request.
	RequestParams *EnterpriseCrmFrontendsEventbusProtoEventParameters `json:"requestParams,omitempty"`

	// ResponseParams: Event parameters come out as part of the response.
	ResponseParams *EnterpriseCrmFrontendsEventbusProtoEventParameters `json:"responseParams,omitempty"`

	// SnapshotNumber: Workflow snapshot number.
	SnapshotNumber int64 `json:"snapshotNumber,omitempty,string"`

	// Tenant: Tenant this event is created. Used to reschedule the event to
	// correct tenant.
	Tenant string `json:"tenant,omitempty"`

	// TriggerId: The trigger id of the workflow trigger config. If both
	// trigger_id and client_id is present, the workflow is executed from
	// the start tasks provided by the matching trigger config otherwise it
	// is executed from the default start tasks.
	TriggerId string `json:"triggerId,omitempty"`

	// WorkflowId: Required. Pointer to the workflow it is executing.
	WorkflowId string `json:"workflowId,omitempty"`

	// WorkflowName: Name of the workflow.
	WorkflowName string `json:"workflowName,omitempty"`

	// WorkflowRetryBackoffIntervalSeconds: Time interval in seconds to
	// schedule retry of workflow in manifold when workflow is already
	// running
	WorkflowRetryBackoffIntervalSeconds int64 `json:"workflowRetryBackoffIntervalSeconds,omitempty,string"`

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

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

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

type EnterpriseCrmFrontendsEventbusProtoEventExecutionSnapshot struct {
	// CheckpointTaskNumber: Indicates "right after which checkpoint task's
	// execution" this snapshot is taken.
	CheckpointTaskNumber string `json:"checkpointTaskNumber,omitempty"`

	// ConditionResults: All of the computed conditions that been
	// calculated.
	ConditionResults []*EnterpriseCrmEventbusProtoConditionResult `json:"conditionResults,omitempty"`

	// DiffParams: The parameters in Event object that differs from last
	// snapshot.
	DiffParams *EnterpriseCrmFrontendsEventbusProtoEventParameters `json:"diffParams,omitempty"`

	// EventExecutionInfoId: Points to the event execution info this
	// snapshot belongs to.
	EventExecutionInfoId string `json:"eventExecutionInfoId,omitempty"`

	// EventExecutionSnapshotId: Auto-generated. Used as primary key for
	// EventExecutionSnapshots table.
	EventExecutionSnapshotId string `json:"eventExecutionSnapshotId,omitempty"`

	EventExecutionSnapshotMetadata *EnterpriseCrmEventbusProtoEventExecutionSnapshotEventExecutionSnapshotMetadata `json:"eventExecutionSnapshotMetadata,omitempty"`

	// EventParams: The parameters in Event object.
	EventParams *EnterpriseCrmFrontendsEventbusProtoEventParameters `json:"eventParams,omitempty"`

	// SnapshotTime: Indicates when this snapshot is taken.
	SnapshotTime int64 `json:"snapshotTime,omitempty,string"`

	// TaskExecutionDetails: All of the task execution details at the given
	// point of time.
	TaskExecutionDetails []*EnterpriseCrmEventbusProtoTaskExecutionDetails `json:"taskExecutionDetails,omitempty"`

	// TaskName: The task name associated with this snapshot. Could be
	// empty.
	TaskName string `json:"taskName,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoEventParameters: LINT.IfChange
// This message is used for processing and persisting (when applicable)
// key value pair parameters for each event in the event bus. Please see
type EnterpriseCrmFrontendsEventbusProtoEventParameters struct {
	// Parameters: Parameters are a part of Event and can be used to
	// communicate between different tasks that are part of the same
	// workflow execution.
	Parameters []*EnterpriseCrmFrontendsEventbusProtoParameterEntry `json:"parameters,omitempty"`

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

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

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

type EnterpriseCrmFrontendsEventbusProtoIntParameterArray struct {
	IntValues googleapi.Int64s `json:"intValues,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoParamSpecEntry: Key-value pair of
// EventBus task parameters. Next id: 13
type EnterpriseCrmFrontendsEventbusProtoParamSpecEntry struct {
	// ClassName: The FQCN of the Java object this represents. A string, for
	// example, would be "java.lang.String". If this is "java.lang.Object",
	// the parameter can be of any type.
	ClassName string `json:"className,omitempty"`

	// CollectionElementClassName: If it is a collection of objects, this
	// would be the FCQN of every individual element in the collection. If
	// this is "java.lang.Object", the parameter is a collection of any
	// type.
	CollectionElementClassName string `json:"collectionElementClassName,omitempty"`

	// Config: Optional fields, such as help text and other useful info.
	Config *EnterpriseCrmEventbusProtoParamSpecEntryConfig `json:"config,omitempty"`

	// DataType: The data type of the parameter.
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "STRING_VALUE"
	//   "INT_VALUE"
	//   "DOUBLE_VALUE"
	//   "BOOLEAN_VALUE"
	//   "PROTO_VALUE"
	//   "SERIALIZED_OBJECT_VALUE"
	//   "STRING_ARRAY"
	//   "INT_ARRAY"
	//   "DOUBLE_ARRAY"
	//   "PROTO_ARRAY"
	//   "PROTO_ENUM"
	//   "BOOLEAN_ARRAY"
	//   "PROTO_ENUM_ARRAY"
	//   "BYTES" - BYTES and BYTES_ARRAY data types are not allowed for
	// top-level params. They're only meant to support protobufs with BYTES
	// (sub)fields.
	//   "BYTES_ARRAY"
	//   "NON_SERIALIZABLE_OBJECT"
	//   "JSON_VALUE"
	DataType string `json:"dataType,omitempty"`

	// DefaultValue: Default values for the defined keys. Each value can
	// either be string, int, double or any proto message or a serialized
	// object.
	DefaultValue *EnterpriseCrmFrontendsEventbusProtoParameterValueType `json:"defaultValue,omitempty"`

	// IsDeprecated: If set, this entry is deprecated, so further use of
	// this parameter should be prohibited.
	IsDeprecated bool `json:"isDeprecated,omitempty"`

	IsOutput bool `json:"isOutput,omitempty"`

	// JsonSchema: If the data_type is JSON_VALUE, then this will define its
	// schema.
	JsonSchema string `json:"jsonSchema,omitempty"`

	// Key: Key is used to retrieve the corresponding parameter value. This
	// should be unique for a given task. These parameters must be
	// predefined in the workflow definition.
	Key string `json:"key,omitempty"`

	// ProtoDef: Populated if this represents a proto or proto array.
	ProtoDef *EnterpriseCrmEventbusProtoParamSpecEntryProtoDefinition `json:"protoDef,omitempty"`

	// Required: If set, the user must provide an input value for this
	// parameter.
	Required bool `json:"required,omitempty"`

	// ValidationRule: Rule used to validate inputs (individual values and
	// collection elements) for this parameter.
	ValidationRule *EnterpriseCrmEventbusProtoParamSpecEntryValidationRule `json:"validationRule,omitempty"`

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

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

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

type EnterpriseCrmFrontendsEventbusProtoParamSpecsMessage struct {
	Parameters []*EnterpriseCrmFrontendsEventbusProtoParamSpecEntry `json:"parameters,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoParameterEntry: Key-value pair of
// EventBus parameters.
type EnterpriseCrmFrontendsEventbusProtoParameterEntry struct {
	// DataType: Explicitly getting the type of the parameter.
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "STRING_VALUE"
	//   "INT_VALUE"
	//   "DOUBLE_VALUE"
	//   "BOOLEAN_VALUE"
	//   "PROTO_VALUE"
	//   "SERIALIZED_OBJECT_VALUE"
	//   "STRING_ARRAY"
	//   "INT_ARRAY"
	//   "DOUBLE_ARRAY"
	//   "PROTO_ARRAY"
	//   "PROTO_ENUM"
	//   "BOOLEAN_ARRAY"
	//   "PROTO_ENUM_ARRAY"
	//   "BYTES" - BYTES and BYTES_ARRAY data types are not allowed for
	// top-level params. They're only meant to support protobufs with BYTES
	// (sub)fields.
	//   "BYTES_ARRAY"
	//   "NON_SERIALIZABLE_OBJECT"
	//   "JSON_VALUE"
	DataType string `json:"dataType,omitempty"`

	// Key: Key is used to retrieve the corresponding parameter value. This
	// should be unique for a given fired event. These parameters must be
	// predefined in the workflow definition.
	Key string `json:"key,omitempty"`

	// Value: Values for the defined keys. Each value can either be string,
	// int, double or any proto message.
	Value *EnterpriseCrmFrontendsEventbusProtoParameterValueType `json:"value,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoParameterMap: A generic multi-map
// that holds key value pairs. They keys and values can be of any type,
// unless specified.
type EnterpriseCrmFrontendsEventbusProtoParameterMap struct {
	Entries []*EnterpriseCrmFrontendsEventbusProtoParameterMapEntry `json:"entries,omitempty"`

	// KeyType: Option to specify key value type for all entries of the map.
	// If provided then field types for all entries must conform to this.
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "STRING_VALUE"
	//   "INT_VALUE"
	//   "DOUBLE_VALUE"
	//   "BOOLEAN_VALUE"
	//   "PROTO_VALUE"
	//   "SERIALIZED_OBJECT_VALUE"
	//   "STRING_ARRAY"
	//   "INT_ARRAY"
	//   "DOUBLE_ARRAY"
	//   "PROTO_ARRAY"
	//   "PROTO_ENUM"
	//   "BOOLEAN_ARRAY"
	//   "PROTO_ENUM_ARRAY"
	//   "BYTES" - BYTES and BYTES_ARRAY data types are not allowed for
	// top-level params. They're only meant to support protobufs with BYTES
	// (sub)fields.
	//   "BYTES_ARRAY"
	//   "NON_SERIALIZABLE_OBJECT"
	//   "JSON_VALUE"
	KeyType string `json:"keyType,omitempty"`

	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "STRING_VALUE"
	//   "INT_VALUE"
	//   "DOUBLE_VALUE"
	//   "BOOLEAN_VALUE"
	//   "PROTO_VALUE"
	//   "SERIALIZED_OBJECT_VALUE"
	//   "STRING_ARRAY"
	//   "INT_ARRAY"
	//   "DOUBLE_ARRAY"
	//   "PROTO_ARRAY"
	//   "PROTO_ENUM"
	//   "BOOLEAN_ARRAY"
	//   "PROTO_ENUM_ARRAY"
	//   "BYTES" - BYTES and BYTES_ARRAY data types are not allowed for
	// top-level params. They're only meant to support protobufs with BYTES
	// (sub)fields.
	//   "BYTES_ARRAY"
	//   "NON_SERIALIZABLE_OBJECT"
	//   "JSON_VALUE"
	ValueType string `json:"valueType,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoParameterMapEntry: Entry is a pair
// of key and value.
type EnterpriseCrmFrontendsEventbusProtoParameterMapEntry struct {
	Key *EnterpriseCrmFrontendsEventbusProtoParameterMapField `json:"key,omitempty"`

	Value *EnterpriseCrmFrontendsEventbusProtoParameterMapField `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EnterpriseCrmFrontendsEventbusProtoParameterMapEntry) MarshalJSON() ([]byte, error) {
	type NoMethod EnterpriseCrmFrontendsEventbusProtoParameterMapEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnterpriseCrmFrontendsEventbusProtoParameterMapField: Field
// represents either the key or value in an entry.
type EnterpriseCrmFrontendsEventbusProtoParameterMapField struct {
	// LiteralValue: Passing a literal value.
	LiteralValue *EnterpriseCrmFrontendsEventbusProtoParameterValueType `json:"literalValue,omitempty"`

	// ReferenceKey: Referencing one of the WF variables.
	ReferenceKey string `json:"referenceKey,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoParameterValueType: To support
// various types of parameter values. Next available id: 14
type EnterpriseCrmFrontendsEventbusProtoParameterValueType struct {
	BooleanArray *EnterpriseCrmFrontendsEventbusProtoBooleanParameterArray `json:"booleanArray,omitempty"`

	BooleanValue bool `json:"booleanValue,omitempty"`

	DoubleArray *EnterpriseCrmFrontendsEventbusProtoDoubleParameterArray `json:"doubleArray,omitempty"`

	DoubleValue float64 `json:"doubleValue,omitempty"`

	IntArray *EnterpriseCrmFrontendsEventbusProtoIntParameterArray `json:"intArray,omitempty"`

	IntValue int64 `json:"intValue,omitempty,string"`

	JsonValue string `json:"jsonValue,omitempty"`

	ProtoArray *EnterpriseCrmFrontendsEventbusProtoProtoParameterArray `json:"protoArray,omitempty"`

	ProtoValue googleapi.RawMessage `json:"protoValue,omitempty"`

	SerializedObjectValue *EnterpriseCrmFrontendsEventbusProtoSerializedObjectParameter `json:"serializedObjectValue,omitempty"`

	StringArray *EnterpriseCrmFrontendsEventbusProtoStringParameterArray `json:"stringArray,omitempty"`

	StringValue string `json:"stringValue,omitempty"`

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

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

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

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

type EnterpriseCrmFrontendsEventbusProtoProtoParameterArray struct {
	ProtoValues []googleapi.RawMessage `json:"protoValues,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoRollbackStrategy: Next available
// id: 4
type EnterpriseCrmFrontendsEventbusProtoRollbackStrategy struct {
	// Parameters: Optional. The customized parameters the user can pass to
	// this task.
	Parameters *EnterpriseCrmFrontendsEventbusProtoEventParameters `json:"parameters,omitempty"`

	// RollbackTaskImplementationClassName: Required. This is the name of
	// the task that needs to be executed upon rollback of this task.
	RollbackTaskImplementationClassName string `json:"rollbackTaskImplementationClassName,omitempty"`

	// TaskNumbersToRollback: Required. These are the tasks numbers of the
	// tasks whose
	// `rollback_strategy.rollback_task_implementation_class_name` needs to
	// be executed upon failure of this task.
	TaskNumbersToRollback []string `json:"taskNumbersToRollback,omitempty"`

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

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

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

type EnterpriseCrmFrontendsEventbusProtoSerializedObjectParameter struct {
	ObjectValue string `json:"objectValue,omitempty"`

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

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

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

type EnterpriseCrmFrontendsEventbusProtoStringParameterArray struct {
	StringValues []string `json:"stringValues,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoTaskConfig: The task configuration
// details. This is not the implementation of Task. There might be
// multiple TaskConfigs for the same Task.
type EnterpriseCrmFrontendsEventbusProtoTaskConfig struct {
	// AlertConfigs: Alert configurations on error rate, warning rate,
	// number of runs, durations, etc.
	AlertConfigs []*EnterpriseCrmEventbusProtoTaskAlertConfig `json:"alertConfigs,omitempty"`

	// CreateTime: Auto-generated.
	CreateTime string `json:"createTime,omitempty"`

	// CreatorEmail: The creator's email address. Auto-generated from the
	// user's email.
	CreatorEmail string `json:"creatorEmail,omitempty"`

	// Description: User-provided description intended to give more business
	// context about the task.
	Description string `json:"description,omitempty"`

	// DisableStrictTypeValidation: If this config contains a TypedTask,
	// allow validation to succeed if an input is read from the output of
	// another TypedTask whose output type is declared as a superclass of
	// the requested input type. For instance, if the previous task declares
	// an output of type Message, any task with this flag enabled will pass
	// validation when attempting to read any proto Message type from the
	// resultant Event parameter.
	DisableStrictTypeValidation bool `json:"disableStrictTypeValidation,omitempty"`

	// ErrorCatcherId: Optional Error catcher id of the error catch flow
	// which will be executed when execution error happens in the task
	ErrorCatcherId string `json:"errorCatcherId,omitempty"`

	// Possible values:
	//   "EXTERNAL_TASK_TYPE_UNSPECIFIED" - Default value. External task
	// type is not specified
	//   "NORMAL_TASK" - Tasks belongs to the normal task flows
	//   "ERROR_TASK" - Task belongs to the error catch task flows
	ExternalTaskType string `json:"externalTaskType,omitempty"`

	// FailurePolicy: Optional. Determines the number of times the task will
	// be retried on failure and with what retry strategy. This is
	// applicable for asynchronous calls to Eventbus alone (Post To Queue,
	// Schedule etc.).
	FailurePolicy *EnterpriseCrmEventbusProtoFailurePolicy `json:"failurePolicy,omitempty"`

	// IncomingEdgeCount: The number of edges leading into this TaskConfig.
	IncomingEdgeCount int64 `json:"incomingEdgeCount,omitempty"`

	// JsonValidationOption: If set, overrides the option configured in the
	// Task implementation class.
	//
	// Possible values:
	//   "UNSPECIFIED_JSON_VALIDATION_OPTION" - As per the default behavior,
	// no validation will be run. Will not override any option set in a
	// Task.
	//   "SKIP" - Do not run any validation against JSON schemas.
	//   "PRE_EXECUTION" - Validate all potential input JSON parameters
	// against schemas specified in WorkflowParameters.
	//   "POST_EXECUTION" - Validate all potential output JSON parameters
	// against schemas specified in WorkflowParameters.
	//   "PRE_POST_EXECUTION" - Perform both PRE_EXECUTION and
	// POST_EXECUTION validations.
	JsonValidationOption string `json:"jsonValidationOption,omitempty"`

	// Label: User-provided label that is attached to this TaskConfig in the
	// UI.
	Label string `json:"label,omitempty"`

	// LastModifiedTime: Auto-generated.
	LastModifiedTime string `json:"lastModifiedTime,omitempty"`

	// NextTasks: The set of tasks that are next in line to be executed as
	// per the execution graph defined for the parent event, specified by
	// `event_config_id`. Each of these next tasks are executed only if the
	// condition associated with them evaluates to true.
	NextTasks []*EnterpriseCrmEventbusProtoNextTask `json:"nextTasks,omitempty"`

	// NextTasksExecutionPolicy: The policy dictating the execution of the
	// next set of tasks for the current task.
	//
	// Possible values:
	//   "UNSPECIFIED" - Default
	//   "RUN_ALL_MATCH" - Execute all the tasks that satisfy their
	// associated condition.
	//   "RUN_FIRST_MATCH" - Execute the first task that satisfies the
	// associated condition.
	NextTasksExecutionPolicy string `json:"nextTasksExecutionPolicy,omitempty"`

	// Parameters: The customized parameters the user can pass to this task.
	Parameters map[string]EnterpriseCrmFrontendsEventbusProtoParameterEntry `json:"parameters,omitempty"`

	// Position: Optional. Informs the front-end application where to draw
	// this task config on the UI.
	Position *EnterpriseCrmEventbusProtoCoordinate `json:"position,omitempty"`

	// Precondition: Optional. Standard filter expression evaluated before
	// execution. Independent of other conditions and tasks. Can be used to
	// enable rollout. e.g. "rollout(5)" will only allow 5% of incoming
	// traffic to task.
	Precondition string `json:"precondition,omitempty"`

	// PreconditionLabel: Optional. User-provided label that is attached to
	// precondition in the UI.
	PreconditionLabel string `json:"preconditionLabel,omitempty"`

	// RollbackStrategy: Optional. Contains information about what needs to
	// be done upon failure (either a permanent error or after it has been
	// retried too many times).
	RollbackStrategy *EnterpriseCrmFrontendsEventbusProtoRollbackStrategy `json:"rollbackStrategy,omitempty"`

	// SuccessPolicy: Determines what action to take upon successful task
	// completion.
	SuccessPolicy *EnterpriseCrmEventbusProtoSuccessPolicy `json:"successPolicy,omitempty"`

	// SynchronousCallFailurePolicy: Optional. Determines the number of
	// times the task will be retried on failure and with what retry
	// strategy. This is applicable for synchronous calls to Eventbus alone
	// (Post).
	SynchronousCallFailurePolicy *EnterpriseCrmEventbusProtoFailurePolicy `json:"synchronousCallFailurePolicy,omitempty"`

	// TaskEntity: Copy of the task entity that this task config is an
	// instance of.
	TaskEntity *EnterpriseCrmFrontendsEventbusProtoTaskEntity `json:"taskEntity,omitempty"`

	// TaskExecutionStrategy: The policy dictating the execution strategy of
	// this task.
	//
	// Possible values:
	//   "WHEN_ALL_SUCCEED" - Wait until all of its previous tasks finished
	// execution, then verify at least one of the edge conditions is met,
	// and execute if possible. This should be considered as
	// WHEN_ALL_TASKS_SUCCEED.
	//   "WHEN_ANY_SUCCEED" - Start execution as long as any of its previous
	// tasks finished execution and the corresponding edge condition is met
	// (since we will execute if only that succeeding edge condition is
	// met).
	//   "WHEN_ALL_TASKS_AND_CONDITIONS_SUCCEED" - Wait until all of its
	// previous tasks finished execution, then verify the all edge
	// conditions are met and execute if possible.
	TaskExecutionStrategy string `json:"taskExecutionStrategy,omitempty"`

	// TaskName: The name for the task.
	TaskName string `json:"taskName,omitempty"`

	// TaskNumber: REQUIRED: the identifier of this task within its parent
	// event config, specified by the client. This should be unique among
	// all the tasks belong to the same event config. We use this field as
	// the identifier to find next tasks (via field
	// `next_tasks.task_number`).
	TaskNumber string `json:"taskNumber,omitempty"`

	// TaskSpec: A string template that allows user to configure task
	// parameters (with either literal default values or tokens which will
	// be resolved at execution time) for the task. It will eventually
	// replace the old "parameters" field.
	TaskSpec string `json:"taskSpec,omitempty"`

	// TaskTemplateName: Used to define task-template name if task is of
	// type task-template
	TaskTemplateName string `json:"taskTemplateName,omitempty"`

	// TaskType: Defines the type of the task
	//
	// Possible values:
	//   "TASK" - Normal IP task
	//   "ASIS_TEMPLATE" - Task is of As-Is Template type
	//   "IO_TEMPLATE" - Task is of I/O template type with a different
	// underlying task
	TaskType string `json:"taskType,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoTaskEntity: Contains a task's
// metadata and associated information. Next available id: 7
type EnterpriseCrmFrontendsEventbusProtoTaskEntity struct {
	// DisabledForVpcSc: True if the task has conflict with vpcsc
	DisabledForVpcSc bool `json:"disabledForVpcSc,omitempty"`

	// Metadata: Metadata inclueds the task name, author and so on.
	Metadata *EnterpriseCrmEventbusProtoTaskMetadata `json:"metadata,omitempty"`

	// ParamSpecs: Declarations for inputs/outputs for a TypedTask. This is
	// also associated with the METADATA mask.
	ParamSpecs *EnterpriseCrmFrontendsEventbusProtoParamSpecsMessage `json:"paramSpecs,omitempty"`

	// Stats: Deprecated - statistics from the Monarch query.
	Stats *EnterpriseCrmEventbusStats `json:"stats,omitempty"`

	// TaskType: Defines the type of the task
	//
	// Possible values:
	//   "TASK" - Normal IP task
	//   "ASIS_TEMPLATE" - Task is of As-Is Template type
	//   "IO_TEMPLATE" - Task is of I/O template type with a different
	// underlying task
	TaskType string `json:"taskType,omitempty"`

	// UiConfig: UI configuration for this task Also associated with the
	// METADATA mask.
	UiConfig *EnterpriseCrmEventbusProtoTaskUiConfig `json:"uiConfig,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoTriggerConfig: Configuration
// detail of a trigger. Next available id: 19
type EnterpriseCrmFrontendsEventbusProtoTriggerConfig struct {
	// AlertConfig: An alert threshold configuration for the [trigger +
	// client + workflow] tuple. If these values are not specified in the
	// trigger config, default values will be populated by the system. Note
	// that there must be exactly one alert threshold configured per [client
	// + trigger + workflow] when published.
	AlertConfig []*EnterpriseCrmEventbusProtoWorkflowAlertConfig `json:"alertConfig,omitempty"`

	CloudSchedulerConfig *EnterpriseCrmEventbusProtoCloudSchedulerConfig `json:"cloudSchedulerConfig,omitempty"`

	// Description: User-provided description intended to give more business
	// context about the task.
	Description string `json:"description,omitempty"`

	// EnabledClients: Required. The list of client ids which are enabled to
	// execute the workflow using this trigger. In other words, these
	// clients have the workflow execution privledges for this trigger. For
	// API trigger, the client id in the incoming request is validated
	// against the list of enabled clients. For non-API triggers, one
	// workflow execution is triggered on behalf of each enabled client.
	EnabledClients []string `json:"enabledClients,omitempty"`

	// ErrorCatcherId: Optional Error catcher id of the error catch flow
	// which will be executed when execution error happens in the task
	ErrorCatcherId string `json:"errorCatcherId,omitempty"`

	// Label: The user created label for a particular trigger.
	Label string `json:"label,omitempty"`

	// NextTasksExecutionPolicy: Dictates how next tasks will be executed.
	//
	// Possible values:
	//   "UNSPECIFIED" - Default
	//   "RUN_ALL_MATCH" - Execute all the tasks that satisfy their
	// associated condition.
	//   "RUN_FIRST_MATCH" - Execute the first task that satisfies the
	// associated condition.
	NextTasksExecutionPolicy string `json:"nextTasksExecutionPolicy,omitempty"`

	// PauseWorkflowExecutions: Optional. If set to true, any upcoming
	// requests for this trigger config will be paused and the executions
	// will be resumed later when the flag is reset. The workflow to which
	// this trigger config belongs has to be in ACTIVE status for the
	// executions to be paused or resumed.
	PauseWorkflowExecutions bool `json:"pauseWorkflowExecutions,omitempty"`

	// Position: Optional. Informs the front-end application where to draw
	// this trigger config on the UI.
	Position *EnterpriseCrmEventbusProtoCoordinate `json:"position,omitempty"`

	// Properties: Configurable properties of the trigger, not to be
	// confused with workflow parameters. E.g. "name" is a property for API
	// triggers and "subscription" is a property for Cloud Pubsub triggers.
	Properties map[string]string `json:"properties,omitempty"`

	// StartTasks: Set of tasks numbers from where the workflow execution is
	// started by this trigger. If this is empty, then workflow is executed
	// with default start tasks. In the list of start tasks, none of two
	// tasks can have direct ancestor-descendant relationships (i.e. in a
	// same workflow execution graph).
	StartTasks []*EnterpriseCrmEventbusProtoNextTask `json:"startTasks,omitempty"`

	// TriggerCriteria: Optional. When set, Eventbus will run the task
	// specified in the trigger_criteria and validate the result using the
	// trigger_criteria.condition, and only execute the workflow when result
	// is true.
	TriggerCriteria *EnterpriseCrmEventbusProtoTriggerCriteria `json:"triggerCriteria,omitempty"`

	// TriggerId: The backend trigger ID.
	TriggerId string `json:"triggerId,omitempty"`

	// TriggerNumber: Required. A number to uniquely identify each trigger
	// config within the workflow on UI.
	TriggerNumber string `json:"triggerNumber,omitempty"`

	// Possible values:
	//   "UNKNOWN"
	//   "CLOUD_PUBSUB"
	//   "GOOPS"
	//   "SFDC_SYNC"
	//   "CRON"
	//   "API"
	//   "MANIFOLD_TRIGGER"
	//   "DATALAYER_DATA_CHANGE"
	//   "SFDC_CHANNEL"
	//   "CLOUD_PUBSUB_EXTERNAL"
	//   "SFDC_CDC_CHANNEL"
	//   "SFDC_PLATFORM_EVENTS_CHANNEL"
	//   "CLOUD_SCHEDULER"
	//   "INTEGRATION_CONNECTOR_TRIGGER"
	TriggerType string `json:"triggerType,omitempty"`

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

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

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

type EnterpriseCrmFrontendsEventbusProtoWorkflowParameterEntry struct {
	// Attributes: Metadata information about the parameters.
	Attributes *EnterpriseCrmEventbusProtoAttributes `json:"attributes,omitempty"`

	// Children: Child parameters nested within this parameter. This field
	// only applies to protobuf parameters
	Children []*EnterpriseCrmFrontendsEventbusProtoWorkflowParameterEntry `json:"children,omitempty"`

	// DataType: The data type of the parameter.
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED"
	//   "STRING_VALUE"
	//   "INT_VALUE"
	//   "DOUBLE_VALUE"
	//   "BOOLEAN_VALUE"
	//   "PROTO_VALUE"
	//   "SERIALIZED_OBJECT_VALUE"
	//   "STRING_ARRAY"
	//   "INT_ARRAY"
	//   "DOUBLE_ARRAY"
	//   "PROTO_ARRAY"
	//   "PROTO_ENUM"
	//   "BOOLEAN_ARRAY"
	//   "PROTO_ENUM_ARRAY"
	//   "BYTES" - BYTES and BYTES_ARRAY data types are not allowed for
	// top-level params. They're only meant to support protobufs with BYTES
	// (sub)fields.
	//   "BYTES_ARRAY"
	//   "NON_SERIALIZABLE_OBJECT"
	//   "JSON_VALUE"
	DataType string `json:"dataType,omitempty"`

	// DefaultValue: Default values for the defined keys. Each value can
	// either be string, int, double or any proto message or a serialized
	// object.
	DefaultValue *EnterpriseCrmFrontendsEventbusProtoParameterValueType `json:"defaultValue,omitempty"`

	// InOutType: Specifies the input/output type for the parameter.
	//
	// Possible values:
	//   "IN_OUT_TYPE_UNSPECIFIED"
	//   "IN" - Input parameters for the workflow. EventBus validates that
	// these parameters exist in the workflows before execution.
	//   "OUT" - Output Parameters for the workflow. EventBus will only
	// return the workflow parameters tagged with OUT in the response back.
	//   "IN_OUT" - Input or Output Parameters. These can be used as both
	// input and output. EventBus will validate for the existence of these
	// parameters before execution and will also return this parameter back
	// in the response.
	InOutType string `json:"inOutType,omitempty"`

	// IsTransient: Whether this parameter is a transient parameter.
	IsTransient bool `json:"isTransient,omitempty"`

	// JsonSchema: This schema will be used to validate runtime JSON-typed
	// values of this parameter.
	JsonSchema string `json:"jsonSchema,omitempty"`

	// Key: Key is used to retrieve the corresponding parameter value. This
	// should be unique for a given fired event. These parameters must be
	// predefined in the workflow definition.
	Key string `json:"key,omitempty"`

	// Name: The name (without prefix) to be displayed in the UI for this
	// parameter. E.g. if the key is "foo.bar.myName", then the name would
	// be "myName".
	Name string `json:"name,omitempty"`

	// ProducedBy: The identifier of the node (TaskConfig/TriggerConfig)
	// this parameter was produced by, if it is a transient param or a copy
	// of an input param.
	ProducedBy *EnterpriseCrmEventbusProtoNodeIdentifier `json:"producedBy,omitempty"`

	Producer string `json:"producer,omitempty"`

	// ProtoDefName: The name of the protobuf type if the parameter has a
	// protobuf data type.
	ProtoDefName string `json:"protoDefName,omitempty"`

	// ProtoDefPath: If the data type is of type proto or proto array, this
	// field needs to be populated with the fully qualified proto name. This
	// message, for example, would be
	// "enterprise.crm.frontends.eventbus.proto.WorkflowParameterEntry".
	ProtoDefPath string `json:"protoDefPath,omitempty"`

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

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

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

// EnterpriseCrmFrontendsEventbusProtoWorkflowParameters: LINT.IfChange
// This is the frontend version of WorkflowParameters. It's exactly like
// the backend version except that instead of flattening protobuf
// parameters and treating every field and subfield of a protobuf
// parameter as a separate parameter, the fields/subfields of a protobuf
// parameter will be nested as "children" (see 'children' field below)
// parameters of the parent parameter. Please refer to
// enterprise/crm/eventbus/proto/workflow_parameters.proto for more
// information about WorkflowParameters.
type EnterpriseCrmFrontendsEventbusProtoWorkflowParameters struct {
	// Parameters: Parameters are a part of Event and can be used to
	// communiticate between different tasks that are part of the same
	// workflow execution.
	Parameters []*EnterpriseCrmFrontendsEventbusProtoWorkflowParameterEntry `json:"parameters,omitempty"`

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

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

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

// EnterpriseCrmLoggingGwsFieldLimits: Describes string and array limits
// when writing to logs. When a limit is exceeded the *shortener_type*
// describes how to shorten the field. next_id: 6
type EnterpriseCrmLoggingGwsFieldLimits struct {
	// Possible values:
	//   "LOG_ACTION_UNSPECIFIED"
	//   "DONT_LOG"
	//   "LOG"
	LogAction string `json:"logAction,omitempty"`

	// LogType: To which type(s) of logs the limits apply.
	//
	// Possible values:
	//   "LOG_TYPE_UNSPECIFIED"
	//   "GWS" - Limits apply when log detail records are written to GWS.
	//   "GTS" - Limits apply when log detail records are written to GTS
	// (e.g., RecordIO files).
	//   "ALL" - Limits apply to *all* output log types.
	LogType []string `json:"logType,omitempty"`

	// MaxArraySize: maximum array size. If the array exceds this size, the
	// field (list) is truncated.
	MaxArraySize int64 `json:"maxArraySize,omitempty"`

	// MaxStringLength: maximum string length. If the field exceeds this
	// amount the field is shortened.
	MaxStringLength int64 `json:"maxStringLength,omitempty"`

	// Possible values:
	//   "SHORTENER_TYPE_UNSPECIFIED"
	//   "SHORTEN" - String is shortened to max_string_length.
	//   "HASH" - String is replaced by its hex-string hash.
	//   "SHORTEN_WITH_HASH" - String is replaced by a combination of string
	// shortening and a hex-string hash.
	//   "SHORTEN_EMAIL" - String shortening for email addresses. Shortening
	// may be done on the user and/or domain portion of the email address.
	//   "SHORTEN_EMAIL_WITH_HASH" - String is replaced by a combination of
	// string shortening and a hex-string hash for an email address.
	//   "SHORTEN_DOMAIN" - Shortens a domain name (e.g., as part of an
	// email address or URL).
	ShortenerType string `json:"shortenerType,omitempty"`

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

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

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

// EnterpriseCrmLoggingGwsSanitizeOptions: Identifies whether a field
// contains, or may contain, PII or sensitive data, and how to sanitize
// the field if it does. If a field's privacy type cannot be determined
// then it is sanitized (e.g., scrubbed). The specific sanitizer
// implementation is determined by run-time configuration and
// environment options (e.g., prod vs. qa). next_id: 5
type EnterpriseCrmLoggingGwsSanitizeOptions struct {
	// IsAlreadySanitized: If true, the value has already been sanitized and
	// needs no further sanitization. For instance, a D3 customer id is
	// already an obfuscated entity and *might not* need further
	// sanitization.
	IsAlreadySanitized bool `json:"isAlreadySanitized,omitempty"`

	// LogType: To which type(s) of logs the sanitize options apply.
	//
	// Possible values:
	//   "LOG_TYPE_UNSPECIFIED"
	//   "GWS" - Limits apply when log detail records are written to GWS.
	//   "GTS" - Limits apply when log detail records are written to GTS
	// (e.g., RecordIO files).
	//   "ALL" - Limits apply to *all* output log types.
	LogType []string `json:"logType,omitempty"`

	// Possible values:
	//   "PRIVACY_TYPE_UNSPECIFIED"
	//   "NOT_PII" - Field does *NOT* contain PII or sensitive data.
	//   "PII" - Field contains PII.
	//   "SPII" - Field contains Sensitive PII.
	//   "UNSURE" - Unsure if field contains PII.
	Privacy string `json:"privacy,omitempty"`

	// Possible values:
	//   "SANITIZE_TYPE_UNSPECIFIED"
	//   "SCRUB" - Replace value with a scrubbed value (usu. a constant).
	//   "ANONYMIZE" - Transform a value so that it cannot be tracked across
	// events. However, a given value, is transformed to the same value
	// *within* an event. E.g., "foo.com" is transformed to "0xabcdef" for
	// event 1001, and to "0xfedcba" for event 1002.
	//   "ANONYMIZE_LIMITED_REPEATABLE" - Transform values as with
	// ANONYMIZER, but the same transformation is repeated for a limited
	// time (e.g., 1 day).
	//   "OBFUSCATE" - The value is transformed using a well-defined
	// obfuscator (e.g., D3_CUSTOMER_ID).
	//   "ENCRYPT" - The value is encrypted.
	//   "DO_NOT_SANITIZE" - No sanitization is required.
	SanitizeType string `json:"sanitizeType,omitempty"`

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

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

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

// GoogleCloudConnectorsV1AuthConfig: AuthConfig defines details of a
// authentication type.
type GoogleCloudConnectorsV1AuthConfig struct {
	// AdditionalVariables: List containing additional auth configs.
	AdditionalVariables []*GoogleCloudConnectorsV1ConfigVariable `json:"additionalVariables,omitempty"`

	// AuthKey: Identifier key for auth config
	AuthKey string `json:"authKey,omitempty"`

	// AuthType: The type of authentication configured.
	//
	// Possible values:
	//   "AUTH_TYPE_UNSPECIFIED" - Authentication type not specified.
	//   "USER_PASSWORD" - Username and Password Authentication.
	//   "OAUTH2_JWT_BEARER" - JSON Web Token (JWT) Profile for Oauth 2.0
	// Authorization Grant based authentication
	//   "OAUTH2_CLIENT_CREDENTIALS" - Oauth 2.0 Client Credentials Grant
	// Authentication
	//   "SSH_PUBLIC_KEY" - SSH Public Key Authentication
	//   "OAUTH2_AUTH_CODE_FLOW" - Oauth 2.0 Authorization Code Flow
	AuthType string `json:"authType,omitempty"`

	// Oauth2AuthCodeFlow: Oauth2AuthCodeFlow.
	Oauth2AuthCodeFlow *GoogleCloudConnectorsV1AuthConfigOauth2AuthCodeFlow `json:"oauth2AuthCodeFlow,omitempty"`

	// Oauth2ClientCredentials: Oauth2ClientCredentials.
	Oauth2ClientCredentials *GoogleCloudConnectorsV1AuthConfigOauth2ClientCredentials `json:"oauth2ClientCredentials,omitempty"`

	// Oauth2JwtBearer: Oauth2JwtBearer.
	Oauth2JwtBearer *GoogleCloudConnectorsV1AuthConfigOauth2JwtBearer `json:"oauth2JwtBearer,omitempty"`

	// SshPublicKey: SSH Public Key.
	SshPublicKey *GoogleCloudConnectorsV1AuthConfigSshPublicKey `json:"sshPublicKey,omitempty"`

	// UserPassword: UserPassword.
	UserPassword *GoogleCloudConnectorsV1AuthConfigUserPassword `json:"userPassword,omitempty"`

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

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

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

// GoogleCloudConnectorsV1AuthConfigOauth2AuthCodeFlow: Parameters to
// support Oauth 2.0 Auth Code Grant Authentication. See
// https://www.rfc-editor.org/rfc/rfc6749#section-1.3.1 for more
// details.
type GoogleCloudConnectorsV1AuthConfigOauth2AuthCodeFlow struct {
	// AuthCode: Authorization code to be exchanged for access and refresh
	// tokens.
	AuthCode string `json:"authCode,omitempty"`

	// AuthUri: Auth URL for Authorization Code Flow
	AuthUri string `json:"authUri,omitempty"`

	// ClientId: Client ID for user-provided OAuth app.
	ClientId string `json:"clientId,omitempty"`

	// ClientSecret: Client secret for user-provided OAuth app.
	ClientSecret *GoogleCloudConnectorsV1Secret `json:"clientSecret,omitempty"`

	// EnablePkce: Whether to enable PKCE when the user performs the auth
	// code flow.
	EnablePkce bool `json:"enablePkce,omitempty"`

	// PkceVerifier: PKCE verifier to be used during the auth code exchange.
	PkceVerifier string `json:"pkceVerifier,omitempty"`

	// RedirectUri: Redirect URI to be provided during the auth code
	// exchange.
	RedirectUri string `json:"redirectUri,omitempty"`

	// Scopes: Scopes the connection will request when the user performs the
	// auth code flow.
	Scopes []string `json:"scopes,omitempty"`

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

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

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

// GoogleCloudConnectorsV1AuthConfigOauth2ClientCredentials: Parameters
// to support Oauth 2.0 Client Credentials Grant Authentication. See
// https://tools.ietf.org/html/rfc6749#section-1.3.4 for more details.
type GoogleCloudConnectorsV1AuthConfigOauth2ClientCredentials struct {
	// ClientId: The client identifier.
	ClientId string `json:"clientId,omitempty"`

	// ClientSecret: Secret version reference containing the client secret.
	ClientSecret *GoogleCloudConnectorsV1Secret `json:"clientSecret,omitempty"`

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

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

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

// GoogleCloudConnectorsV1AuthConfigOauth2JwtBearer: Parameters to
// support JSON Web Token (JWT) Profile for Oauth 2.0 Authorization
// Grant based authentication. See https://tools.ietf.org/html/rfc7523
// for more details.
type GoogleCloudConnectorsV1AuthConfigOauth2JwtBearer struct {
	// ClientKey: Secret version reference containing a PKCS#8 PEM-encoded
	// private key associated with the Client Certificate. This private key
	// will be used to sign JWTs used for the jwt-bearer authorization
	// grant. Specified in the form as: `projects/*/secrets/*/versions/*`.
	ClientKey *GoogleCloudConnectorsV1Secret `json:"clientKey,omitempty"`

	// JwtClaims: JwtClaims providers fields to generate the token.
	JwtClaims *GoogleCloudConnectorsV1AuthConfigOauth2JwtBearerJwtClaims `json:"jwtClaims,omitempty"`

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

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

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

// GoogleCloudConnectorsV1AuthConfigOauth2JwtBearerJwtClaims: JWT claims
// used for the jwt-bearer authorization grant.
type GoogleCloudConnectorsV1AuthConfigOauth2JwtBearerJwtClaims struct {
	// Audience: Value for the "aud" claim.
	Audience string `json:"audience,omitempty"`

	// Issuer: Value for the "iss" claim.
	Issuer string `json:"issuer,omitempty"`

	// Subject: Value for the "sub" claim.
	Subject string `json:"subject,omitempty"`

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

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

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

// GoogleCloudConnectorsV1AuthConfigSshPublicKey: Parameters to support
// Ssh public key Authentication.
type GoogleCloudConnectorsV1AuthConfigSshPublicKey struct {
	// CertType: Format of SSH Client cert.
	CertType string `json:"certType,omitempty"`

	// SshClientCert: SSH Client Cert. It should contain both public and
	// private key.
	SshClientCert *GoogleCloudConnectorsV1Secret `json:"sshClientCert,omitempty"`

	// SshClientCertPass: Password (passphrase) for ssh client certificate
	// if it has one.
	SshClientCertPass *GoogleCloudConnectorsV1Secret `json:"sshClientCertPass,omitempty"`

	// Username: The user account used to authenticate.
	Username string `json:"username,omitempty"`

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

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

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

// GoogleCloudConnectorsV1AuthConfigUserPassword: Parameters to support
// Username and Password Authentication.
type GoogleCloudConnectorsV1AuthConfigUserPassword struct {
	// Password: Secret version reference containing the password.
	Password *GoogleCloudConnectorsV1Secret `json:"password,omitempty"`

	// Username: Username.
	Username string `json:"username,omitempty"`

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

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

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

// GoogleCloudConnectorsV1ConfigVariable: ConfigVariable represents a
// configuration variable present in a Connection. or AuthConfig.
type GoogleCloudConnectorsV1ConfigVariable struct {
	// BoolValue: Value is a bool.
	BoolValue bool `json:"boolValue,omitempty"`

	// IntValue: Value is an integer
	IntValue int64 `json:"intValue,omitempty,string"`

	// Key: Key of the config variable.
	Key string `json:"key,omitempty"`

	// KeyValue: Value is a Encryption Key.
	KeyValue *GoogleCloudConnectorsV1EncryptionKey `json:"keyValue,omitempty"`

	// SecretValue: Value is a secret.
	SecretValue *GoogleCloudConnectorsV1Secret `json:"secretValue,omitempty"`

	// StringValue: Value is a string.
	StringValue string `json:"stringValue,omitempty"`

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

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

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

// GoogleCloudConnectorsV1Connection: Connection represents an instance
// of connector.
type GoogleCloudConnectorsV1Connection struct {
	// AuthConfig: Optional. Configuration for establishing the connection's
	// authentication with an external system.
	AuthConfig *GoogleCloudConnectorsV1AuthConfig `json:"authConfig,omitempty"`

	// ConfigVariables: Optional. Configuration for configuring the
	// connection with an external system.
	ConfigVariables []*GoogleCloudConnectorsV1ConfigVariable `json:"configVariables,omitempty"`

	// ConnectionRevision: Output only. Connection revision. This field is
	// only updated when the connection is created or updated by User.
	ConnectionRevision int64 `json:"connectionRevision,omitempty,string"`

	// ConnectorVersion: Required. Connector version on which the connection
	// is created. The format is:
	// projects/*/locations/*/providers/*/connectors/*/versions/* Only
	// global location is supported for ConnectorVersion resource.
	ConnectorVersion string `json:"connectorVersion,omitempty"`

	// ConnectorVersionLaunchStage: Output only. Flag to mark the version
	// indicating the launch stage.
	//
	// Possible values:
	//   "LAUNCH_STAGE_UNSPECIFIED" - LAUNCH_STAGE_UNSPECIFIED.
	//   "PREVIEW" - PREVIEW.
	//   "GA" - GA.
	//   "DEPRECATED" - DEPRECATED.
	//   "PRIVATE_PREVIEW" - PRIVATE_PREVIEW.
	ConnectorVersionLaunchStage string `json:"connectorVersionLaunchStage,omitempty"`

	// CreateTime: Output only. Created time.
	CreateTime string `json:"createTime,omitempty"`

	// Description: Optional. Description of the resource.
	Description string `json:"description,omitempty"`

	// DestinationConfigs: Optional. Configuration of the Connector's
	// destination. Only accepted for Connectors that accepts user defined
	// destination(s).
	DestinationConfigs []*GoogleCloudConnectorsV1DestinationConfig `json:"destinationConfigs,omitempty"`

	// EnvoyImageLocation: Output only. GCR location where the envoy image
	// is stored. formatted like: gcr.io/{bucketName}/{imageName}
	EnvoyImageLocation string `json:"envoyImageLocation,omitempty"`

	// ImageLocation: Output only. GCR location where the runtime image is
	// stored. formatted like: gcr.io/{bucketName}/{imageName}
	ImageLocation string `json:"imageLocation,omitempty"`

	// Labels: Optional. Resource labels to represent user-provided
	// metadata. Refer to cloud documentation on labels for more details.
	// https://cloud.google.com/compute/docs/labeling-resources
	Labels map[string]string `json:"labels,omitempty"`

	// LockConfig: Optional. Configuration that indicates whether or not the
	// Connection can be edited.
	LockConfig *GoogleCloudConnectorsV1LockConfig `json:"lockConfig,omitempty"`

	// LogConfig: Optional. Log configuration for the connection.
	LogConfig *GoogleCloudConnectorsV1LogConfig `json:"logConfig,omitempty"`

	// Name: Output only. Resource name of the Connection. Format:
	// projects/{project}/locations/{location}/connections/{connection}
	Name string `json:"name,omitempty"`

	// NodeConfig: Optional. Node configuration for the connection.
	NodeConfig *GoogleCloudConnectorsV1NodeConfig `json:"nodeConfig,omitempty"`

	// ServiceAccount: Optional. Service account needed for runtime plane to
	// access GCP resources.
	ServiceAccount string `json:"serviceAccount,omitempty"`

	// ServiceDirectory: Output only. The name of the Service Directory
	// service name. Used for Private Harpoon to resolve the ILB address.
	// e.g.
	// "projects/cloud-connectors-e2e-testing/locations/us-central1/namespace
	// s/istio-system/services/istio-ingressgateway-connectors"
	ServiceDirectory string `json:"serviceDirectory,omitempty"`

	// SslConfig: Optional. Ssl config of a connection
	SslConfig *GoogleCloudConnectorsV1SslConfig `json:"sslConfig,omitempty"`

	// Status: Output only. Current status of the connection.
	Status *GoogleCloudConnectorsV1ConnectionStatus `json:"status,omitempty"`

	// SubscriptionType: Output only. This subscription type enum states the
	// subscription type of the project.
	//
	// Possible values:
	//   "SUBSCRIPTION_TYPE_UNSPECIFIED" - Unspecified subscription type.
	//   "PAY_G" - PayG subscription.
	//   "PAID" - Paid Subscription.
	SubscriptionType string `json:"subscriptionType,omitempty"`

	// Suspended: Optional. Suspended indicates if a user has suspended a
	// connection or not.
	Suspended bool `json:"suspended,omitempty"`

	// UpdateTime: Output only. Updated time.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

// GoogleCloudConnectorsV1ConnectionStatus: ConnectionStatus indicates
// the state of the connection.
type GoogleCloudConnectorsV1ConnectionStatus struct {
	// Description: Description.
	Description string `json:"description,omitempty"`

	// State: State.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Connection does not have a state yet.
	//   "CREATING" - Connection is being created.
	//   "ACTIVE" - Connection is running and ready for requests.
	//   "INACTIVE" - Connection is stopped.
	//   "DELETING" - Connection is being deleted.
	//   "UPDATING" - Connection is being updated.
	//   "ERROR" - Connection is not running due to an error.
	//   "AUTHORIZATION_REQUIRED" - Connection is not running because the
	// authorization configuration is not complete.
	State string `json:"state,omitempty"`

	// Status: Status provides detailed information for the state.
	Status string `json:"status,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *GoogleCloudConnectorsV1ConnectionStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudConnectorsV1ConnectionStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleCloudConnectorsV1Destination struct {
	// Host: For publicly routable host.
	Host string `json:"host,omitempty"`

	// Port: The port is the target port number that is accepted by the
	// destination.
	Port int64 `json:"port,omitempty"`

	// ServiceAttachment: PSC service attachments. Format:
	// projects/*/regions/*/serviceAttachments/*
	ServiceAttachment string `json:"serviceAttachment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Host") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *GoogleCloudConnectorsV1Destination) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudConnectorsV1Destination
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudConnectorsV1DestinationConfig: Define the Connectors
// target endpoint.
type GoogleCloudConnectorsV1DestinationConfig struct {
	// Destinations: The destinations for the key.
	Destinations []*GoogleCloudConnectorsV1Destination `json:"destinations,omitempty"`

	// Key: The key is the destination identifier that is supported by the
	// Connector.
	Key string `json:"key,omitempty"`

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

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

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

// GoogleCloudConnectorsV1EncryptionKey: Encryption Key value.
type GoogleCloudConnectorsV1EncryptionKey struct {
	// KmsKeyName: The [KMS key name] with which the content of the
	// Operation is encrypted. The expected format:
	// `projects/*/locations/*/keyRings/*/cryptoKeys/*`. Will be empty
	// string if google managed.
	KmsKeyName string `json:"kmsKeyName,omitempty"`

	// Type: Type.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Value type is not specified.
	//   "GOOGLE_MANAGED" - Google Managed.
	//   "CUSTOMER_MANAGED" - Customer Managed.
	Type string `json:"type,omitempty"`

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

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

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

// GoogleCloudConnectorsV1LockConfig: Determines whether or no a
// connection is locked. If locked, a reason must be specified.
type GoogleCloudConnectorsV1LockConfig struct {
	// Locked: Indicates whether or not the connection is locked.
	Locked bool `json:"locked,omitempty"`

	// Reason: Describes why a connection is locked.
	Reason string `json:"reason,omitempty"`

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

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

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

// GoogleCloudConnectorsV1LogConfig: Log configuration for the
// connection.
type GoogleCloudConnectorsV1LogConfig struct {
	// Enabled: Enabled represents whether logging is enabled or not for a
	// connection.
	Enabled bool `json:"enabled,omitempty"`

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

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

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

// GoogleCloudConnectorsV1NodeConfig: Node configuration for the
// connection.
type GoogleCloudConnectorsV1NodeConfig struct {
	// MaxNodeCount: Maximum number of nodes in the runtime nodes.
	MaxNodeCount int64 `json:"maxNodeCount,omitempty"`

	// MinNodeCount: Minimum number of nodes in the runtime nodes.
	MinNodeCount int64 `json:"minNodeCount,omitempty"`

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

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

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

// GoogleCloudConnectorsV1Secret: Secret provides a reference to entries
// in Secret Manager.
type GoogleCloudConnectorsV1Secret struct {
	// SecretVersion: The resource name of the secret version in the format,
	// format as: `projects/*/secrets/*/versions/*`.
	SecretVersion string `json:"secretVersion,omitempty"`

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

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

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

// GoogleCloudConnectorsV1SslConfig: SSL Configuration of a connection
type GoogleCloudConnectorsV1SslConfig struct {
	// AdditionalVariables: Additional SSL related field values
	AdditionalVariables []*GoogleCloudConnectorsV1ConfigVariable `json:"additionalVariables,omitempty"`

	// ClientCertType: Type of Client Cert (PEM/JKS/.. etc.)
	//
	// Possible values:
	//   "CERT_TYPE_UNSPECIFIED" - Cert type unspecified.
	//   "PEM" - Privacy Enhanced Mail (PEM) Type
	ClientCertType string `json:"clientCertType,omitempty"`

	// ClientCertificate: Client Certificate
	ClientCertificate *GoogleCloudConnectorsV1Secret `json:"clientCertificate,omitempty"`

	// ClientPrivateKey: Client Private Key
	ClientPrivateKey *GoogleCloudConnectorsV1Secret `json:"clientPrivateKey,omitempty"`

	// ClientPrivateKeyPass: Secret containing the passphrase protecting the
	// Client Private Key
	ClientPrivateKeyPass *GoogleCloudConnectorsV1Secret `json:"clientPrivateKeyPass,omitempty"`

	// PrivateServerCertificate: Private Server Certificate. Needs to be
	// specified if trust model is `PRIVATE`.
	PrivateServerCertificate *GoogleCloudConnectorsV1Secret `json:"privateServerCertificate,omitempty"`

	// ServerCertType: Type of Server Cert (PEM/JKS/.. etc.)
	//
	// Possible values:
	//   "CERT_TYPE_UNSPECIFIED" - Cert type unspecified.
	//   "PEM" - Privacy Enhanced Mail (PEM) Type
	ServerCertType string `json:"serverCertType,omitempty"`

	// TrustModel: Trust Model of the SSL connection
	//
	// Possible values:
	//   "PUBLIC" - Public Trust Model. Takes the Default Java trust store.
	//   "PRIVATE" - Private Trust Model. Takes custom/private trust store.
	//   "INSECURE" - Insecure Trust Model. Accept all certificates.
	TrustModel string `json:"trustModel,omitempty"`

	// Type: Controls the ssl type for the given connector version.
	//
	// Possible values:
	//   "SSL_TYPE_UNSPECIFIED" - No SSL configuration required.
	//   "TLS" - TLS Handshake
	//   "MTLS" - mutual TLS (MTLS) Handshake
	Type string `json:"type,omitempty"`

	// UseSsl: Bool for enabling SSL
	UseSsl bool `json:"useSsl,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaAccessToken: The access token
// represents the authorization of a specific application to access
// specific parts of a user’s data.
type GoogleCloudIntegrationsV1alphaAccessToken struct {
	// AccessToken: The access token encapsulating the security identity of
	// a process or thread.
	AccessToken string `json:"accessToken,omitempty"`

	// AccessTokenExpireTime: Required. The approximate time until the
	// access token retrieved is valid.
	AccessTokenExpireTime string `json:"accessTokenExpireTime,omitempty"`

	// RefreshToken: If the access token will expire, use the refresh token
	// to obtain another access token.
	RefreshToken string `json:"refreshToken,omitempty"`

	// RefreshTokenExpireTime: The approximate time until the refresh token
	// retrieved is valid.
	RefreshTokenExpireTime string `json:"refreshTokenExpireTime,omitempty"`

	// TokenType: Only support "bearer" token in v1 as bearer token is the
	// predominant type used with OAuth 2.0.
	TokenType string `json:"tokenType,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaAttemptStats: Status for the execution
// attempt.
type GoogleCloudIntegrationsV1alphaAttemptStats struct {
	// EndTime: The end time of the event execution for current attempt.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: The start time of the event execution for current attempt.
	// This could be in the future if it's been scheduled.
	StartTime string `json:"startTime,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaAuthConfig: The AuthConfig resource use
// to hold channels and connection config data.
type GoogleCloudIntegrationsV1alphaAuthConfig struct {
	// CertificateId: Certificate id for client certificate
	CertificateId string `json:"certificateId,omitempty"`

	// CreateTime: Output only. The timestamp when the auth config is
	// created.
	CreateTime string `json:"createTime,omitempty"`

	// CreatorEmail: The creator's email address. Generated based on the End
	// User Credentials/LOAS role of the user making the call.
	CreatorEmail string `json:"creatorEmail,omitempty"`

	// CredentialType: Credential type of the encrypted credential.
	//
	// Possible values:
	//   "CREDENTIAL_TYPE_UNSPECIFIED" - Unspecified credential type
	//   "USERNAME_AND_PASSWORD" - Regular username/password pair.
	//   "API_KEY" - API key.
	//   "OAUTH2_AUTHORIZATION_CODE" - OAuth 2.0 Authorization Code Grant
	// Type.
	//   "OAUTH2_IMPLICIT" - OAuth 2.0 Implicit Grant Type.
	//   "OAUTH2_CLIENT_CREDENTIALS" - OAuth 2.0 Client Credentials Grant
	// Type.
	//   "OAUTH2_RESOURCE_OWNER_CREDENTIALS" - OAuth 2.0 Resource Owner
	// Credentials Grant Type.
	//   "JWT" - JWT Token.
	//   "AUTH_TOKEN" - Auth Token, e.g. bearer token.
	//   "SERVICE_ACCOUNT" - Service Account which can be used to generate
	// token for authentication.
	//   "CLIENT_CERTIFICATE_ONLY" - Client Certificate only.
	//   "OIDC_TOKEN" - Google OIDC ID Token
	CredentialType string `json:"credentialType,omitempty"`

	// DecryptedCredential: Raw auth credentials.
	DecryptedCredential *GoogleCloudIntegrationsV1alphaCredential `json:"decryptedCredential,omitempty"`

	// Description: A description of the auth config.
	Description string `json:"description,omitempty"`

	// DisplayName: The name of the auth config.
	DisplayName string `json:"displayName,omitempty"`

	// EncryptedCredential: Auth credential encrypted by Cloud KMS. Can be
	// decrypted as Credential with proper KMS key.
	EncryptedCredential string `json:"encryptedCredential,omitempty"`

	// ExpiryNotificationDuration: User can define the time to receive
	// notification after which the auth config becomes invalid. Support up
	// to 30 days. Support granularity in hours.
	ExpiryNotificationDuration []string `json:"expiryNotificationDuration,omitempty"`

	// LastModifierEmail: The last modifier's email address. Generated based
	// on the End User Credentials/LOAS role of the user making the call.
	LastModifierEmail string `json:"lastModifierEmail,omitempty"`

	// Name: Resource name of the SFDC instance
	// projects/{project}/locations/{location}/authConfigs/{authConfig}.
	Name string `json:"name,omitempty"`

	// OverrideValidTime: User provided expiry time to override. For the
	// example of Salesforce, username/password credentials can be valid for
	// 6 months depending on the instance settings.
	OverrideValidTime string `json:"overrideValidTime,omitempty"`

	// Reason: The reason / details of the current status.
	Reason string `json:"reason,omitempty"`

	// State: The status of the auth config.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Status not specified.
	//   "VALID" - Valid Auth config.
	//   "INVALID" - General invalidity, if it doesn't fits in the detailed
	// issue below.
	//   "SOFT_DELETED" - Auth config soft deleted.
	//   "EXPIRED" - Auth config expired.
	//   "UNAUTHORIZED" - Auth config unauthorized.
	//   "UNSUPPORTED" - Auth config not supported.
	State string `json:"state,omitempty"`

	// UpdateTime: Output only. The timestamp when the auth config is
	// modified.
	UpdateTime string `json:"updateTime,omitempty"`

	// ValidTime: The time until the auth config is valid. Empty or max
	// value is considered the auth config won't expire.
	ValidTime string `json:"validTime,omitempty"`

	// Visibility: The visibility of the auth config.
	//
	// Possible values:
	//   "AUTH_CONFIG_VISIBILITY_UNSPECIFIED" - Visibility not specified.
	//   "PRIVATE" - Profile visible to the creator only.
	//   "CLIENT_VISIBLE" - Profile visible within the client.
	Visibility string `json:"visibility,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaAuthToken: The credentials to
// authenticate a user agent with a server that is put in HTTP
// Authorization request header.
type GoogleCloudIntegrationsV1alphaAuthToken struct {
	// Token: The token for the auth type.
	Token string `json:"token,omitempty"`

	// Type: Authentication type, e.g. "Basic", "Bearer", etc.
	Type string `json:"type,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaBooleanParameterArray: This message
// only contains a field of boolean array.
type GoogleCloudIntegrationsV1alphaBooleanParameterArray struct {
	// BooleanValues: Boolean array.
	BooleanValues []bool `json:"booleanValues,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaCancelExecutionRequest: Request for
// cancelling an execution.
type GoogleCloudIntegrationsV1alphaCancelExecutionRequest struct {
}

// GoogleCloudIntegrationsV1alphaCancelExecutionResponse: Response for
// cancelling an execution.
type GoogleCloudIntegrationsV1alphaCancelExecutionResponse struct {
	// IsCanceled: True if cancellation performed successfully
	IsCanceled bool `json:"isCanceled,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaCertificate: The certificate definition
type GoogleCloudIntegrationsV1alphaCertificate struct {
	// CertificateStatus: Status of the certificate
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Unspecified certificate status
	//   "ACTIVE" - Certificate in active state will be able to use
	//   "EXPIRED" - Certificate in expired state needs to be updated
	CertificateStatus string `json:"certificateStatus,omitempty"`

	// CredentialId: Immutable. Credential id that will be used to register
	// with trawler INTERNAL_ONLY
	CredentialId string `json:"credentialId,omitempty"`

	// Description: Description of the certificate
	Description string `json:"description,omitempty"`

	// DisplayName: Name of the certificate
	DisplayName string `json:"displayName,omitempty"`

	// Name: Output only. Auto generated primary key
	Name string `json:"name,omitempty"`

	// RawCertificate: Input only. Raw client certificate which would be
	// registered with trawler
	RawCertificate *GoogleCloudIntegrationsV1alphaClientCertificate `json:"rawCertificate,omitempty"`

	// RequestorId: Immutable. Requestor ID to be used to register
	// certificate with trawler
	RequestorId string `json:"requestorId,omitempty"`

	// ValidEndTime: Output only. The timestamp after which certificate will
	// expire
	ValidEndTime string `json:"validEndTime,omitempty"`

	// ValidStartTime: Output only. The timestamp after which certificate
	// will be valid
	ValidStartTime string `json:"validStartTime,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaClientCertificate: Contains client
// certificate information
type GoogleCloudIntegrationsV1alphaClientCertificate struct {
	// EncryptedPrivateKey: The ssl certificate encoded in PEM format. This
	// string must include the begin header and end footer lines. For
	// example, -----BEGIN CERTIFICATE-----
	// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
	// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
	// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
	// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
	// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
	// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
	// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
	// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
	// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
	// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
	// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
	// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
	// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
	EncryptedPrivateKey string `json:"encryptedPrivateKey,omitempty"`

	// Passphrase: 'passphrase' should be left unset if private key is not
	// encrypted. Note that 'passphrase' is not the password for web server,
	// but an extra layer of security to protected private key.
	Passphrase string `json:"passphrase,omitempty"`

	// SslCertificate: The ssl certificate encoded in PEM format. This
	// string must include the begin header and end footer lines. For
	// example, -----BEGIN CERTIFICATE-----
	// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
	// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
	// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
	// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
	// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
	// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
	// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
	// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
	// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
	// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
	// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
	// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
	// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
	SslCertificate string `json:"sslCertificate,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaCloudSchedulerConfig: Cloud Scheduler
// Trigger configuration
type GoogleCloudIntegrationsV1alphaCloudSchedulerConfig struct {
	// CronTab: Required. The cron tab of cloud scheduler trigger.
	CronTab string `json:"cronTab,omitempty"`

	// ErrorMessage: Optional. When the job was deleted from Pantheon UI,
	// error_message will be populated when Get/List integrations
	ErrorMessage string `json:"errorMessage,omitempty"`

	// Location: Required. The location where associated cloud scheduler job
	// will be created
	Location string `json:"location,omitempty"`

	// ServiceAccountEmail: Required. Service account used by Cloud
	// Scheduler to trigger the integration at scheduled time
	ServiceAccountEmail string `json:"serviceAccountEmail,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaConnectionSchemaMetadata: Metadata of
// runtime connection schema.
type GoogleCloudIntegrationsV1alphaConnectionSchemaMetadata struct {
	// Actions: List of actions.
	Actions []string `json:"actions,omitempty"`

	// Entities: List of entity names.
	Entities []string `json:"entities,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaCoordinate: Configuration detail of
// coordinate, it used for UI
type GoogleCloudIntegrationsV1alphaCoordinate struct {
	// X: Required. X axis of the coordinate
	X int64 `json:"x,omitempty"`

	// Y: Required. Y axis of the coordinate
	Y int64 `json:"y,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectRequest: Request
// for CreateAppsScriptProject rpc call.
type GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectRequest struct {
	// AppsScriptProject: The name of the Apps Script project to be created.
	AppsScriptProject string `json:"appsScriptProject,omitempty"`

	// AuthConfigId: The auth config id necessary to fetch the necessary
	// credentials to create the project for external clients
	AuthConfigId string `json:"authConfigId,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectResponse:
// Response for CreateAppsScriptProject rpc call.
type GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectResponse struct {
	// ProjectId: The created AppsScriptProject ID.
	ProjectId string `json:"projectId,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaCredential: Defines parameters for a
// single, canonical credential.
type GoogleCloudIntegrationsV1alphaCredential struct {
	// AuthToken: Auth token credential
	AuthToken *GoogleCloudIntegrationsV1alphaAuthToken `json:"authToken,omitempty"`

	// CredentialType: Credential type associated with auth config.
	//
	// Possible values:
	//   "CREDENTIAL_TYPE_UNSPECIFIED" - Unspecified credential type
	//   "USERNAME_AND_PASSWORD" - Regular username/password pair.
	//   "API_KEY" - API key.
	//   "OAUTH2_AUTHORIZATION_CODE" - OAuth 2.0 Authorization Code Grant
	// Type.
	//   "OAUTH2_IMPLICIT" - OAuth 2.0 Implicit Grant Type.
	//   "OAUTH2_CLIENT_CREDENTIALS" - OAuth 2.0 Client Credentials Grant
	// Type.
	//   "OAUTH2_RESOURCE_OWNER_CREDENTIALS" - OAuth 2.0 Resource Owner
	// Credentials Grant Type.
	//   "JWT" - JWT Token.
	//   "AUTH_TOKEN" - Auth Token, e.g. bearer token.
	//   "SERVICE_ACCOUNT" - Service Account which can be used to generate
	// token for authentication.
	//   "CLIENT_CERTIFICATE_ONLY" - Client Certificate only.
	//   "OIDC_TOKEN" - Google OIDC ID Token
	CredentialType string `json:"credentialType,omitempty"`

	// Jwt: JWT credential
	Jwt *GoogleCloudIntegrationsV1alphaJwt `json:"jwt,omitempty"`

	// Oauth2AuthorizationCode: The api_key and oauth2_implicit are not
	// covered in v1 and will be picked up once v1 is implemented. ApiKey
	// api_key = 3; OAuth2 authorization code credential
	Oauth2AuthorizationCode *GoogleCloudIntegrationsV1alphaOAuth2AuthorizationCode `json:"oauth2AuthorizationCode,omitempty"`

	// Oauth2ClientCredentials: OAuth2Implicit oauth2_implicit = 5; OAuth2
	// client credentials
	Oauth2ClientCredentials *GoogleCloudIntegrationsV1alphaOAuth2ClientCredentials `json:"oauth2ClientCredentials,omitempty"`

	// Oauth2ResourceOwnerCredentials: OAuth2 resource owner credentials
	Oauth2ResourceOwnerCredentials *GoogleCloudIntegrationsV1alphaOAuth2ResourceOwnerCredentials `json:"oauth2ResourceOwnerCredentials,omitempty"`

	// OidcToken: Google OIDC ID Token
	OidcToken *GoogleCloudIntegrationsV1alphaOidcToken `json:"oidcToken,omitempty"`

	// ServiceAccountCredentials: Service account credential
	ServiceAccountCredentials *GoogleCloudIntegrationsV1alphaServiceAccountCredentials `json:"serviceAccountCredentials,omitempty"`

	// UsernameAndPassword: Username and password credential
	UsernameAndPassword *GoogleCloudIntegrationsV1alphaUsernameAndPassword `json:"usernameAndPassword,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaDoubleParameterArray: This message only
// contains a field of double number array.
type GoogleCloudIntegrationsV1alphaDoubleParameterArray struct {
	// DoubleValues: Double number array.
	DoubleValues []float64 `json:"doubleValues,omitempty"`

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

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

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

func (s *GoogleCloudIntegrationsV1alphaDoubleParameterArray) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudIntegrationsV1alphaDoubleParameterArray
	var s1 struct {
		DoubleValues []gensupport.JSONFloat64 `json:"doubleValues"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DoubleValues = make([]float64, len(s1.DoubleValues))
	for i := range s1.DoubleValues {
		s.DoubleValues[i] = float64(s1.DoubleValues[i])
	}
	return nil
}

// GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse:
// Response for DownloadIntegrationVersion.
type GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse struct {
	// Content: String representation of the integration version.
	Content string `json:"content,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaEnumerateConnectorPlatformRegionsRespons
// e: Response containing all provisioned regions for Connector
// Platform.
type GoogleCloudIntegrationsV1alphaEnumerateConnectorPlatformRegionsResponse struct {
	// Regions: All regions where Connector Platform is provisioned.
	Regions []string `json:"regions,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaErrorCatcherConfig: Configuration
// detail of a error catch task
type GoogleCloudIntegrationsV1alphaErrorCatcherConfig struct {
	// Description: Optional. User-provided description intended to give
	// more business context about the error catcher config.
	Description string `json:"description,omitempty"`

	// ErrorCatcherId: Required. An error catcher id is string
	// representation for the error catcher config. Within a workflow,
	// error_catcher_id uniquely identifies an error catcher config among
	// all error catcher configs for the workflow
	ErrorCatcherId string `json:"errorCatcherId,omitempty"`

	// ErrorCatcherNumber: Required. A number to uniquely identify each
	// error catcher config within the workflow on UI.
	ErrorCatcherNumber string `json:"errorCatcherNumber,omitempty"`

	// Label: Optional. The user created label for a particular error
	// catcher. Optional.
	Label string `json:"label,omitempty"`

	// Position: Optional. Informs the front-end application where to draw
	// this error catcher config on the UI.
	Position *GoogleCloudIntegrationsV1alphaCoordinate `json:"position,omitempty"`

	// StartErrorTasks: Required. The set of start tasks that are to be
	// executed for the error catch flow
	StartErrorTasks []*GoogleCloudIntegrationsV1alphaNextTask `json:"startErrorTasks,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *GoogleCloudIntegrationsV1alphaErrorCatcherConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudIntegrationsV1alphaErrorCatcherConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudIntegrationsV1alphaEventParameter: This message is used
// for processing and persisting (when applicable) key value pair
// parameters for each event in the event bus.
type GoogleCloudIntegrationsV1alphaEventParameter struct {
	// Key: Key is used to retrieve the corresponding parameter value. This
	// should be unique for a given fired event. These parameters must be
	// predefined in the integration definition.
	Key string `json:"key,omitempty"`

	// Value: Values for the defined keys. Each value can either be string,
	// int, double or any proto message.
	Value *GoogleCloudIntegrationsV1alphaValueType `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *GoogleCloudIntegrationsV1alphaEventParameter) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudIntegrationsV1alphaEventParameter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudIntegrationsV1alphaExecuteEventRequest: Request for
// triggering an integration using event triggers.
type GoogleCloudIntegrationsV1alphaExecuteEventRequest struct {
	// CloudEvent: Required. Details about the trigger which is to be
	// executed and values for input variable to the integration.
	CloudEvent *IoCloudeventsV1CloudEvent `json:"cloudEvent,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaExecuteEventResponse: The response for
// executing an integration.
type GoogleCloudIntegrationsV1alphaExecuteEventResponse struct {
	// ExecutionId: The id of the execution corresponding to this run of
	// integration.
	ExecutionId string `json:"executionId,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaExecuteIntegrationsRequest: The request
// for executing an integration.
type GoogleCloudIntegrationsV1alphaExecuteIntegrationsRequest struct {
	// DoNotPropagateError: Optional. Flag to determine how to should
	// propagate errors. If this flag is set to be true, it will not throw
	// an exception. Instead, it will return a {@link
	// ExecuteIntegrationsResponse} with an execution id and error messages
	// as PostWithTriggerIdExecutionException in {@link EventParameters}.
	// The flag is set to be false by default.
	DoNotPropagateError bool `json:"doNotPropagateError,omitempty"`

	// ExecutionId: Optional. The id of the ON_HOLD execution to be resumed.
	ExecutionId string `json:"executionId,omitempty"`

	// InputParameters: Optional. Input parameters used by integration
	// execution.
	InputParameters map[string]GoogleCloudIntegrationsV1alphaValueType `json:"inputParameters,omitempty"`

	// ParameterEntries: Optional. Parameters are a part of Event and can be
	// used to communicate between different tasks that are part of the same
	// integration execution.
	ParameterEntries []*EnterpriseCrmFrontendsEventbusProtoParameterEntry `json:"parameterEntries,omitempty"`

	// Parameters: Optional. Passed in as parameters to each integration
	// execution. Redacted
	Parameters *EnterpriseCrmFrontendsEventbusProtoEventParameters `json:"parameters,omitempty"`

	// RequestId: Optional. This is used to de-dup incoming request: if the
	// duplicate request was detected, the response from the previous
	// execution is returned.
	RequestId string `json:"requestId,omitempty"`

	// TriggerId: Required. Matched against all {@link TriggerConfig}s
	// across all integrations. i.e.
	// TriggerConfig.trigger_id.equals(trigger_id). The trigger_id is in the
	// format of `api_trigger/TRIGGER_NAME`.
	TriggerId string `json:"triggerId,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse: The
// response for executing an integration.
type GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse struct {
	// EventParameters: Details for the integration that were executed.
	EventParameters *EnterpriseCrmFrontendsEventbusProtoEventParameters `json:"eventParameters,omitempty"`

	// ExecutionFailed: Is true if any execution in the integration failed.
	// False otherwise.
	ExecutionFailed bool `json:"executionFailed,omitempty"`

	// ExecutionId: The id of the execution corresponding to this run of
	// integration.
	ExecutionId string `json:"executionId,omitempty"`

	// OutputParameters: OUTPUT parameters in format of Map. Where Key is
	// the name of the parameter. Note: Name of the system generated
	// parameters are wrapped by backtick(`) to distinguish them from the
	// user defined parameters.
	OutputParameters googleapi.RawMessage `json:"outputParameters,omitempty"`

	// ParameterEntries: Parameters are a part of Event and can be used to
	// communicate between different tasks that are part of the same
	// integration execution.
	ParameterEntries []*EnterpriseCrmFrontendsEventbusProtoParameterEntry `json:"parameterEntries,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaExecution: The Execution resource
// contains detailed information of an individual integration execution.
type GoogleCloudIntegrationsV1alphaExecution struct {
	// CreateTime: Output only. Created time of the execution.
	CreateTime string `json:"createTime,omitempty"`

	// DirectSubExecutions: Direct sub executions of the following
	// Execution.
	DirectSubExecutions []*GoogleCloudIntegrationsV1alphaExecution `json:"directSubExecutions,omitempty"`

	// EventExecutionDetails: The execution info about this event.
	EventExecutionDetails *EnterpriseCrmEventbusProtoEventExecutionDetails `json:"eventExecutionDetails,omitempty"`

	// ExecutionDetails: Detailed info of this execution.
	ExecutionDetails *GoogleCloudIntegrationsV1alphaExecutionDetails `json:"executionDetails,omitempty"`

	// ExecutionMethod: The ways user posts this event.
	//
	// Possible values:
	//   "EXECUTION_METHOD_UNSPECIFIED" - Default value.
	//   "POST" - Sync post.
	//   "POST_TO_QUEUE" - Async post.
	//   "SCHEDULE" - Async post with schedule time.
	ExecutionMethod string `json:"executionMethod,omitempty"`

	// Name: Auto-generated primary key.
	Name string `json:"name,omitempty"`

	// RequestParameters: Event parameters come in as part of the request.
	RequestParameters map[string]GoogleCloudIntegrationsV1alphaValueType `json:"requestParameters,omitempty"`

	// RequestParams: Event parameters come in as part of the request.
	RequestParams []*EnterpriseCrmFrontendsEventbusProtoParameterEntry `json:"requestParams,omitempty"`

	// ResponseParameters: Event parameters returned as part of the
	// response.
	ResponseParameters map[string]GoogleCloudIntegrationsV1alphaValueType `json:"responseParameters,omitempty"`

	// ResponseParams: Event parameters come out as part of the response.
	ResponseParams []*EnterpriseCrmFrontendsEventbusProtoParameterEntry `json:"responseParams,omitempty"`

	// TriggerId: The trigger id of the integration trigger config. If both
	// trigger_id and client_id is present, the integration is executed from
	// the start tasks provided by the matching trigger config otherwise it
	// is executed from the default start tasks.
	TriggerId string `json:"triggerId,omitempty"`

	// UpdateTime: Output only. Last modified time of the execution.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaExecutionDetails: Contains the details
// of the execution info: this includes the tasks execution details plus
// the event execution statistics.
type GoogleCloudIntegrationsV1alphaExecutionDetails struct {
	// AttemptStats: List of Start and end time of the execution attempts.
	AttemptStats []*GoogleCloudIntegrationsV1alphaAttemptStats `json:"attemptStats,omitempty"`

	// ExecutionSnapshots: List of snapshots taken during the execution.
	ExecutionSnapshots []*GoogleCloudIntegrationsV1alphaExecutionSnapshot `json:"executionSnapshots,omitempty"`

	// State: Status of the execution.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Default.
	//   "PENDING" - Execution is scheduled and awaiting to be triggered.
	//   "PROCESSING" - Execution is processing.
	//   "SUCCEEDED" - Execution successfully finished. There's no more
	// change after this state.
	//   "FAILED" - Execution failed. There's no more change after this
	// state.
	//   "CANCELLED" - Execution canceled by user. There's no more change
	// after this state.
	//   "RETRY_ON_HOLD" - Execution failed and waiting for retry.
	//   "SUSPENDED" - Execution suspended and waiting for manual
	// intervention.
	State string `json:"state,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaExecutionSnapshot: Contains the
// snapshot of the execution for a given checkpoint.
type GoogleCloudIntegrationsV1alphaExecutionSnapshot struct {
	// CheckpointTaskNumber: Indicates "after which checkpoint task's
	// execution" this snapshot is taken.
	CheckpointTaskNumber string `json:"checkpointTaskNumber,omitempty"`

	// ExecutionSnapshotMetadata: Metadata of the execution snapshot.
	ExecutionSnapshotMetadata *GoogleCloudIntegrationsV1alphaExecutionSnapshotExecutionSnapshotMetadata `json:"executionSnapshotMetadata,omitempty"`

	// Params: Parameters used during the execution.
	Params map[string]GoogleCloudIntegrationsV1alphaValueType `json:"params,omitempty"`

	// TaskExecutionDetails: All of the task execution details at the given
	// point of time.
	TaskExecutionDetails []*GoogleCloudIntegrationsV1alphaTaskExecutionDetails `json:"taskExecutionDetails,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaExecutionSnapshotExecutionSnapshotMetada
// ta: Metadata of the execution snapshot.
type GoogleCloudIntegrationsV1alphaExecutionSnapshotExecutionSnapshotMetadata struct {
	// ExecutionAttempt: the execution attempt number this snapshot belongs
	// to.
	ExecutionAttempt int64 `json:"executionAttempt,omitempty"`

	// Task: the task name associated with this snapshot.
	Task string `json:"task,omitempty"`

	// TaskAttempt: the task attempt number this snapshot belongs to.
	TaskAttempt int64 `json:"taskAttempt,omitempty"`

	// TaskLabel: the task label associated with this snapshot. Could be
	// empty.
	TaskLabel string `json:"taskLabel,omitempty"`

	// TaskNumber: The task number associated with this snapshot.
	TaskNumber string `json:"taskNumber,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaFailurePolicy: Policy that defines the
// task retry logic and failure type. If no FailurePolicy is defined for
// a task, all its dependent tasks will not be executed (i.e, a
// `retry_strategy` of NONE will be applied).
type GoogleCloudIntegrationsV1alphaFailurePolicy struct {
	// IntervalTime: Required if retry_strategy is FIXED_INTERVAL or
	// LINEAR/EXPONENTIAL_BACKOFF/RESTART_INTEGRATION_WITH_BACKOFF. Defines
	// the initial interval in seconds for backoff.
	IntervalTime string `json:"intervalTime,omitempty"`

	// MaxRetries: Required if retry_strategy is FIXED_INTERVAL or
	// LINEAR/EXPONENTIAL_BACKOFF/RESTART_INTEGRATION_WITH_BACKOFF. Defines
	// the number of times the task will be retried if failed.
	MaxRetries int64 `json:"maxRetries,omitempty"`

	// RetryStrategy: Defines what happens to the task upon failure.
	//
	// Possible values:
	//   "RETRY_STRATEGY_UNSPECIFIED" - UNSPECIFIED.
	//   "IGNORE" - Ignores the failure of this task. The rest of the
	// integration will be executed Assuming this task succeeded.
	//   "NONE" - Causes a permanent failure of the task. However, if the
	// last task(s) of event was successfully completed despite the failure
	// of this task, it has no impact on the integration.
	//   "FATAL" - Causes a permanent failure of the event. It is different
	// from NONE because this will mark the event as FAILED by shutting down
	// the event execution.
	//   "FIXED_INTERVAL" - The task will be retried from the failed task
	// onwards after a fixed delay. A max-retry count is required to be
	// specified with this strategy. A jitter is added to each exponential
	// interval so that concurrently failing tasks of the same type do not
	// end up retrying after the exact same exponential interval.
	// max_retries and interval_in_seconds must be specified.
	//   "LINEAR_BACKOFF" - The task will be retried from the failed task
	// onwards after a fixed delay that linearly increases with each retry
	// attempt. A jitter is added to each exponential interval so that
	// concurrently failing tasks of the same type do not end up retrying
	// after the exact same exponential interval. A max-retry count is
	// required to be specified with this strategy. max_retries and
	// interval_in_seconds must be specified.
	//   "EXPONENTIAL_BACKOFF" - The task will be retried after an
	// exponentially increasing period of time with each failure. A jitter
	// is added to each exponential interval so that concurrently failing
	// tasks of the same type do not end up retrying after the exact same
	// exponential interval. A max-retry count is required to be specified
	// with this strategy. `max_retries` and `interval_in_seconds` must be
	// specified.
	//   "RESTART_INTEGRATION_WITH_BACKOFF" - The entire integration will be
	// restarted with the initial parameters that were set when the event
	// was fired. A max-retry count is required to be specified with this
	// strategy. `max_retries` and `interval_in_seconds` must be specified.
	RetryStrategy string `json:"retryStrategy,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaGenerateTokenResponse: Returns success
// or error message
type GoogleCloudIntegrationsV1alphaGenerateTokenResponse struct {
	// Message: The message that notifies the user if the request succeeded
	// or not.
	Message string `json:"message,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaIntParameterArray: This message only
// contains a field of integer array.
type GoogleCloudIntegrationsV1alphaIntParameterArray struct {
	// IntValues: Integer array.
	IntValues googleapi.Int64s `json:"intValues,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaIntegration: The integration
// definition.
type GoogleCloudIntegrationsV1alphaIntegration struct {
	// Active: Required. If any integration version is published.
	Active bool `json:"active,omitempty"`

	// Description: Optional.
	Description string `json:"description,omitempty"`

	// Name: Required. The resource name of the integration.
	Name string `json:"name,omitempty"`

	// UpdateTime: Output only. Auto-generated.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaIntegrationAlertConfig: Message to be
// used to configure custom alerting in the {@code EventConfig} protos
// for an event.
type GoogleCloudIntegrationsV1alphaIntegrationAlertConfig struct {
	// AggregationPeriod: The period over which the metric value should be
	// aggregated and evaluated. Format is , where integer should be a
	// positive integer and unit should be one of (s,m,h,d,w) meaning
	// (second, minute, hour, day, week). For an EXPECTED_MIN threshold,
	// this aggregation_period must be lesser than 24 hours.
	AggregationPeriod string `json:"aggregationPeriod,omitempty"`

	// AlertThreshold: For how many contiguous aggregation periods should
	// the expected min or max be violated for the alert to be fired.
	AlertThreshold int64 `json:"alertThreshold,omitempty"`

	// DisableAlert: Set to false by default. When set to true, the metrics
	// are not aggregated or pushed to Monarch for this integration alert.
	DisableAlert bool `json:"disableAlert,omitempty"`

	// DisplayName: Name of the alert. This will be displayed in the alert
	// subject. If set, this name should be unique within the scope of the
	// integration.
	DisplayName string `json:"displayName,omitempty"`

	// DurationThreshold: Should be specified only for *AVERAGE_DURATION and
	// *PERCENTILE_DURATION metrics. This member should be used to specify
	// what duration value the metrics should exceed for the alert to
	// trigger.
	DurationThreshold string `json:"durationThreshold,omitempty"`

	// MetricType: The type of metric.
	//
	// Possible values:
	//   "METRIC_TYPE_UNSPECIFIED" - The default value. Metric type should
	// always be set to one of the other non-default values, otherwise it
	// will result in an INVALID_ARGUMENT error.
	//   "EVENT_ERROR_RATE" - Specifies alerting on the rate of errors for
	// the enclosing integration.
	//   "EVENT_WARNING_RATE" - Specifies alerting on the rate of warnings
	// for the enclosing integration. Warnings use the same enum values as
	// errors.
	//   "TASK_ERROR_RATE" - Specifies alerting on the rate of errors for
	// any task in the enclosing integration.
	//   "TASK_WARNING_RATE" - Specifies alerting on the rate of warnings
	// for any task in the enclosing integration.
	//   "TASK_RATE" - Specifies alerting on the rate of executions over all
	// tasks in the enclosing integration.
	//   "EVENT_RATE" - Specifies alerting on the number of events executed
	// in the given aggregation_period.
	//   "EVENT_AVERAGE_DURATION" - Specifies alerting on the average
	// duration of executions for this integration.
	//   "EVENT_PERCENTILE_DURATION" - Specifies alerting on the duration
	// value of a particular percentile of integration executions. E.g. If
	// 10% or more of the integration executions have durations above 5
	// seconds, alert.
	//   "TASK_AVERAGE_DURATION" - Specifies alerting on the average
	// duration of any task in the enclosing integration,
	//   "TASK_PERCENTILE_DURATION" - Specifies alerting on the duration
	// value of a particular percentile of any task executions within the
	// enclosing integration. E.g. If 10% or more of the task executions in
	// the integration have durations above 5 seconds, alert.
	MetricType string `json:"metricType,omitempty"`

	// OnlyFinalAttempt: For either events or tasks, depending on the type
	// of alert, count only final attempts, not retries.
	OnlyFinalAttempt bool `json:"onlyFinalAttempt,omitempty"`

	// ThresholdType: The threshold type, whether lower(expected_min) or
	// upper(expected_max), for which this alert is being configured. If
	// value falls below expected_min or exceeds expected_max, an alert will
	// be fired.
	//
	// Possible values:
	//   "THRESHOLD_TYPE_UNSPECIFIED" - Default.
	//   "EXPECTED_MIN" - Note that this field will only trigger alerts if
	// the integration specifying it runs at least once in 24 hours (which
	// is our in-memory retention period for monarch streams). Also note
	// that `aggregation_period` for this alert configuration must be less
	// than 24 hours. Min value threshold.
	//   "EXPECTED_MAX" - Max value threshold.
	ThresholdType string `json:"thresholdType,omitempty"`

	// ThresholdValue: The metric value, above or below which the alert
	// should be triggered.
	ThresholdValue *GoogleCloudIntegrationsV1alphaIntegrationAlertConfigThresholdValue `json:"thresholdValue,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaIntegrationAlertConfigThresholdValue:
// The threshold value of the metric, above or below which the alert
// should be triggered. See EventAlertConfig or TaskAlertConfig for the
// different alert metric types in each case. For the *RATE metrics, one
// or both of these fields may be set. Zero is the default value and can
// be left at that. For *PERCENTILE_DURATION metrics, one or both of
// these fields may be set, and also, the duration threshold value
// should be specified in the threshold_duration_ms member below. For
// *AVERAGE_DURATION metrics, these fields should not be set at all. A
// different member, threshold_duration_ms, must be set in the
// EventAlertConfig or the TaskAlertConfig.
type GoogleCloudIntegrationsV1alphaIntegrationAlertConfigThresholdValue struct {
	// Absolute: Absolute value threshold.
	Absolute int64 `json:"absolute,omitempty,string"`

	// Percentage: Percentage threshold.
	Percentage int64 `json:"percentage,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaIntegrationParameter: Integration
// Parameter is defined in the integration config and are used to
// provide information about data types of the expected parameters and
// provide any default values if needed. They can also be used to add
// custom attributes. These are static in nature and should not be used
// for dynamic event definition.
type GoogleCloudIntegrationsV1alphaIntegrationParameter struct {
	// DataType: Type of the parameter.
	//
	// Possible values:
	//   "INTEGRATION_PARAMETER_DATA_TYPE_UNSPECIFIED" - Unspecified.
	//   "STRING_VALUE" - String.
	//   "INT_VALUE" - Integer.
	//   "DOUBLE_VALUE" - Double Number.
	//   "BOOLEAN_VALUE" - Boolean.
	//   "STRING_ARRAY" - String Array.
	//   "INT_ARRAY" - Integer Array.
	//   "DOUBLE_ARRAY" - Double Number Array.
	//   "BOOLEAN_ARRAY" - Boolean Array.
	//   "JSON_VALUE" - Json.
	//   "PROTO_VALUE" - Proto Value (Internal use only).
	//   "PROTO_ARRAY" - Proto Array (Internal use only).
	DataType string `json:"dataType,omitempty"`

	// DefaultValue: Default values for the defined keys. Each value can
	// either be string, int, double or any proto message or a serialized
	// object.
	DefaultValue *GoogleCloudIntegrationsV1alphaValueType `json:"defaultValue,omitempty"`

	// DisplayName: The name (without prefix) to be displayed in the UI for
	// this parameter. E.g. if the key is "foo.bar.myName", then the name
	// would be "myName".
	DisplayName string `json:"displayName,omitempty"`

	// InputOutputType: Specifies the input/output type for the parameter.
	//
	// Possible values:
	//   "IN_OUT_TYPE_UNSPECIFIED" - Default.
	//   "IN" - Input parameters for the integration. EventBus validates
	// that these parameters exist in the integrations before execution.
	//   "OUT" - Output Parameters for the integration. EventBus will only
	// return the integration parameters tagged with OUT in the response
	// back.
	//   "IN_OUT" - Input and Output Parameters. These can be used as both
	// input and output. EventBus will validate for the existence of these
	// parameters before execution and will also return this parameter back
	// in the response.
	InputOutputType string `json:"inputOutputType,omitempty"`

	// IsTransient: Whether this parameter is a transient parameter.
	IsTransient bool `json:"isTransient,omitempty"`

	// JsonSchema: This schema will be used to validate runtime JSON-typed
	// values of this parameter.
	JsonSchema string `json:"jsonSchema,omitempty"`

	// Key: Key is used to retrieve the corresponding parameter value. This
	// should be unique for a given fired event. These parameters must be
	// predefined in the integration definition.
	Key string `json:"key,omitempty"`

	// Producer: The identifier of the node (TaskConfig/TriggerConfig) this
	// parameter was produced by, if it is a transient param or a copy of an
	// input param.
	Producer string `json:"producer,omitempty"`

	// Searchable: Searchable in the execution log or not.
	Searchable bool `json:"searchable,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion:
// IntegrationTemplateVersion definition. An IntegrationTemplateVersion
// provides configurations required to construct an IntegrationVersion.
// It cannot be executed directly like an Integration. Users can create
// IntegrationTemplateVersions using Integrations. These Templates can
// be shared by users across GCP projects.
type GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion struct {
	// CreateTime: Output only. Auto-generated.
	CreateTime string `json:"createTime,omitempty"`

	// DatabasePersistencePolicy: Optional. Flag to disable database
	// persistence for execution data, including event execution info,
	// execution export info, execution metadata index and execution param
	// index.
	//
	// Possible values:
	//   "DATABASE_PERSISTENCE_POLICY_UNSPECIFIED" - Enables persistence for
	// all execution data.
	//   "DATABASE_PERSISTENCE_DISABLED" - Disables persistence for all
	// execution data.
	DatabasePersistencePolicy string `json:"databasePersistencePolicy,omitempty"`

	// Description: Optional. The templateversion description. Permitted
	// format is alphanumeric with underscores and no spaces.
	Description string `json:"description,omitempty"`

	// ErrorCatcherConfigs: Optional. Error Catch Task configuration for the
	// IntegrationTemplateVersion. It's optional.
	ErrorCatcherConfigs []*GoogleCloudIntegrationsV1alphaErrorCatcherConfig `json:"errorCatcherConfigs,omitempty"`

	// LastModifierEmail: Optional. The last modifier's email address.
	// Generated based on the End User Credentials/LOAS role of the user
	// making the call.
	LastModifierEmail string `json:"lastModifierEmail,omitempty"`

	// Name: Output only. Auto-generated primary key. Format:
	// projects/{project}/locations/{location}/products/{product}/integration
	// templates/{integrationtemplate}/versions/{version}
	Name string `json:"name,omitempty"`

	// ParentIntegrationVersionId: Optional. ID of the IntegrationVersion
	// that was used to create this IntegrationTemplateVersion
	ParentIntegrationVersionId string `json:"parentIntegrationVersionId,omitempty"`

	// SnapshotNumber: Output only. An increasing sequence that is set when
	// a new snapshot is created.
	SnapshotNumber int64 `json:"snapshotNumber,omitempty,string"`

	// Status: Optional. Generated by eventbus. User should not set it as an
	// input.
	//
	// Possible values:
	//   "UNKNOWN"
	//   "DRAFT"
	//   "ACTIVE"
	//   "ARCHIVED"
	//   "SNAPSHOT"
	Status string `json:"status,omitempty"`

	// TaskConfigs: Optional. Task configuration for the
	// IntegrationTemplateVersion. It's optional, but the
	// IntegrationTemplateVersion doesn't do anything without task_configs.
	TaskConfigs []*EnterpriseCrmFrontendsEventbusProtoTaskConfig `json:"taskConfigs,omitempty"`

	// Teardown: Optional. Contains a graph of tasks that will be executed
	// before putting the event in a terminal state
	// (SUCCEEDED/FAILED/FATAL), regardless of success or failure, similar
	// to "finally" in code.
	Teardown *EnterpriseCrmEventbusProtoTeardown `json:"teardown,omitempty"`

	// TemplateParameters: Optional. Parameters that are expected to be
	// passed to the IntegrationTemplateVersion when an event is triggered.
	// This consists of all the parameters that are expected in the
	// IntegrationTemplateVersion execution. This gives the user the ability
	// to provide default values, add information like PII and also provide
	// data types of each parameter.
	TemplateParameters *EnterpriseCrmFrontendsEventbusProtoWorkflowParameters `json:"templateParameters,omitempty"`

	// TriggerConfigs: Optional. Trigger configurations.
	TriggerConfigs []*EnterpriseCrmFrontendsEventbusProtoTriggerConfig `json:"triggerConfigs,omitempty"`

	// UpdateTime: Output only. Auto-generated.
	UpdateTime string `json:"updateTime,omitempty"`

	// UserLabel: Optional. A user-defined label that annotates an
	// integration version. Typically, this is only set when the integration
	// version is created.
	UserLabel string `json:"userLabel,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaIntegrationVersion: The integration
// version definition.
type GoogleCloudIntegrationsV1alphaIntegrationVersion struct {
	// CreateTime: Output only. Auto-generated.
	CreateTime string `json:"createTime,omitempty"`

	// DatabasePersistencePolicy: Optional. Flag to disable database
	// persistence for execution data, including event execution info,
	// execution export info, execution metadata index and execution param
	// index.
	//
	// Possible values:
	//   "DATABASE_PERSISTENCE_POLICY_UNSPECIFIED" - Enables persistence for
	// all execution data.
	//   "DATABASE_PERSISTENCE_DISABLED" - Disables persistence for all
	// execution data.
	DatabasePersistencePolicy string `json:"databasePersistencePolicy,omitempty"`

	// Description: Optional. The integration description.
	Description string `json:"description,omitempty"`

	// ErrorCatcherConfigs: Optional. Error Catch Task configuration for the
	// integration. It's optional.
	ErrorCatcherConfigs []*GoogleCloudIntegrationsV1alphaErrorCatcherConfig `json:"errorCatcherConfigs,omitempty"`

	// IntegrationParameters: Optional. Parameters that are expected to be
	// passed to the integration when an event is triggered. This consists
	// of all the parameters that are expected in the integration execution.
	// This gives the user the ability to provide default values, add
	// information like PII and also provide data types of each parameter.
	IntegrationParameters []*GoogleCloudIntegrationsV1alphaIntegrationParameter `json:"integrationParameters,omitempty"`

	// IntegrationParametersInternal: Optional. Parameters that are expected
	// to be passed to the integration when an event is triggered. This
	// consists of all the parameters that are expected in the integration
	// execution. This gives the user the ability to provide default values,
	// add information like PII and also provide data types of each
	// parameter.
	IntegrationParametersInternal *EnterpriseCrmFrontendsEventbusProtoWorkflowParameters `json:"integrationParametersInternal,omitempty"`

	// LastModifierEmail: Optional. The last modifier's email address.
	// Generated based on the End User Credentials/LOAS role of the user
	// making the call.
	LastModifierEmail string `json:"lastModifierEmail,omitempty"`

	// LockHolder: Optional. The edit lock holder's email address. Generated
	// based on the End User Credentials/LOAS role of the user making the
	// call.
	LockHolder string `json:"lockHolder,omitempty"`

	// Name: Output only. Auto-generated primary key.
	Name string `json:"name,omitempty"`

	// Origin: Optional. The origin that indicates where this integration is
	// coming from.
	//
	// Possible values:
	//   "UNSPECIFIED"
	//   "UI" - Workflow is being created via event bus UI.
	//   "PIPER_V2" - User checked in this workflow in Piper as v2 textproto
	// format and we synced it into spanner.
	//   "PIPER_V3" - User checked in this workflow in piper as v3 textproto
	// format and we synced it into spanner.
	//   "APPLICATION_IP_PROVISIONING" - Workflow is being created via
	// Standalone IP Provisioning
	Origin string `json:"origin,omitempty"`

	// ParentTemplateId: Optional. The id of the template which was used to
	// create this integration_version.
	ParentTemplateId string `json:"parentTemplateId,omitempty"`

	// RunAsServiceAccount: Optional. The run-as service account email, if
	// set and auth config is not configured, that will be used to generate
	// auth token to be used in Connector task, Rest caller task and Cloud
	// function task.
	RunAsServiceAccount string `json:"runAsServiceAccount,omitempty"`

	// SnapshotNumber: Optional. An increasing sequence that is set when a
	// new snapshot is created. The last created snapshot can be identified
	// by [workflow_name, org_id latest(snapshot_number)]. However, last
	// created snapshot need not be same as the HEAD. So users should always
	// use "HEAD" tag to identify the head.
	SnapshotNumber int64 `json:"snapshotNumber,omitempty,string"`

	// State: Output only. User should not set it as an input.
	//
	// Possible values:
	//   "INTEGRATION_STATE_UNSPECIFIED" - Default.
	//   "DRAFT" - Draft.
	//   "ACTIVE" - Active.
	//   "ARCHIVED" - Archived.
	//   "SNAPSHOT" - Snapshot.
	State string `json:"state,omitempty"`

	// Status: Output only. Generated by eventbus. User should not set it as
	// an input.
	//
	// Possible values:
	//   "UNKNOWN"
	//   "DRAFT"
	//   "ACTIVE"
	//   "ARCHIVED"
	//   "SNAPSHOT"
	Status string `json:"status,omitempty"`

	// TaskConfigs: Optional. Task configuration for the integration. It's
	// optional, but the integration doesn't do anything without
	// task_configs.
	TaskConfigs []*GoogleCloudIntegrationsV1alphaTaskConfig `json:"taskConfigs,omitempty"`

	// TaskConfigsInternal: Optional. Task configuration for the
	// integration. It's optional, but the integration doesn't do anything
	// without task_configs.
	TaskConfigsInternal []*EnterpriseCrmFrontendsEventbusProtoTaskConfig `json:"taskConfigsInternal,omitempty"`

	// Teardown: Optional. Contains a graph of tasks that will be executed
	// before putting the event in a terminal state
	// (SUCCEEDED/FAILED/FATAL), regardless of success or failure, similar
	// to "finally" in code.
	Teardown *EnterpriseCrmEventbusProtoTeardown `json:"teardown,omitempty"`

	// TriggerConfigs: Optional. Trigger configurations.
	TriggerConfigs []*GoogleCloudIntegrationsV1alphaTriggerConfig `json:"triggerConfigs,omitempty"`

	// TriggerConfigsInternal: Optional. Trigger configurations.
	TriggerConfigsInternal []*EnterpriseCrmFrontendsEventbusProtoTriggerConfig `json:"triggerConfigsInternal,omitempty"`

	// UpdateTime: Output only. Auto-generated.
	UpdateTime string `json:"updateTime,omitempty"`

	// UserLabel: Optional. A user-defined label that annotates an
	// integration version. Typically, this is only set when the integration
	// version is created.
	UserLabel string `json:"userLabel,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaJwt: Represents JSON web token(JWT),
// which is a compact, URL-safe means of representing claims to be
// transferred between two parties, enabling the claims to be digitally
// signed or integrity protected.
type GoogleCloudIntegrationsV1alphaJwt struct {
	// Jwt: The token calculated by the header, payload and signature.
	Jwt string `json:"jwt,omitempty"`

	// JwtHeader: Identifies which algorithm is used to generate the
	// signature.
	JwtHeader string `json:"jwtHeader,omitempty"`

	// JwtPayload: Contains a set of claims. The JWT specification defines
	// seven Registered Claim Names which are the standard fields commonly
	// included in tokens. Custom claims are usually also included,
	// depending on the purpose of the token.
	JwtPayload string `json:"jwtPayload,omitempty"`

	// Secret: User's pre-shared secret to sign the token.
	Secret string `json:"secret,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaLiftSuspensionRequest: Request for lift
// Suspension
type GoogleCloudIntegrationsV1alphaLiftSuspensionRequest struct {
	// SuspensionResult: User passed in suspension result and will be used
	// to control workflow execution branching behavior by setting up
	// corresponnding edge condition with suspension result. For example, if
	// you want to lift the suspension, you can pass "Approved", or if you
	// want to reject the suspension and terminate workfloe execution, you
	// can pass "Rejected" and terminate the workflow execution with
	// configuring the edge condition.
	SuspensionResult string `json:"suspensionResult,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaLiftSuspensionResponse: Response of
// lift Suspense
type GoogleCloudIntegrationsV1alphaLiftSuspensionResponse struct {
	// EventExecutionInfoId: Execution Id that will be returned
	EventExecutionInfoId string `json:"eventExecutionInfoId,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectRequest: Request
// for LinkAppsScriptProject rpc call.
type GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectRequest struct {
	// ScriptId: The id of the Apps Script project to be linked.
	ScriptId string `json:"scriptId,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectResponse: Response
// for LinkAppsScriptProject rpc call.
type GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectResponse struct {
	// ScriptId: The id of the linked Apps Script project.
	ScriptId string `json:"scriptId,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaListAuthConfigsResponse: Response to
// list AuthConfigs.
type GoogleCloudIntegrationsV1alphaListAuthConfigsResponse struct {
	// AuthConfigs: The list of AuthConfigs retrieved.
	AuthConfigs []*GoogleCloudIntegrationsV1alphaAuthConfig `json:"authConfigs,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaListCertificatesResponse: Response to
// list Certificates.
type GoogleCloudIntegrationsV1alphaListCertificatesResponse struct {
	// Certificates: The list of Certificates retrieved.
	Certificates []*GoogleCloudIntegrationsV1alphaCertificate `json:"certificates,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaListConnectionsResponse: Response
// containing Connections listed by region.
type GoogleCloudIntegrationsV1alphaListConnectionsResponse struct {
	// Connections: Connections.
	Connections []*GoogleCloudConnectorsV1Connection `json:"connections,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaListExecutionsResponse: Response for
// listing the integration execution data.
type GoogleCloudIntegrationsV1alphaListExecutionsResponse struct {
	// ExecutionInfos: Required. The detailed information of requested
	// executions.
	ExecutionInfos []*EnterpriseCrmFrontendsEventbusProtoEventExecutionInfo `json:"executionInfos,omitempty"`

	// Executions: The detailed information of requested executions
	Executions []*GoogleCloudIntegrationsV1alphaExecution `json:"executions,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaListIntegrationTemplateVersionsResponse:
//
//	Response for
//
// IntegrationTemplateVersions.ListIntegrationTemplateVersions.
type GoogleCloudIntegrationsV1alphaListIntegrationTemplateVersionsResponse struct {
	// IntegrationTemplateVersions: The IntegrationTemplateVersions which
	// match the request.
	IntegrationTemplateVersions []*GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion `json:"integrationTemplateVersions,omitempty"`

	// NextPageToken: A token, which can be sent as `page_token` to retrieve
	// the next page. If this field is omitted, there are no subsequent
	// pages.
	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.
	// "IntegrationTemplateVersions") to unconditionally include in API
	// requests. By default, fields with empty or default values are omitted
	// from API requests. However, any non-pointer, non-interface field
	// appearing in ForceSendFields will be sent to the server regardless of
	// whether the field is empty or not. This may be used to include empty
	// fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse:
// Response for ListIntegrationVersions.
type GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse struct {
	// IntegrationVersions: The integrations which match the request.
	IntegrationVersions []*GoogleCloudIntegrationsV1alphaIntegrationVersion `json:"integrationVersions,omitempty"`

	// NextPageToken: A token, which can be sent as `page_token` to retrieve
	// the next page. If this field is omitted, there are no subsequent
	// pages.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// NoPermission: Whether the user has no permission on the version or
	// not.
	NoPermission bool `json:"noPermission,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaListIntegrationsResponse: Response for
// ListIntegrations.
type GoogleCloudIntegrationsV1alphaListIntegrationsResponse struct {
	// Integrations: The integrations which match the request.
	Integrations []*GoogleCloudIntegrationsV1alphaIntegration `json:"integrations,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaListRuntimeActionSchemasResponse:
// Response for listing RuntimeActionSchemas for a specific Connection.
type GoogleCloudIntegrationsV1alphaListRuntimeActionSchemasResponse struct {
	// NextPageToken: Next page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// RuntimeActionSchemas: Runtime action schemas.
	RuntimeActionSchemas []*GoogleCloudIntegrationsV1alphaRuntimeActionSchema `json:"runtimeActionSchemas,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaListRuntimeEntitySchemasResponse:
// Response for listing RuntimeEntitySchemas for a specific Connection.
type GoogleCloudIntegrationsV1alphaListRuntimeEntitySchemasResponse struct {
	// NextPageToken: Next page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// RuntimeEntitySchemas: Runtime entity schemas.
	RuntimeEntitySchemas []*GoogleCloudIntegrationsV1alphaRuntimeEntitySchema `json:"runtimeEntitySchemas,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse: Response to
// list SfdcChannels.
type GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse struct {
	// NextPageToken: The token used to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SfdcChannels: The list of SfdcChannels retrieved.
	SfdcChannels []*GoogleCloudIntegrationsV1alphaSfdcChannel `json:"sfdcChannels,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse: Response to
// list SfdcInstances.
type GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse struct {
	// NextPageToken: The token used to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SfdcInstances: The list of SfdcInstances retrieved.
	SfdcInstances []*GoogleCloudIntegrationsV1alphaSfdcInstance `json:"sfdcInstances,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaListSuspensionsResponse: Response for
// Suspensions.ListSuspensions.
type GoogleCloudIntegrationsV1alphaListSuspensionsResponse struct {
	// NextPageToken: Token to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Suspensions: The suspensions for the relevant execution which the
	// caller has permissions to view and resolve.
	Suspensions []*GoogleCloudIntegrationsV1alphaSuspension `json:"suspensions,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaNextTask: The task that is next in line
// to be executed, if the condition specified evaluated to true.
type GoogleCloudIntegrationsV1alphaNextTask struct {
	// Condition: Standard filter expression for this task to become an
	// eligible next task.
	Condition string `json:"condition,omitempty"`

	// Description: User-provided description intended to give additional
	// business context about the task.
	Description string `json:"description,omitempty"`

	// DisplayName: User-provided label that is attached to this edge in the
	// UI.
	DisplayName string `json:"displayName,omitempty"`

	// TaskConfigId: ID of the next task.
	TaskConfigId string `json:"taskConfigId,omitempty"`

	// TaskId: Task number of the next task.
	TaskId string `json:"taskId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Condition") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *GoogleCloudIntegrationsV1alphaNextTask) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudIntegrationsV1alphaNextTask
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudIntegrationsV1alphaOAuth2AuthorizationCode: The OAuth Type
// where the client sends request with the client id and requested
// scopes to auth endpoint. User sees a consent screen and auth code is
// received at specified redirect url afterwards. The auth code is then
// combined with the client id and secret and sent to the token endpoint
// in exchange for the access and refresh token. The refresh token can
// be used to fetch new access tokens.
type GoogleCloudIntegrationsV1alphaOAuth2AuthorizationCode struct {
	// AccessToken: The access token received from the token endpoint.
	AccessToken *GoogleCloudIntegrationsV1alphaAccessToken `json:"accessToken,omitempty"`

	// ApplyReauthPolicy: Indicates if the user has opted in Google Reauth
	// Policy. If opted in, the refresh token will be valid for 20 hours,
	// after which time users must re-authenticate in order to obtain a new
	// one.
	ApplyReauthPolicy bool `json:"applyReauthPolicy,omitempty"`

	// AuthCode: The Auth Code that is used to initially retrieve the access
	// token.
	AuthCode string `json:"authCode,omitempty"`

	// AuthEndpoint: The auth url endpoint to send the auth code request to.
	AuthEndpoint string `json:"authEndpoint,omitempty"`

	// AuthParams: The auth parameters sent along with the auth code
	// request.
	AuthParams *GoogleCloudIntegrationsV1alphaParameterMap `json:"authParams,omitempty"`

	// ClientId: The client's id.
	ClientId string `json:"clientId,omitempty"`

	// ClientSecret: The client's secret.
	ClientSecret string `json:"clientSecret,omitempty"`

	// RequestType: Represent how to pass parameters to fetch access token
	//
	// Possible values:
	//   "REQUEST_TYPE_UNSPECIFIED" - Unspecified request type
	//   "REQUEST_BODY" - To pass all the parameters in post body.
	//   "QUERY_PARAMETERS" - To pass all the parameters as a part of query
	// parameter.
	//   "ENCODED_HEADER" - To pass client id and client secret as base 64
	// encoding of client_id:client_password and rest parameters in post
	// body.
	RequestType string `json:"requestType,omitempty"`

	// Scope: A space-delimited list of requested scope permissions.
	Scope string `json:"scope,omitempty"`

	// TokenEndpoint: The token url endpoint to send the token request to.
	TokenEndpoint string `json:"tokenEndpoint,omitempty"`

	// TokenParams: The token parameters sent along with the token request.
	TokenParams *GoogleCloudIntegrationsV1alphaParameterMap `json:"tokenParams,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaOAuth2ClientCredentials: For client
// credentials grant, the client sends a POST request with grant_type as
// 'client_credentials' to the authorization server. The authorization
// server will respond with a JSON object containing the access token.
type GoogleCloudIntegrationsV1alphaOAuth2ClientCredentials struct {
	// AccessToken: Access token fetched from the authorization server.
	AccessToken *GoogleCloudIntegrationsV1alphaAccessToken `json:"accessToken,omitempty"`

	// ClientId: The client's ID.
	ClientId string `json:"clientId,omitempty"`

	// ClientSecret: The client's secret.
	ClientSecret string `json:"clientSecret,omitempty"`

	// RequestType: Represent how to pass parameters to fetch access token
	//
	// Possible values:
	//   "REQUEST_TYPE_UNSPECIFIED" - Unspecified request type
	//   "REQUEST_BODY" - To pass all the parameters in post body.
	//   "QUERY_PARAMETERS" - To pass all the parameters as a part of query
	// parameter.
	//   "ENCODED_HEADER" - To pass client id and client secret as base 64
	// encoding of client_id:client_password and rest parameters in post
	// body.
	RequestType string `json:"requestType,omitempty"`

	// Scope: A space-delimited list of requested scope permissions.
	Scope string `json:"scope,omitempty"`

	// TokenEndpoint: The token endpoint is used by the client to obtain an
	// access token by presenting its authorization grant or refresh token.
	TokenEndpoint string `json:"tokenEndpoint,omitempty"`

	// TokenParams: Token parameters for the auth request.
	TokenParams *GoogleCloudIntegrationsV1alphaParameterMap `json:"tokenParams,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaOAuth2ResourceOwnerCredentials: For
// resource owner credentials grant, the client will ask the user for
// their authorization credentials (ususally a username and password)
// and send a POST request to the authorization server. The
// authorization server will respond with a JSON object containing the
// access token.
type GoogleCloudIntegrationsV1alphaOAuth2ResourceOwnerCredentials struct {
	// AccessToken: Access token fetched from the authorization server.
	AccessToken *GoogleCloudIntegrationsV1alphaAccessToken `json:"accessToken,omitempty"`

	// ClientId: The client's ID.
	ClientId string `json:"clientId,omitempty"`

	// ClientSecret: The client's secret.
	ClientSecret string `json:"clientSecret,omitempty"`

	// Password: The user's password.
	Password string `json:"password,omitempty"`

	// RequestType: Represent how to pass parameters to fetch access token
	//
	// Possible values:
	//   "REQUEST_TYPE_UNSPECIFIED" - Unspecified request type
	//   "REQUEST_BODY" - To pass all the parameters in post body.
	//   "QUERY_PARAMETERS" - To pass all the parameters as a part of query
	// parameter.
	//   "ENCODED_HEADER" - To pass client id and client secret as base 64
	// encoding of client_id:client_password and rest parameters in post
	// body.
	RequestType string `json:"requestType,omitempty"`

	// Scope: A space-delimited list of requested scope permissions.
	Scope string `json:"scope,omitempty"`

	// TokenEndpoint: The token endpoint is used by the client to obtain an
	// access token by presenting its authorization grant or refresh token.
	TokenEndpoint string `json:"tokenEndpoint,omitempty"`

	// TokenParams: Token parameters for the auth request.
	TokenParams *GoogleCloudIntegrationsV1alphaParameterMap `json:"tokenParams,omitempty"`

	// Username: The user's username.
	Username string `json:"username,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaOidcToken: OIDC Token
type GoogleCloudIntegrationsV1alphaOidcToken struct {
	// Audience: Audience to be used when generating OIDC token. The
	// audience claim identifies the recipients that the JWT is intended
	// for.
	Audience string `json:"audience,omitempty"`

	// ServiceAccountEmail: The service account email to be used as the
	// identity for the token.
	ServiceAccountEmail string `json:"serviceAccountEmail,omitempty"`

	// Token: ID token obtained for the service account
	Token string `json:"token,omitempty"`

	// TokenExpireTime: The approximate time until the token retrieved is
	// valid.
	TokenExpireTime string `json:"tokenExpireTime,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaParameterMap: A generic multi-map that
// holds key value pairs. They keys and values can be of any type,
// unless specified.
type GoogleCloudIntegrationsV1alphaParameterMap struct {
	// Entries: A list of parameter map entries.
	Entries []*GoogleCloudIntegrationsV1alphaParameterMapEntry `json:"entries,omitempty"`

	// KeyType: Option to specify key type for all entries of the map. If
	// provided then field types for all entries must conform to this.
	//
	// Possible values:
	//   "INTEGRATION_PARAMETER_DATA_TYPE_UNSPECIFIED" - Unspecified.
	//   "STRING_VALUE" - String.
	//   "INT_VALUE" - Integer.
	//   "DOUBLE_VALUE" - Double Number.
	//   "BOOLEAN_VALUE" - Boolean.
	//   "STRING_ARRAY" - String Array.
	//   "INT_ARRAY" - Integer Array.
	//   "DOUBLE_ARRAY" - Double Number Array.
	//   "BOOLEAN_ARRAY" - Boolean Array.
	//   "JSON_VALUE" - Json.
	//   "PROTO_VALUE" - Proto Value (Internal use only).
	//   "PROTO_ARRAY" - Proto Array (Internal use only).
	KeyType string `json:"keyType,omitempty"`

	// ValueType: Option to specify value type for all entries of the map.
	// If provided then field types for all entries must conform to this.
	//
	// Possible values:
	//   "INTEGRATION_PARAMETER_DATA_TYPE_UNSPECIFIED" - Unspecified.
	//   "STRING_VALUE" - String.
	//   "INT_VALUE" - Integer.
	//   "DOUBLE_VALUE" - Double Number.
	//   "BOOLEAN_VALUE" - Boolean.
	//   "STRING_ARRAY" - String Array.
	//   "INT_ARRAY" - Integer Array.
	//   "DOUBLE_ARRAY" - Double Number Array.
	//   "BOOLEAN_ARRAY" - Boolean Array.
	//   "JSON_VALUE" - Json.
	//   "PROTO_VALUE" - Proto Value (Internal use only).
	//   "PROTO_ARRAY" - Proto Array (Internal use only).
	ValueType string `json:"valueType,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaParameterMapEntry: Entry is a pair of
// key and value.
type GoogleCloudIntegrationsV1alphaParameterMapEntry struct {
	// Key: Key of the map entry.
	Key *GoogleCloudIntegrationsV1alphaParameterMapField `json:"key,omitempty"`

	// Value: Value of the map entry.
	Value *GoogleCloudIntegrationsV1alphaParameterMapField `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *GoogleCloudIntegrationsV1alphaParameterMapEntry) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudIntegrationsV1alphaParameterMapEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudIntegrationsV1alphaParameterMapField: Field represents
// either the key or value in an entry.
type GoogleCloudIntegrationsV1alphaParameterMapField struct {
	// LiteralValue: Passing a literal value.
	LiteralValue *GoogleCloudIntegrationsV1alphaValueType `json:"literalValue,omitempty"`

	// ReferenceKey: Referencing one of the Integration variables.
	ReferenceKey string `json:"referenceKey,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaPublishIntegrationVersionRequest:
// Request for PublishIntegrationVersion.
type GoogleCloudIntegrationsV1alphaPublishIntegrationVersionRequest struct {
}

// GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse:
// Response for PublishIntegrationVersion.
type GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// GoogleCloudIntegrationsV1alphaResolveSuspensionRequest: Request for
// [Suspensions.ResolveSuspensions].
type GoogleCloudIntegrationsV1alphaResolveSuspensionRequest struct {
	// Suspension: Suspension, containing the event_execution_info_id,
	// task_id, and state to set on the corresponding suspension record.
	Suspension *GoogleCloudIntegrationsV1alphaSuspension `json:"suspension,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaResolveSuspensionResponse: Response for
// Suspensions.ResolveSuspensions.
type GoogleCloudIntegrationsV1alphaResolveSuspensionResponse struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// GoogleCloudIntegrationsV1alphaRuntimeActionSchema: Metadata of an
// action, including schemas for its inputs and outputs.
type GoogleCloudIntegrationsV1alphaRuntimeActionSchema struct {
	// Action: Name of the action.
	Action string `json:"action,omitempty"`

	// InputSchema: Input parameter schema for the action.
	InputSchema string `json:"inputSchema,omitempty"`

	// OutputSchema: Output parameter schema for the action.
	OutputSchema string `json:"outputSchema,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaRuntimeEntitySchema: Metadata of an
// entity, including a schema for its properties.
type GoogleCloudIntegrationsV1alphaRuntimeEntitySchema struct {
	// ArrayFieldSchema: The above schema, but for an array of the
	// associated entity.
	ArrayFieldSchema string `json:"arrayFieldSchema,omitempty"`

	// Entity: Name of the entity.
	Entity string `json:"entity,omitempty"`

	// FieldSchema: List of fields in the entity.
	FieldSchema string `json:"fieldSchema,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaScheduleIntegrationsRequest: The
// request for scheduling an integration.
type GoogleCloudIntegrationsV1alphaScheduleIntegrationsRequest struct {
	// InputParameters: Optional. Input parameters used by integration
	// execution.
	InputParameters map[string]GoogleCloudIntegrationsV1alphaValueType `json:"inputParameters,omitempty"`

	// ParameterEntries: Parameters are a part of Event and can be used to
	// communicate between different tasks that are part of the same
	// integration execution.
	ParameterEntries []*EnterpriseCrmFrontendsEventbusProtoParameterEntry `json:"parameterEntries,omitempty"`

	// Parameters: Passed in as parameters to each integration execution.
	Parameters *EnterpriseCrmEventbusProtoEventParameters `json:"parameters,omitempty"`

	// RequestId: This is used to de-dup incoming request: if the duplicate
	// request was detected, the response from the previous execution is
	// returned.
	RequestId string `json:"requestId,omitempty"`

	// ScheduleTime: The time that the integration should be executed. If
	// the time is less or equal to the current time, the integration is
	// executed immediately.
	ScheduleTime string `json:"scheduleTime,omitempty"`

	// TriggerId: Required. Matched against all {@link TriggerConfig}s
	// across all integrations. i.e.
	// TriggerConfig.trigger_id.equals(trigger_id)
	TriggerId string `json:"triggerId,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse: The
// response for executing an integration.
type GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse struct {
	// ExecutionInfoIds: The execution info id for the executed
	// integrations.
	ExecutionInfoIds []string `json:"executionInfoIds,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaServiceAccountCredentials: Represents
// the service account which can be used to generate access token for
// authenticating the service call.
type GoogleCloudIntegrationsV1alphaServiceAccountCredentials struct {
	// Scope: A space-delimited list of requested scope permissions.
	Scope string `json:"scope,omitempty"`

	// ServiceAccount: Name of the service account that has the permission
	// to make the request.
	ServiceAccount string `json:"serviceAccount,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaSfdcChannel: The SfdcChannel that
// points to a CDC or Platform Event Channel.
type GoogleCloudIntegrationsV1alphaSfdcChannel struct {
	// ChannelTopic: The Channel topic defined by salesforce once an channel
	// is opened
	ChannelTopic string `json:"channelTopic,omitempty"`

	// CreateTime: Output only. Time when the channel is created
	CreateTime string `json:"createTime,omitempty"`

	// DeleteTime: Output only. Time when the channel was deleted. Empty if
	// not deleted.
	DeleteTime string `json:"deleteTime,omitempty"`

	// Description: The description for this channel
	Description string `json:"description,omitempty"`

	// DisplayName: Client level unique name/alias to easily reference a
	// channel.
	DisplayName string `json:"displayName,omitempty"`

	// IsActive: Indicated if a channel has any active integrations
	// referencing it. Set to false when the channel is created, and set to
	// true if there is any integration published with the channel
	// configured in it.
	IsActive bool `json:"isActive,omitempty"`

	// LastReplayId: Last sfdc messsage replay id for channel
	LastReplayId string `json:"lastReplayId,omitempty"`

	// Name: Resource name of the SFDC channel
	// projects/{project}/locations/{location}/sfdcInstances/{sfdc_instance}/
	// sfdcChannels/{sfdc_channel}.
	Name string `json:"name,omitempty"`

	// UpdateTime: Output only. Time when the channel was last updated
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaSfdcInstance: The SfdcInstance resource
// use to hold channels and connection config data.
type GoogleCloudIntegrationsV1alphaSfdcInstance struct {
	// AuthConfigId: A list of AuthConfigs that can be tried to open the
	// channel to SFDC
	AuthConfigId []string `json:"authConfigId,omitempty"`

	// CreateTime: Output only. Time when the instance is created
	CreateTime string `json:"createTime,omitempty"`

	// DeleteTime: Output only. Time when the instance was deleted. Empty if
	// not deleted.
	DeleteTime string `json:"deleteTime,omitempty"`

	// Description: A description of the sfdc instance.
	Description string `json:"description,omitempty"`

	// DisplayName: User selected unique name/alias to easily reference an
	// instance.
	DisplayName string `json:"displayName,omitempty"`

	// Name: Resource name of the SFDC instance
	// projects/{project}/locations/{location}/sfdcInstances/{sfdcInstance}.
	Name string `json:"name,omitempty"`

	// ServiceAuthority: URL used for API calls after authentication (the
	// login authority is configured within the referenced AuthConfig).
	ServiceAuthority string `json:"serviceAuthority,omitempty"`

	// SfdcOrgId: The SFDC Org Id. This is defined in salesforce.
	SfdcOrgId string `json:"sfdcOrgId,omitempty"`

	// UpdateTime: Output only. Time when the instance was last updated
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaStringParameterArray: This message only
// contains a field of string array.
type GoogleCloudIntegrationsV1alphaStringParameterArray struct {
	// StringValues: String array.
	StringValues []string `json:"stringValues,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaSuccessPolicy: Policy that dictates the
// behavior for the task after it completes successfully.
type GoogleCloudIntegrationsV1alphaSuccessPolicy struct {
	// FinalState: State to which the execution snapshot status will be set
	// if the task succeeds.
	//
	// Possible values:
	//   "FINAL_STATE_UNSPECIFIED" - UNSPECIFIED.
	//   "SUCCEEDED" - The default behavior, where successful tasks will be
	// marked as SUCCEEDED.
	//   "SUSPENDED" - Sets the state to SUSPENDED after executing. This is
	// required for SuspensionTask; event execution will continue once the
	// user calls ResolveSuspensions with the event_execution_info_id and
	// the task number.
	FinalState string `json:"finalState,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaSuspension: A record representing a
// suspension.
type GoogleCloudIntegrationsV1alphaSuspension struct {
	// ApprovalConfig: Controls the notifications and approval permissions
	// for this suspension.
	ApprovalConfig *GoogleCloudIntegrationsV1alphaSuspensionApprovalConfig `json:"approvalConfig,omitempty"`

	// Audit: Metadata pertaining to the resolution of this suspension.
	Audit *GoogleCloudIntegrationsV1alphaSuspensionAudit `json:"audit,omitempty"`

	// CreateTime: Output only. Auto-generated.
	CreateTime string `json:"createTime,omitempty"`

	// EventExecutionInfoId: Required. ID of the associated execution.
	EventExecutionInfoId string `json:"eventExecutionInfoId,omitempty"`

	// Integration: Required. The name of the originating integration.
	Integration string `json:"integration,omitempty"`

	// LastModifyTime: Output only. Auto-generated.
	LastModifyTime string `json:"lastModifyTime,omitempty"`

	// Name: Resource name for suspensions suspension/{suspension_id}
	Name string `json:"name,omitempty"`

	// State: Required. State of this suspension, indicating what action a
	// resolver has taken.
	//
	// Possible values:
	//   "RESOLUTION_STATE_UNSPECIFIED" - Unset state.
	//   "PENDING" - The suspension has not yet been resolved.
	//   "REJECTED" - The resolver has rejected the suspension.
	//   "LIFTED" - The resolver has lifted the suspension.
	State string `json:"state,omitempty"`

	// SuspensionConfig: Controls the notifications and resolver permissions
	// for this suspension.
	SuspensionConfig *EnterpriseCrmEventbusProtoSuspensionConfig `json:"suspensionConfig,omitempty"`

	// TaskId: Required. Task id of the associated SuspensionTask.
	TaskId string `json:"taskId,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaSuspensionApprovalConfig:
// Configurations for approving the Suspension.
type GoogleCloudIntegrationsV1alphaSuspensionApprovalConfig struct {
	// CustomMessage: Information to provide for recipients.
	CustomMessage string `json:"customMessage,omitempty"`

	// EmailAddresses: Email addresses to send approval request to.
	EmailAddresses []string `json:"emailAddresses,omitempty"`

	// Expiration: Indicates the next steps when no external actions happen
	// on the suspension.
	Expiration *GoogleCloudIntegrationsV1alphaSuspensionApprovalExpiration `json:"expiration,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaSuspensionApprovalExpiration:
// Expiration configs for the approval request.
type GoogleCloudIntegrationsV1alphaSuspensionApprovalExpiration struct {
	// ExpireTime: Output only. Time after which the suspension expires, if
	// no action taken.
	ExpireTime string `json:"expireTime,omitempty"`

	// LiftWhenExpired: Whether the suspension will be REJECTED or LIFTED
	// upon expiration. REJECTED is the default behavior.
	LiftWhenExpired bool `json:"liftWhenExpired,omitempty"`

	// RemindTime: Time after the previous suspension action reminder, if
	// any, is sent using the selected notification option, for a suspension
	// which is still PENDING_UNSPECIFIED.
	RemindTime string `json:"remindTime,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaSuspensionAudit: Contains when and by
// whom the suspension was resolved.
type GoogleCloudIntegrationsV1alphaSuspensionAudit struct {
	// ResolveTime: Time at which this suspension was resolved.
	ResolveTime string `json:"resolveTime,omitempty"`

	// Resolver: Email address of the person who resolved this suspension.
	Resolver string `json:"resolver,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaTakeoverEditLockRequest: Request for
// TakeoverEditLock.
type GoogleCloudIntegrationsV1alphaTakeoverEditLockRequest struct {
}

// GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse: Response for
// TakeoverEditLock.
type GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse struct {
	// IntegrationVersion: Version after the lock is acquired by the new
	// user.
	IntegrationVersion *GoogleCloudIntegrationsV1alphaIntegrationVersion `json:"integrationVersion,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaTaskConfig: The task configuration
// details. This is not the implementation of Task. There might be
// multiple TaskConfigs for the same Task.
type GoogleCloudIntegrationsV1alphaTaskConfig struct {
	// Description: Optional. User-provided description intended to give
	// additional business context about the task.
	Description string `json:"description,omitempty"`

	// DisplayName: Optional. User-provided label that is attached to this
	// TaskConfig in the UI.
	DisplayName string `json:"displayName,omitempty"`

	// ErrorCatcherId: Optional. Optional Error catcher id of the error
	// catch flow which will be executed when execution error happens in the
	// task
	ErrorCatcherId string `json:"errorCatcherId,omitempty"`

	// ExternalTaskType: Optional. External task type of the task
	//
	// Possible values:
	//   "EXTERNAL_TASK_TYPE_UNSPECIFIED" - Default value. External task
	// type is not specified
	//   "NORMAL_TASK" - Tasks belongs to the normal task flows
	//   "ERROR_TASK" - Task belongs to the error catch task flows
	ExternalTaskType string `json:"externalTaskType,omitempty"`

	// FailurePolicy: Optional. Determines the number of times the task will
	// be retried on failure and with what retry strategy. This is
	// applicable for asynchronous calls to Eventbus alone (Post To Queue,
	// Schedule etc.).
	FailurePolicy *GoogleCloudIntegrationsV1alphaFailurePolicy `json:"failurePolicy,omitempty"`

	// JsonValidationOption: Optional. If set, overrides the option
	// configured in the Task implementation class.
	//
	// Possible values:
	//   "JSON_VALIDATION_OPTION_UNSPECIFIED" - As per the default behavior,
	// no validation will be run. Will not override any option set in a
	// Task.
	//   "SKIP" - Do not run any validation against JSON schemas.
	//   "PRE_EXECUTION" - Validate all potential input JSON parameters
	// against schemas specified in IntegrationParameter.
	//   "POST_EXECUTION" - Validate all potential output JSON parameters
	// against schemas specified in IntegrationParameter.
	//   "PRE_POST_EXECUTION" - Perform both PRE_EXECUTION and
	// POST_EXECUTION validations.
	JsonValidationOption string `json:"jsonValidationOption,omitempty"`

	// NextTasks: Optional. The set of tasks that are next in line to be
	// executed as per the execution graph defined for the parent event,
	// specified by `event_config_id`. Each of these next tasks are executed
	// only if the condition associated with them evaluates to true.
	NextTasks []*GoogleCloudIntegrationsV1alphaNextTask `json:"nextTasks,omitempty"`

	// NextTasksExecutionPolicy: Optional. The policy dictating the
	// execution of the next set of tasks for the current task.
	//
	// Possible values:
	//   "NEXT_TASKS_EXECUTION_POLICY_UNSPECIFIED" - Default.
	//   "RUN_ALL_MATCH" - Execute all the tasks that satisfy their
	// associated condition.
	//   "RUN_FIRST_MATCH" - Execute the first task that satisfies the
	// associated condition.
	NextTasksExecutionPolicy string `json:"nextTasksExecutionPolicy,omitempty"`

	// Parameters: Optional. The customized parameters the user can pass to
	// this task.
	Parameters map[string]GoogleCloudIntegrationsV1alphaEventParameter `json:"parameters,omitempty"`

	// Position: Optional. Informs the front-end application where to draw
	// this error catcher config on the UI.
	Position *GoogleCloudIntegrationsV1alphaCoordinate `json:"position,omitempty"`

	// SuccessPolicy: Optional. Determines what action to take upon
	// successful task completion.
	SuccessPolicy *GoogleCloudIntegrationsV1alphaSuccessPolicy `json:"successPolicy,omitempty"`

	// SynchronousCallFailurePolicy: Optional. Determines the number of
	// times the task will be retried on failure and with what retry
	// strategy. This is applicable for synchronous calls to Eventbus alone
	// (Post).
	SynchronousCallFailurePolicy *GoogleCloudIntegrationsV1alphaFailurePolicy `json:"synchronousCallFailurePolicy,omitempty"`

	// Task: Optional. The name for the task.
	Task string `json:"task,omitempty"`

	// TaskExecutionStrategy: Optional. The policy dictating the execution
	// strategy of this task.
	//
	// Possible values:
	//   "TASK_EXECUTION_STRATEGY_UNSPECIFIED" - Default. If the strategy is
	// not set explicitly, it will default to `WHEN_ALL_SUCCEED`.
	//   "WHEN_ALL_SUCCEED" - Wait until all of its previous tasks finished
	// execution, then verify at least one of the edge conditions is met,
	// and execute if possible. This should be considered as
	// WHEN_ALL_TASKS_SUCCEED.
	//   "WHEN_ANY_SUCCEED" - Start execution as long as any of its previous
	// tasks finished execution and the corresponding edge condition is met
	// (since we will execute if only that succeeding edge condition is
	// met).
	//   "WHEN_ALL_TASKS_AND_CONDITIONS_SUCCEED" - Wait until all of its
	// previous tasks finished execution, then verify the all edge
	// conditions are met and execute if possible.
	TaskExecutionStrategy string `json:"taskExecutionStrategy,omitempty"`

	// TaskId: Required. The identifier of this task within its parent event
	// config, specified by the client. This should be unique among all the
	// tasks belong to the same event config. We use this field as the
	// identifier to find next tasks (via field `next_tasks.task_id`).
	TaskId string `json:"taskId,omitempty"`

	// TaskTemplate: Optional. Used to define task-template name if task is
	// of type task-template
	TaskTemplate string `json:"taskTemplate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *GoogleCloudIntegrationsV1alphaTaskConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudIntegrationsV1alphaTaskConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudIntegrationsV1alphaTaskExecutionDetails: Contains the
// details of the execution of this task.
type GoogleCloudIntegrationsV1alphaTaskExecutionDetails struct {
	// TaskAttemptStats: Status for the current task execution attempt.
	TaskAttemptStats []*GoogleCloudIntegrationsV1alphaAttemptStats `json:"taskAttemptStats,omitempty"`

	// TaskExecutionState: The execution state of this task.
	//
	// Possible values:
	//   "TASK_EXECUTION_STATE_UNSPECIFIED" - Default value.
	//   "PENDING_EXECUTION" - Task is waiting for its precondition tasks to
	// finish to start the execution.
	//   "IN_PROCESS" - Task is under processing.
	//   "SUCCEED" - Task execution successfully finished. There's no more
	// change after this state.
	//   "FAILED" - Task execution failed. There's no more change after this
	// state.
	//   "FATAL" - Task execution failed and cause the whole event execution
	// to fail immediately. There's no more change after this state.
	//   "RETRY_ON_HOLD" - Task execution failed and waiting for retry.
	//   "SKIPPED" - Task execution skipped. This happens when its
	// precondition wasn't met, or the event execution been canceled before
	// reach to the task. There's no more changes after this state.
	//   "CANCELLED" - Task execution canceled when in progress. This
	// happens when event execution been canceled or any other task fall in
	// fatal state.
	//   "PENDING_ROLLBACK" - Task is waiting for its dependency tasks'
	// rollback to finish to start its rollback.
	//   "ROLLBACK_IN_PROCESS" - Task is rolling back.
	//   "ROLLEDBACK" - Task is rolled back. This is the state we will set
	// regardless of rollback succeeding or failing.
	//   "SUSPENDED" - Task is a SuspensionTask which has executed once,
	// creating a pending suspension.
	TaskExecutionState string `json:"taskExecutionState,omitempty"`

	// TaskNumber: Pointer to the task config it used for execution.
	TaskNumber string `json:"taskNumber,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaTriggerConfig: Configuration detail of
// a trigger.
type GoogleCloudIntegrationsV1alphaTriggerConfig struct {
	// AlertConfig: Optional. An alert threshold configuration for the
	// [trigger + client + integration] tuple. If these values are not
	// specified in the trigger config, default values will be populated by
	// the system. Note that there must be exactly one alert threshold
	// configured per [client + trigger + integration] when published.
	AlertConfig []*GoogleCloudIntegrationsV1alphaIntegrationAlertConfig `json:"alertConfig,omitempty"`

	// CloudSchedulerConfig: Optional. Cloud Scheduler Trigger related
	// metadata
	CloudSchedulerConfig *GoogleCloudIntegrationsV1alphaCloudSchedulerConfig `json:"cloudSchedulerConfig,omitempty"`

	// Description: Optional. User-provided description intended to give
	// additional business context about the task.
	Description string `json:"description,omitempty"`

	// ErrorCatcherId: Optional. Optional Error catcher id of the error
	// catch flow which will be executed when execution error happens in the
	// task
	ErrorCatcherId string `json:"errorCatcherId,omitempty"`

	// Label: Optional. The user created label for a particular trigger.
	Label string `json:"label,omitempty"`

	// NextTasksExecutionPolicy: Optional. Dictates how next tasks will be
	// executed.
	//
	// Possible values:
	//   "NEXT_TASKS_EXECUTION_POLICY_UNSPECIFIED" - Default.
	//   "RUN_ALL_MATCH" - Execute all the tasks that satisfy their
	// associated condition.
	//   "RUN_FIRST_MATCH" - Execute the first task that satisfies the
	// associated condition.
	NextTasksExecutionPolicy string `json:"nextTasksExecutionPolicy,omitempty"`

	// Position: Optional. Informs the front-end application where to draw
	// this error catcher config on the UI.
	Position *GoogleCloudIntegrationsV1alphaCoordinate `json:"position,omitempty"`

	// Properties: Optional. Configurable properties of the trigger, not to
	// be confused with integration parameters. E.g. "name" is a property
	// for API triggers and "subscription" is a property for Pub/sub
	// triggers.
	Properties map[string]string `json:"properties,omitempty"`

	// StartTasks: Optional. Set of tasks numbers from where the integration
	// execution is started by this trigger. If this is empty, then
	// integration is executed with default start tasks. In the list of
	// start tasks, none of two tasks can have direct ancestor-descendant
	// relationships (i.e. in a same integration execution graph).
	StartTasks []*GoogleCloudIntegrationsV1alphaNextTask `json:"startTasks,omitempty"`

	// TriggerId: Optional. The backend trigger ID.
	TriggerId string `json:"triggerId,omitempty"`

	// TriggerNumber: Required. A number to uniquely identify each trigger
	// config within the integration on UI.
	TriggerNumber string `json:"triggerNumber,omitempty"`

	// TriggerType: Optional. Type of trigger
	//
	// Possible values:
	//   "TRIGGER_TYPE_UNSPECIFIED" - Unknown.
	//   "CRON" - Trigger by scheduled time.
	//   "API" - Trigger by API call.
	//   "SFDC_CHANNEL" - Trigger by Salesforce Channel.
	//   "CLOUD_PUBSUB_EXTERNAL" - Trigger by Pub/Sub external.
	//   "SFDC_CDC_CHANNEL" - SFDC Channel Trigger for CDC.
	//   "CLOUD_SCHEDULER" - Trigger by Cloud Scheduler job.
	//   "INTEGRATION_CONNECTOR_TRIGGER" - Trigger by Connector Event
	TriggerType string `json:"triggerType,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaUnpublishIntegrationVersionRequest:
// Request for UnpublishIntegrationVersion.
type GoogleCloudIntegrationsV1alphaUnpublishIntegrationVersionRequest struct {
}

// GoogleCloudIntegrationsV1alphaUploadIntegrationVersionRequest:
// Request for UploadIntegrationVersion.
type GoogleCloudIntegrationsV1alphaUploadIntegrationVersionRequest struct {
	// Content: The textproto of the integration_version.
	Content string `json:"content,omitempty"`

	// FileFormat: File format for upload request.
	//
	// Possible values:
	//   "FILE_FORMAT_UNSPECIFIED" - Unspecified file format
	//   "JSON" - JSON File Format
	//   "YAML" - YAML File Format
	FileFormat string `json:"fileFormat,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse:
// Response for UploadIntegrationVersion.
type GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse struct {
	// IntegrationVersion: The uploaded integration.
	IntegrationVersion *GoogleCloudIntegrationsV1alphaIntegrationVersion `json:"integrationVersion,omitempty"`

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

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

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

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

// GoogleCloudIntegrationsV1alphaUsernameAndPassword: Username and
// password pair.
type GoogleCloudIntegrationsV1alphaUsernameAndPassword struct {
	// Password: Password to be used
	Password string `json:"password,omitempty"`

	// Username: Username to be used
	Username string `json:"username,omitempty"`

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

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

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

// GoogleCloudIntegrationsV1alphaValueType: The type of the parameter.
type GoogleCloudIntegrationsV1alphaValueType struct {
	// BooleanArray: Boolean Array.
	BooleanArray *GoogleCloudIntegrationsV1alphaBooleanParameterArray `json:"booleanArray,omitempty"`

	// BooleanValue: Boolean.
	BooleanValue bool `json:"booleanValue,omitempty"`

	// DoubleArray: Double Number Array.
	DoubleArray *GoogleCloudIntegrationsV1alphaDoubleParameterArray `json:"doubleArray,omitempty"`

	// DoubleValue: Double Number.
	DoubleValue float64 `json:"doubleValue,omitempty"`

	// IntArray: Integer Array.
	IntArray *GoogleCloudIntegrationsV1alphaIntParameterArray `json:"intArray,omitempty"`

	// IntValue: Integer.
	IntValue int64 `json:"intValue,omitempty,string"`

	// JsonValue: Json.
	JsonValue string `json:"jsonValue,omitempty"`

	// StringArray: String Array.
	StringArray *GoogleCloudIntegrationsV1alphaStringParameterArray `json:"stringArray,omitempty"`

	// StringValue: String.
	StringValue string `json:"stringValue,omitempty"`

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

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

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

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

// GoogleInternalCloudCrmEventbusV3PostToQueueWithTriggerIdRequest: Use
// this request to post all workflows associated with a given trigger
// id. Next available id: 11
type GoogleInternalCloudCrmEventbusV3PostToQueueWithTriggerIdRequest struct {
	// ClientId: Optional. If the client id is provided, then the
	// combination of trigger id and client id is matched across all the
	// workflows. If the client id is not provided, then workflows with
	// matching trigger id are executed for each client id in the {@link
	// TriggerConfig}. For Api Trigger, the client id is required and will
	// be validated against the allowed clients.
	ClientId string `json:"clientId,omitempty"`

	// IgnoreErrorIfNoActiveWorkflow: Optional. Flag to determine whether
	// clients would suppress a warning when no ACTIVE workflows are not
	// found. If this flag is set to be true, an error will not be thrown if
	// the requested trigger_id or client_id is not found in any ACTIVE
	// workflow. Otherwise, the error is always thrown. The flag is set to
	// be false by default.
	IgnoreErrorIfNoActiveWorkflow bool `json:"ignoreErrorIfNoActiveWorkflow,omitempty"`

	// Parameters: Passed in as parameters to each workflow execution.
	// Optional.
	Parameters *EnterpriseCrmEventbusProtoEventParameters `json:"parameters,omitempty"`

	// Priority: The request priority this request should be processed at.
	// For internal users:
	//
	// Possible values:
	//   "UNSPCIFIED" - Unspecified
	//   "SHEDDABLE" - Frequent partial and occasional full unavailability
	// is expected and not pageable. * Requests to this band will be shed
	// before all other requests. * This is the default for async calls sent
	// from batch jobs.
	//   "SHEDDABLE_PLUS" - Partial unavailability is expected and is not
	// necessarily pageable. * Requests to this band will be shed before any
	// critical traffic. * This is the default for async calls sent from
	// production jobs.
	//   "CRITICAL" - Any outage is a pageable event. * During a production
	// outage requests in this band will only be shed before CRITICAL_PLUS.
	// * This is the default for sync calls sent from production jobs.
	//   "CRITICAL_PLUS" - Any outage is a pageable event. * The guideline
	// is for < 10% of requests to a service to be in this band. * During a
	// production outage requests in this band will be prioritized above all
	// others. * Opt-in to CRITICAL_PLUS when your workflow triggers by
	// human.
	Priority string `json:"priority,omitempty"`

	// RequestId: Optional. This is used to de-dup incoming request: if the
	// duplicate request was detected, the response from the previous
	// execution is returned. Must have no more than 36 characters and
	// contain only alphanumeric characters and hyphens.
	RequestId string `json:"requestId,omitempty"`

	// ResourceName: This field is only required when using Admin Access.
	// The resource name of target, or the parent resource name. For
	// example: "projects/*/locations/*/integrations/*"
	ResourceName string `json:"resourceName,omitempty"`

	// ScheduledTime: Optional. Time in milliseconds since epoch when the
	// given event would be scheduled.
	ScheduledTime int64 `json:"scheduledTime,omitempty,string"`

	// TestMode: Optional. Sets test mode in {@link
	// enterprise/crm/eventbus/event_message.proto}.
	TestMode bool `json:"testMode,omitempty"`

	// TriggerId: Matched against all {@link TriggerConfig}s across all
	// workflows. i.e. TriggerConfig.trigger_id.equals(trigger_id) Required.
	TriggerId string `json:"triggerId,omitempty"`

	// WorkflowName: Optional. If provided, the workflow_name is used to
	// filter all the matched workflows having same trigger_id+client_id. A
	// combination of trigger_id, client_id and workflow_name identifies a
	// unique workflow.
	WorkflowName string `json:"workflowName,omitempty"`

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

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

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

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

// IoCloudeventsV1CloudEvent: -- CloudEvent Context Attributes
type IoCloudeventsV1CloudEvent struct {
	// Attributes: Optional & Extension Attributes
	Attributes map[string]IoCloudeventsV1CloudEventCloudEventAttributeValue `json:"attributes,omitempty"`

	BinaryData string `json:"binaryData,omitempty"`

	// Id: Required Attributes
	Id string `json:"id,omitempty"`

	ProtoData googleapi.RawMessage `json:"protoData,omitempty"`

	// Source: URI-reference
	Source string `json:"source,omitempty"`

	SpecVersion string `json:"specVersion,omitempty"`

	TextData string `json:"textData,omitempty"`

	Type string `json:"type,omitempty"`

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

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

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

type IoCloudeventsV1CloudEventCloudEventAttributeValue struct {
	CeBoolean bool `json:"ceBoolean,omitempty"`

	CeBytes string `json:"ceBytes,omitempty"`

	CeInteger int64 `json:"ceInteger,omitempty"`

	CeString string `json:"ceString,omitempty"`

	CeTimestamp string `json:"ceTimestamp,omitempty"`

	CeUri string `json:"ceUri,omitempty"`

	CeUriRef string `json:"ceUriRef,omitempty"`

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

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

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

// method id "integrations.callback.generateToken":

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

// GenerateToken: Receives the auth code and auth config id to combine
// that with the client id and secret to retrieve access tokens from the
// token endpoint. Returns either a success or error message when it's
// done.
func (r *CallbackService) GenerateToken() *CallbackGenerateTokenCall {
	c := &CallbackGenerateTokenCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Code sets the optional parameter "code": The auth code for the given
// request
func (c *CallbackGenerateTokenCall) Code(code string) *CallbackGenerateTokenCall {
	c.urlParams_.Set("code", code)
	return c
}

// GcpProjectId sets the optional parameter "gcpProjectId": The gcp
// project id of the request
func (c *CallbackGenerateTokenCall) GcpProjectId(gcpProjectId string) *CallbackGenerateTokenCall {
	c.urlParams_.Set("gcpProjectId", gcpProjectId)
	return c
}

// Product sets the optional parameter "product": Which product sends
// the request
//
// Possible values:
//
//	"UNSPECIFIED_PRODUCT"
//	"IP"
//	"APIGEE"
//	"SECURITY"
func (c *CallbackGenerateTokenCall) Product(product string) *CallbackGenerateTokenCall {
	c.urlParams_.Set("product", product)
	return c
}

// RedirectUri sets the optional parameter "redirectUri": Redirect uri
// of the auth code request
func (c *CallbackGenerateTokenCall) RedirectUri(redirectUri string) *CallbackGenerateTokenCall {
	c.urlParams_.Set("redirectUri", redirectUri)
	return c
}

// State sets the optional parameter "state": The auth config id for the
// given request
func (c *CallbackGenerateTokenCall) State(state string) *CallbackGenerateTokenCall {
	c.urlParams_.Set("state", state)
	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 *CallbackGenerateTokenCall) Fields(s ...googleapi.Field) *CallbackGenerateTokenCall {
	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 *CallbackGenerateTokenCall) IfNoneMatch(entityTag string) *CallbackGenerateTokenCall {
	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 *CallbackGenerateTokenCall) Context(ctx context.Context) *CallbackGenerateTokenCall {
	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 *CallbackGenerateTokenCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.callback.generateToken" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaGenerateTokenResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaGenerateTokenResponse.ServerResponse.He
// ader 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 *CallbackGenerateTokenCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaGenerateTokenResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaGenerateTokenResponse{
		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": "Receives the auth code and auth config id to combine that with the client id and secret to retrieve access tokens from the token endpoint. Returns either a success or error message when it's done.",
	//   "flatPath": "v1alpha/callback:generateToken",
	//   "httpMethod": "GET",
	//   "id": "integrations.callback.generateToken",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "code": {
	//       "description": "The auth code for the given request",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "gcpProjectId": {
	//       "description": "The gcp project id of the request",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "product": {
	//       "description": "Which product sends the request",
	//       "enum": [
	//         "UNSPECIFIED_PRODUCT",
	//         "IP",
	//         "APIGEE",
	//         "SECURITY"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "redirectUri": {
	//       "description": "Redirect uri of the auth code request",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "state": {
	//       "description": "The auth config id for the given request",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/callback:generateToken",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaGenerateTokenResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.connectorPlatformRegions.enumerate":

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

// Enumerate: Enumerates the regions for which Connector Platform is
// provisioned.
func (r *ConnectorPlatformRegionsService) Enumerate() *ConnectorPlatformRegionsEnumerateCall {
	c := &ConnectorPlatformRegionsEnumerateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	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 *ConnectorPlatformRegionsEnumerateCall) Fields(s ...googleapi.Field) *ConnectorPlatformRegionsEnumerateCall {
	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 *ConnectorPlatformRegionsEnumerateCall) IfNoneMatch(entityTag string) *ConnectorPlatformRegionsEnumerateCall {
	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 *ConnectorPlatformRegionsEnumerateCall) Context(ctx context.Context) *ConnectorPlatformRegionsEnumerateCall {
	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 *ConnectorPlatformRegionsEnumerateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.connectorPlatformRegions.enumerate" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaEnumerateConnectorPlatformRegionsRespon
// se or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaEnumerateConnectorPlatformRegionsRespon
// se.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 *ConnectorPlatformRegionsEnumerateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaEnumerateConnectorPlatformRegionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaEnumerateConnectorPlatformRegionsResponse{
		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": "Enumerates the regions for which Connector Platform is provisioned.",
	//   "flatPath": "v1alpha/connectorPlatformRegions:enumerate",
	//   "httpMethod": "GET",
	//   "id": "integrations.connectorPlatformRegions.enumerate",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha/connectorPlatformRegions:enumerate",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaEnumerateConnectorPlatformRegionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.appsScriptProjects.create":

type ProjectsLocationsAppsScriptProjectsCreateCall struct {
	s                                                            *Service
	parent                                                       string
	googlecloudintegrationsv1alphacreateappsscriptprojectrequest *GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectRequest
	urlParams_                                                   gensupport.URLParams
	ctx_                                                         context.Context
	header_                                                      http.Header
}

// Create: Creates an Apps Script project.
//
// - parent: The project that the executed integration belongs to.
func (r *ProjectsLocationsAppsScriptProjectsService) Create(parent string, googlecloudintegrationsv1alphacreateappsscriptprojectrequest *GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectRequest) *ProjectsLocationsAppsScriptProjectsCreateCall {
	c := &ProjectsLocationsAppsScriptProjectsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphacreateappsscriptprojectrequest = googlecloudintegrationsv1alphacreateappsscriptprojectrequest
	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 *ProjectsLocationsAppsScriptProjectsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsAppsScriptProjectsCreateCall {
	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 *ProjectsLocationsAppsScriptProjectsCreateCall) Context(ctx context.Context) *ProjectsLocationsAppsScriptProjectsCreateCall {
	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 *ProjectsLocationsAppsScriptProjectsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsAppsScriptProjectsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphacreateappsscriptprojectrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/appsScriptProjects")
	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 "integrations.projects.locations.appsScriptProjects.create" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectResponse.ServerR
// esponse.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 *ProjectsLocationsAppsScriptProjectsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectResponse{
		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 an Apps Script project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/appsScriptProjects",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.appsScriptProjects.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project that the executed integration belongs to.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/appsScriptProjects",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCreateAppsScriptProjectResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.appsScriptProjects.link":

type ProjectsLocationsAppsScriptProjectsLinkCall struct {
	s                                                          *Service
	parent                                                     string
	googlecloudintegrationsv1alphalinkappsscriptprojectrequest *GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectRequest
	urlParams_                                                 gensupport.URLParams
	ctx_                                                       context.Context
	header_                                                    http.Header
}

// Link: Links a existing Apps Script project.
//
// - parent: The project that the executed integration belongs to.
func (r *ProjectsLocationsAppsScriptProjectsService) Link(parent string, googlecloudintegrationsv1alphalinkappsscriptprojectrequest *GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectRequest) *ProjectsLocationsAppsScriptProjectsLinkCall {
	c := &ProjectsLocationsAppsScriptProjectsLinkCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphalinkappsscriptprojectrequest = googlecloudintegrationsv1alphalinkappsscriptprojectrequest
	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 *ProjectsLocationsAppsScriptProjectsLinkCall) Fields(s ...googleapi.Field) *ProjectsLocationsAppsScriptProjectsLinkCall {
	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 *ProjectsLocationsAppsScriptProjectsLinkCall) Context(ctx context.Context) *ProjectsLocationsAppsScriptProjectsLinkCall {
	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 *ProjectsLocationsAppsScriptProjectsLinkCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsAppsScriptProjectsLinkCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphalinkappsscriptprojectrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/appsScriptProjects:link")
	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 "integrations.projects.locations.appsScriptProjects.link" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectResponse.ServerRes
// ponse.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 *ProjectsLocationsAppsScriptProjectsLinkCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectResponse{
		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": "Links a existing Apps Script project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/appsScriptProjects:link",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.appsScriptProjects.link",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project that the executed integration belongs to.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/appsScriptProjects:link",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaLinkAppsScriptProjectResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.authConfigs.create":

type ProjectsLocationsAuthConfigsCreateCall struct {
	s                                        *Service
	parent                                   string
	googlecloudintegrationsv1alphaauthconfig *GoogleCloudIntegrationsV1alphaAuthConfig
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// Create: Creates an auth config record. Fetch corresponding
// credentials for specific auth types, e.g. access token for OAuth 2.0,
// JWT token for JWT. Encrypt the auth config with Cloud KMS and store
// the encrypted credentials in Spanner. Returns the encrypted auth
// config.
//
// - parent: "projects/{project}/locations/{location}" format.
func (r *ProjectsLocationsAuthConfigsService) Create(parent string, googlecloudintegrationsv1alphaauthconfig *GoogleCloudIntegrationsV1alphaAuthConfig) *ProjectsLocationsAuthConfigsCreateCall {
	c := &ProjectsLocationsAuthConfigsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphaauthconfig = googlecloudintegrationsv1alphaauthconfig
	return c
}

// ClientCertificateEncryptedPrivateKey sets the optional parameter
// "clientCertificate.encryptedPrivateKey": The ssl certificate encoded
// in PEM format. This string must include the begin header and end
// footer lines. For example, -----BEGIN CERTIFICATE-----
// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
func (c *ProjectsLocationsAuthConfigsCreateCall) ClientCertificateEncryptedPrivateKey(clientCertificateEncryptedPrivateKey string) *ProjectsLocationsAuthConfigsCreateCall {
	c.urlParams_.Set("clientCertificate.encryptedPrivateKey", clientCertificateEncryptedPrivateKey)
	return c
}

// ClientCertificatePassphrase sets the optional parameter
// "clientCertificate.passphrase": 'passphrase' should be left unset if
// private key is not encrypted. Note that 'passphrase' is not the
// password for web server, but an extra layer of security to protected
// private key.
func (c *ProjectsLocationsAuthConfigsCreateCall) ClientCertificatePassphrase(clientCertificatePassphrase string) *ProjectsLocationsAuthConfigsCreateCall {
	c.urlParams_.Set("clientCertificate.passphrase", clientCertificatePassphrase)
	return c
}

// ClientCertificateSslCertificate sets the optional parameter
// "clientCertificate.sslCertificate": The ssl certificate encoded in
// PEM format. This string must include the begin header and end footer
// lines. For example, -----BEGIN CERTIFICATE-----
// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
func (c *ProjectsLocationsAuthConfigsCreateCall) ClientCertificateSslCertificate(clientCertificateSslCertificate string) *ProjectsLocationsAuthConfigsCreateCall {
	c.urlParams_.Set("clientCertificate.sslCertificate", clientCertificateSslCertificate)
	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 *ProjectsLocationsAuthConfigsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsAuthConfigsCreateCall {
	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 *ProjectsLocationsAuthConfigsCreateCall) Context(ctx context.Context) *ProjectsLocationsAuthConfigsCreateCall {
	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 *ProjectsLocationsAuthConfigsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsAuthConfigsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaauthconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/authConfigs")
	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 "integrations.projects.locations.authConfigs.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaAuthConfig or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaAuthConfig.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 *ProjectsLocationsAuthConfigsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaAuthConfig, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaAuthConfig{
		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 an auth config record. Fetch corresponding credentials for specific auth types, e.g. access token for OAuth 2.0, JWT token for JWT. Encrypt the auth config with Cloud KMS and store the encrypted credentials in Spanner. Returns the encrypted auth config.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/authConfigs",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.authConfigs.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "clientCertificate.encryptedPrivateKey": {
	//       "description": "The ssl certificate encoded in PEM format. This string must include the begin header and end footer lines. For example, -----BEGIN CERTIFICATE----- MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1 JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientCertificate.passphrase": {
	//       "description": "'passphrase' should be left unset if private key is not encrypted. Note that 'passphrase' is not the password for web server, but an extra layer of security to protected private key.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientCertificate.sslCertificate": {
	//       "description": "The ssl certificate encoded in PEM format. This string must include the begin header and end footer lines. For example, -----BEGIN CERTIFICATE----- MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1 JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. \"projects/{project}/locations/{location}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/authConfigs",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.authConfigs.delete":

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

// Delete: Deletes an auth config.
//
// - name: The name that is associated with the AuthConfig.
func (r *ProjectsLocationsAuthConfigsService) Delete(name string) *ProjectsLocationsAuthConfigsDeleteCall {
	c := &ProjectsLocationsAuthConfigsDeleteCall{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 *ProjectsLocationsAuthConfigsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsAuthConfigsDeleteCall {
	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 *ProjectsLocationsAuthConfigsDeleteCall) Context(ctx context.Context) *ProjectsLocationsAuthConfigsDeleteCall {
	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 *ProjectsLocationsAuthConfigsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.authConfigs.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsAuthConfigsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an auth config.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/authConfigs/{authConfigsId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.authConfigs.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the AuthConfig.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/authConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.authConfigs.get":

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

// Get: Gets a complete auth config. If the auth config doesn't exist,
// Code.NOT_FOUND exception will be thrown. Returns the decrypted auth
// config.
//
// - name: The name that is associated with the AuthConfig.
func (r *ProjectsLocationsAuthConfigsService) Get(name string) *ProjectsLocationsAuthConfigsGetCall {
	c := &ProjectsLocationsAuthConfigsGetCall{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 *ProjectsLocationsAuthConfigsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsAuthConfigsGetCall {
	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 *ProjectsLocationsAuthConfigsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsAuthConfigsGetCall {
	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 *ProjectsLocationsAuthConfigsGetCall) Context(ctx context.Context) *ProjectsLocationsAuthConfigsGetCall {
	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 *ProjectsLocationsAuthConfigsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.authConfigs.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaAuthConfig or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaAuthConfig.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 *ProjectsLocationsAuthConfigsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaAuthConfig, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaAuthConfig{
		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 a complete auth config. If the auth config doesn't exist, Code.NOT_FOUND exception will be thrown. Returns the decrypted auth config.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/authConfigs/{authConfigsId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.authConfigs.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the AuthConfig.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/authConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.authConfigs.list":

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

// List: Lists all auth configs that match the filter. Restrict to auth
// configs belong to the current client only.
//
// - parent: The client, which owns this collection of AuthConfigs.
func (r *ProjectsLocationsAuthConfigsService) List(parent string) *ProjectsLocationsAuthConfigsListCall {
	c := &ProjectsLocationsAuthConfigsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filtering as supported
// in
// https://developers.google.com/authorized-buyers/apis/guides/list-filters.
func (c *ProjectsLocationsAuthConfigsListCall) Filter(filter string) *ProjectsLocationsAuthConfigsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response. If unspecified, defaults to 100.
func (c *ProjectsLocationsAuthConfigsListCall) PageSize(pageSize int64) *ProjectsLocationsAuthConfigsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsAuthConfigsListCall) PageToken(pageToken string) *ProjectsLocationsAuthConfigsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": The mask which
// specifies fields that need to be returned in the AuthConfig's
// response.
func (c *ProjectsLocationsAuthConfigsListCall) ReadMask(readMask string) *ProjectsLocationsAuthConfigsListCall {
	c.urlParams_.Set("readMask", readMask)
	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 *ProjectsLocationsAuthConfigsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsAuthConfigsListCall {
	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 *ProjectsLocationsAuthConfigsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsAuthConfigsListCall {
	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 *ProjectsLocationsAuthConfigsListCall) Context(ctx context.Context) *ProjectsLocationsAuthConfigsListCall {
	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 *ProjectsLocationsAuthConfigsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsAuthConfigsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/authConfigs")
	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 "integrations.projects.locations.authConfigs.list" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaListAuthConfigsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaListAuthConfigsResponse.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 *ProjectsLocationsAuthConfigsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListAuthConfigsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListAuthConfigsResponse{
		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 all auth configs that match the filter. Restrict to auth configs belong to the current client only.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/authConfigs",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.authConfigs.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filtering as supported in https://developers.google.com/authorized-buyers/apis/guides/list-filters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The size of entries in the response. If unspecified, defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The client, which owns this collection of AuthConfigs.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "The mask which specifies fields that need to be returned in the AuthConfig's response.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/authConfigs",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListAuthConfigsResponse"
	//   },
	//   "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 *ProjectsLocationsAuthConfigsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListAuthConfigsResponse) 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 "integrations.projects.locations.authConfigs.patch":

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

// Patch: Updates an auth config. If credential is updated, fetch the
// encrypted auth config from Spanner, decrypt with Cloud KMS key,
// update the credential fields, re-encrypt with Cloud KMS key and
// update the Spanner record. For other fields, directly update the
// Spanner record. Returns the encrypted auth config.
//
//   - name: Resource name of the SFDC instance
//     projects/{project}/locations/{location}/authConfigs/{authConfig}.
func (r *ProjectsLocationsAuthConfigsService) Patch(name string, googlecloudintegrationsv1alphaauthconfig *GoogleCloudIntegrationsV1alphaAuthConfig) *ProjectsLocationsAuthConfigsPatchCall {
	c := &ProjectsLocationsAuthConfigsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaauthconfig = googlecloudintegrationsv1alphaauthconfig
	return c
}

// ClientCertificateEncryptedPrivateKey sets the optional parameter
// "clientCertificate.encryptedPrivateKey": The ssl certificate encoded
// in PEM format. This string must include the begin header and end
// footer lines. For example, -----BEGIN CERTIFICATE-----
// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
func (c *ProjectsLocationsAuthConfigsPatchCall) ClientCertificateEncryptedPrivateKey(clientCertificateEncryptedPrivateKey string) *ProjectsLocationsAuthConfigsPatchCall {
	c.urlParams_.Set("clientCertificate.encryptedPrivateKey", clientCertificateEncryptedPrivateKey)
	return c
}

// ClientCertificatePassphrase sets the optional parameter
// "clientCertificate.passphrase": 'passphrase' should be left unset if
// private key is not encrypted. Note that 'passphrase' is not the
// password for web server, but an extra layer of security to protected
// private key.
func (c *ProjectsLocationsAuthConfigsPatchCall) ClientCertificatePassphrase(clientCertificatePassphrase string) *ProjectsLocationsAuthConfigsPatchCall {
	c.urlParams_.Set("clientCertificate.passphrase", clientCertificatePassphrase)
	return c
}

// ClientCertificateSslCertificate sets the optional parameter
// "clientCertificate.sslCertificate": The ssl certificate encoded in
// PEM format. This string must include the begin header and end footer
// lines. For example, -----BEGIN CERTIFICATE-----
// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
func (c *ProjectsLocationsAuthConfigsPatchCall) ClientCertificateSslCertificate(clientCertificateSslCertificate string) *ProjectsLocationsAuthConfigsPatchCall {
	c.urlParams_.Set("clientCertificate.sslCertificate", clientCertificateSslCertificate)
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above AuthConfig that have been modified
// and need to be updated.
func (c *ProjectsLocationsAuthConfigsPatchCall) UpdateMask(updateMask string) *ProjectsLocationsAuthConfigsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.authConfigs.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaAuthConfig or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaAuthConfig.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 *ProjectsLocationsAuthConfigsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaAuthConfig, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaAuthConfig{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an auth config. If credential is updated, fetch the encrypted auth config from Spanner, decrypt with Cloud KMS key, update the credential fields, re-encrypt with Cloud KMS key and update the Spanner record. For other fields, directly update the Spanner record. Returns the encrypted auth config.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/authConfigs/{authConfigsId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.authConfigs.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "clientCertificate.encryptedPrivateKey": {
	//       "description": "The ssl certificate encoded in PEM format. This string must include the begin header and end footer lines. For example, -----BEGIN CERTIFICATE----- MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1 JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientCertificate.passphrase": {
	//       "description": "'passphrase' should be left unset if private key is not encrypted. Note that 'passphrase' is not the password for web server, but an extra layer of security to protected private key.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientCertificate.sslCertificate": {
	//       "description": "The ssl certificate encoded in PEM format. This string must include the begin header and end footer lines. For example, -----BEGIN CERTIFICATE----- MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1 JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Resource name of the SFDC instance projects/{project}/locations/{location}/authConfigs/{authConfig}.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/authConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above AuthConfig that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.certificates.get":

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

// Get: Get a certificates in the specified project.
//
//   - name: The certificate to retrieve. Format:
//     projects/{project}/locations/{location}/certificates/{certificate}.
func (r *ProjectsLocationsCertificatesService) Get(name string) *ProjectsLocationsCertificatesGetCall {
	c := &ProjectsLocationsCertificatesGetCall{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 *ProjectsLocationsCertificatesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsCertificatesGetCall {
	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 *ProjectsLocationsCertificatesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsCertificatesGetCall {
	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 *ProjectsLocationsCertificatesGetCall) Context(ctx context.Context) *ProjectsLocationsCertificatesGetCall {
	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 *ProjectsLocationsCertificatesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.certificates.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaCertificate or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaCertificate.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 *ProjectsLocationsCertificatesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaCertificate, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaCertificate{
		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 a certificates in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/certificates/{certificatesId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.certificates.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The certificate to retrieve. Format: projects/{project}/locations/{location}/certificates/{certificate}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/certificates/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCertificate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.connections.getConnectionSchemaMetadata":

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

// GetConnectionSchemaMetadata: Lists the available entities and actions
// associated with a Connection.
//
//   - name: ConnectionSchemaMetadata name. Format:
//     projects/{project}/locations/{location}/connections/{connection}/con
//     nectionSchemaMetadata.
func (r *ProjectsLocationsConnectionsService) GetConnectionSchemaMetadata(name string) *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall {
	c := &ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall{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 *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall) Fields(s ...googleapi.Field) *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall {
	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 *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall) IfNoneMatch(entityTag string) *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall {
	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 *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall) Context(ctx context.Context) *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall {
	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 *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.connections.getConnectionSchemaMetadata" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaConnectionSchemaMetadata or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaConnectionSchemaMetadata.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 *ProjectsLocationsConnectionsGetConnectionSchemaMetadataCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaConnectionSchemaMetadata, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaConnectionSchemaMetadata{
		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 the available entities and actions associated with a Connection.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/connections/{connectionsId}/connectionSchemaMetadata",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.connections.getConnectionSchemaMetadata",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. ConnectionSchemaMetadata name. Format: projects/{project}/locations/{location}/connections/{connection}/connectionSchemaMetadata",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/connections/[^/]+/connectionSchemaMetadata$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaConnectionSchemaMetadata"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.connections.list":

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

// List: Lists Connections in a given project and location.
//
//   - parent: Parent resource of the Connection, of the form:
//     `projects/*/locations/*`.
func (r *ProjectsLocationsConnectionsService) List(parent string) *ProjectsLocationsConnectionsListCall {
	c := &ProjectsLocationsConnectionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filter.
func (c *ProjectsLocationsConnectionsListCall) Filter(filter string) *ProjectsLocationsConnectionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Order by parameters.
func (c *ProjectsLocationsConnectionsListCall) OrderBy(orderBy string) *ProjectsLocationsConnectionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Page size.
func (c *ProjectsLocationsConnectionsListCall) PageSize(pageSize int64) *ProjectsLocationsConnectionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

func (c *ProjectsLocationsConnectionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/connections")
	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 "integrations.projects.locations.connections.list" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaListConnectionsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaListConnectionsResponse.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 *ProjectsLocationsConnectionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListConnectionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListConnectionsResponse{
		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 Connections in a given project and location.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/connections",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.connections.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Order by parameters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Parent resource of the Connection, of the form: `projects/*/locations/*`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/connections",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListConnectionsResponse"
	//   },
	//   "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 *ProjectsLocationsConnectionsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListConnectionsResponse) 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 "integrations.projects.locations.connections.runtimeActionSchemas.list":

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

// List: Lists the JSON schemas for the inputs and outputs of actions,
// filtered by action name.
//
//   - parent: Parent resource of RuntimeActionSchema. Format:
//     projects/{project}/locations/{location}/connections/{connection}.
func (r *ProjectsLocationsConnectionsRuntimeActionSchemasService) List(parent string) *ProjectsLocationsConnectionsRuntimeActionSchemasListCall {
	c := &ProjectsLocationsConnectionsRuntimeActionSchemasListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filter. Only the action
// field with literal equality operator is supported.
func (c *ProjectsLocationsConnectionsRuntimeActionSchemasListCall) Filter(filter string) *ProjectsLocationsConnectionsRuntimeActionSchemasListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": Page size.
func (c *ProjectsLocationsConnectionsRuntimeActionSchemasListCall) PageSize(pageSize int64) *ProjectsLocationsConnectionsRuntimeActionSchemasListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

func (c *ProjectsLocationsConnectionsRuntimeActionSchemasListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/runtimeActionSchemas")
	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 "integrations.projects.locations.connections.runtimeActionSchemas.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListRuntimeActionSchemasResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaListRuntimeActionSchemasResponse.Server
// Response.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 *ProjectsLocationsConnectionsRuntimeActionSchemasListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListRuntimeActionSchemasResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListRuntimeActionSchemasResponse{
		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 the JSON schemas for the inputs and outputs of actions, filtered by action name.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/connections/{connectionsId}/runtimeActionSchemas",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.connections.runtimeActionSchemas.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filter. Only the action field with literal equality operator is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Parent resource of RuntimeActionSchema. Format: projects/{project}/locations/{location}/connections/{connection}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/connections/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/runtimeActionSchemas",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListRuntimeActionSchemasResponse"
	//   },
	//   "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 *ProjectsLocationsConnectionsRuntimeActionSchemasListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListRuntimeActionSchemasResponse) 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 "integrations.projects.locations.connections.runtimeEntitySchemas.list":

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

// List: Lists the JSON schemas for the properties of runtime entities,
// filtered by entity name.
//
//   - parent: Parent resource of RuntimeEntitySchema. Format:
//     projects/{project}/locations/{location}/connections/{connection}.
func (r *ProjectsLocationsConnectionsRuntimeEntitySchemasService) List(parent string) *ProjectsLocationsConnectionsRuntimeEntitySchemasListCall {
	c := &ProjectsLocationsConnectionsRuntimeEntitySchemasListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filter. Only the entity
// field with literal equality operator is supported.
func (c *ProjectsLocationsConnectionsRuntimeEntitySchemasListCall) Filter(filter string) *ProjectsLocationsConnectionsRuntimeEntitySchemasListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": Page size.
func (c *ProjectsLocationsConnectionsRuntimeEntitySchemasListCall) PageSize(pageSize int64) *ProjectsLocationsConnectionsRuntimeEntitySchemasListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

func (c *ProjectsLocationsConnectionsRuntimeEntitySchemasListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/runtimeEntitySchemas")
	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 "integrations.projects.locations.connections.runtimeEntitySchemas.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListRuntimeEntitySchemasResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaListRuntimeEntitySchemasResponse.Server
// Response.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 *ProjectsLocationsConnectionsRuntimeEntitySchemasListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListRuntimeEntitySchemasResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListRuntimeEntitySchemasResponse{
		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 the JSON schemas for the properties of runtime entities, filtered by entity name.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/connections/{connectionsId}/runtimeEntitySchemas",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.connections.runtimeEntitySchemas.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filter. Only the entity field with literal equality operator is supported.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Parent resource of RuntimeEntitySchema. Format: projects/{project}/locations/{location}/connections/{connection}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/connections/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/runtimeEntitySchemas",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListRuntimeEntitySchemasResponse"
	//   },
	//   "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 *ProjectsLocationsConnectionsRuntimeEntitySchemasListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListRuntimeEntitySchemasResponse) 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 "integrations.projects.locations.integrations.delete":

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

// Delete: Delete the selected integration and all versions inside
//
// - name: The location resource of the request.
func (r *ProjectsLocationsIntegrationsService) Delete(name string) *ProjectsLocationsIntegrationsDeleteCall {
	c := &ProjectsLocationsIntegrationsDeleteCall{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 *ProjectsLocationsIntegrationsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsDeleteCall {
	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 *ProjectsLocationsIntegrationsDeleteCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsDeleteCall {
	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 *ProjectsLocationsIntegrationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.integrations.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsIntegrationsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		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 the selected integration and all versions inside",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.integrations.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The location resource of the request.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.execute":

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

// Execute: Executes integrations synchronously by passing the trigger
// id in the request body. The request is not returned until the
// requested executions are either fulfilled or experienced an error. If
// the integration name is not specified (passing `-`), all of the
// associated integration under the given trigger_id will be executed.
// Otherwise only the specified integration for the given `trigger_id`
// is executed. This is helpful for execution the integration from UI.
//
// - name: The integration resource name.
func (r *ProjectsLocationsIntegrationsService) Execute(name string, googlecloudintegrationsv1alphaexecuteintegrationsrequest *GoogleCloudIntegrationsV1alphaExecuteIntegrationsRequest) *ProjectsLocationsIntegrationsExecuteCall {
	c := &ProjectsLocationsIntegrationsExecuteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaexecuteintegrationsrequest = googlecloudintegrationsv1alphaexecuteintegrationsrequest
	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 *ProjectsLocationsIntegrationsExecuteCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsExecuteCall {
	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 *ProjectsLocationsIntegrationsExecuteCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsExecuteCall {
	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 *ProjectsLocationsIntegrationsExecuteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsExecuteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaexecuteintegrationsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:execute")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.integrations.execute" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse.ServerRespo
// nse.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 *ProjectsLocationsIntegrationsExecuteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse{
		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": "Executes integrations synchronously by passing the trigger id in the request body. The request is not returned until the requested executions are either fulfilled or experienced an error. If the integration name is not specified (passing `-`), all of the associated integration under the given trigger_id will be executed. Otherwise only the specified integration for the given `trigger_id` is executed. This is helpful for execution the integration from UI.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}:execute",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.execute",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The integration resource name.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:execute",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaExecuteIntegrationsRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.executeEvent":

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

// ExecuteEvent: Executes an integration on receiving events from
// Integration Connector triggers, Eventarc or CPS Trigger. The details
// about integration are derived from CloudEvent request body.
//
//   - name: The integration resource name. Format:
//     projects/{gcp_project_id}/locations/{location}/integrations/{integra
//     tion_id}.
func (r *ProjectsLocationsIntegrationsService) ExecuteEvent(name string, googlecloudintegrationsv1alphaexecuteeventrequest *GoogleCloudIntegrationsV1alphaExecuteEventRequest) *ProjectsLocationsIntegrationsExecuteEventCall {
	c := &ProjectsLocationsIntegrationsExecuteEventCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaexecuteeventrequest = googlecloudintegrationsv1alphaexecuteeventrequest
	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 *ProjectsLocationsIntegrationsExecuteEventCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsExecuteEventCall {
	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 *ProjectsLocationsIntegrationsExecuteEventCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsExecuteEventCall {
	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 *ProjectsLocationsIntegrationsExecuteEventCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsExecuteEventCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaexecuteeventrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:executeEvent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.integrations.executeEvent" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaExecuteEventResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaExecuteEventResponse.ServerResponse.Hea
// der 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 *ProjectsLocationsIntegrationsExecuteEventCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaExecuteEventResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaExecuteEventResponse{
		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": "Executes an integration on receiving events from Integration Connector triggers, Eventarc or CPS Trigger. The details about integration are derived from CloudEvent request body.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}:executeEvent",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.executeEvent",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The integration resource name. Format: projects/{gcp_project_id}/locations/{location}/integrations/{integration_id}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:executeEvent",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaExecuteEventRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaExecuteEventResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.list":

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

// List: Returns the list of all integrations in the specified project.
//
//   - parent: Project and location from which the integrations should be
//     listed. Format: projects/{project}.
func (r *ProjectsLocationsIntegrationsService) List(parent string) *ProjectsLocationsIntegrationsListCall {
	c := &ProjectsLocationsIntegrationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filter on fields of
// IntegrationVersion. Fields can be compared with literal values by use
// of ":" (containment), "=" (equality), ">" (greater), "<" (less than),
// >=" (greater than or equal to), "<=" (less than or equal to), and
// "!=" (inequality) operators. Negation, conjunction, and disjunction
// are written using NOT, AND, and OR keywords. For example,
// organization_id=\"1\" AND state=ACTIVE AND description:"test".
// Filtering cannot be performed on repeated fields like `task_config`.
func (c *ProjectsLocationsIntegrationsListCall) Filter(filter string) *ProjectsLocationsIntegrationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": The results would be
// returned in order you specified here. Supported sort keys are:
// Descending sort order by "last_modified_time", "created_time",
// "snapshot_number". Ascending sort order by the integration name.
func (c *ProjectsLocationsIntegrationsListCall) OrderBy(orderBy string) *ProjectsLocationsIntegrationsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The page size for
// the resquest.
func (c *ProjectsLocationsIntegrationsListCall) PageSize(pageSize int64) *ProjectsLocationsIntegrationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

func (c *ProjectsLocationsIntegrationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/integrations")
	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 "integrations.projects.locations.integrations.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListIntegrationsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaListIntegrationsResponse.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 *ProjectsLocationsIntegrationsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListIntegrationsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListIntegrationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the list of all integrations in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.integrations.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filter on fields of IntegrationVersion. Fields can be compared with literal values by use of \":\" (containment), \"=\" (equality), \"\u003e\" (greater), \"\u003c\" (less than), \u003e=\" (greater than or equal to), \"\u003c=\" (less than or equal to), and \"!=\" (inequality) operators. Negation, conjunction, and disjunction are written using NOT, AND, and OR keywords. For example, organization_id=\\\"1\\\" AND state=ACTIVE AND description:\"test\". Filtering cannot be performed on repeated fields like `task_config`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "The results would be returned in order you specified here. Supported sort keys are: Descending sort order by \"last_modified_time\", \"created_time\", \"snapshot_number\". Ascending sort order by the integration name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The page size for the resquest.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The page token for the resquest.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Project and location from which the integrations should be listed. Format: projects/{project}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/integrations",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListIntegrationsResponse"
	//   },
	//   "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 *ProjectsLocationsIntegrationsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListIntegrationsResponse) 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 "integrations.projects.locations.integrations.schedule":

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

// Schedule: Schedules an integration for execution by passing the
// trigger id and the scheduled time in the request body.
//
// - name: The integration resource name.
func (r *ProjectsLocationsIntegrationsService) Schedule(name string, googlecloudintegrationsv1alphascheduleintegrationsrequest *GoogleCloudIntegrationsV1alphaScheduleIntegrationsRequest) *ProjectsLocationsIntegrationsScheduleCall {
	c := &ProjectsLocationsIntegrationsScheduleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphascheduleintegrationsrequest = googlecloudintegrationsv1alphascheduleintegrationsrequest
	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 *ProjectsLocationsIntegrationsScheduleCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsScheduleCall {
	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 *ProjectsLocationsIntegrationsScheduleCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsScheduleCall {
	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 *ProjectsLocationsIntegrationsScheduleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsScheduleCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphascheduleintegrationsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:schedule")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.integrations.schedule" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse.ServerResp
// onse.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 *ProjectsLocationsIntegrationsScheduleCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse{
		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": "Schedules an integration for execution by passing the trigger id and the scheduled time in the request body.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}:schedule",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.schedule",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The integration resource name.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:schedule",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaScheduleIntegrationsRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.executions.list":

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

// List: Lists the results of all the integration executions. The
// response includes the same information as the execution log
// (https://cloud.google.com/application-integration/docs/viewing-logs)
// in the Integration UI.
//
// - parent: The parent resource name of the integration execution.
func (r *ProjectsLocationsIntegrationsExecutionsService) List(parent string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c := &ProjectsLocationsIntegrationsExecutionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Standard filter field,
// we support filtering on following fields: workflow_name: the name of
// the integration. CreateTimestamp: the execution created time.
// event_execution_state: the state of the executions. execution_id: the
// id of the execution. trigger_id: the id of the trigger.
// parameter_type: the type of the parameters involved in the execution.
// All fields support for EQUALS, in additional: CreateTimestamp support
// for LESS_THAN, GREATER_THAN ParameterType support for HAS For
// example: "parameter_type" HAS \"string\" Also supports operators like
// AND, OR, NOT For example, trigger_id=\"id1\" AND
// workflow_name=\"testWorkflow\"
func (c *ProjectsLocationsIntegrationsExecutionsListCall) Filter(filter string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// FilterParamsCustomFilter sets the optional parameter
// "filterParams.customFilter": Optional user-provided custom filter.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsCustomFilter(filterParamsCustomFilter string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.customFilter", filterParamsCustomFilter)
	return c
}

// FilterParamsEndTime sets the optional parameter
// "filterParams.endTime": End timestamp.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsEndTime(filterParamsEndTime int64) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.endTime", fmt.Sprint(filterParamsEndTime))
	return c
}

// FilterParamsEventStatuses sets the optional parameter
// "filterParams.eventStatuses": List of possible event statuses.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsEventStatuses(filterParamsEventStatuses ...string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.SetMulti("filterParams.eventStatuses", append([]string{}, filterParamsEventStatuses...))
	return c
}

// FilterParamsExecutionId sets the optional parameter
// "filterParams.executionId": Execution id.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsExecutionId(filterParamsExecutionId string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.executionId", filterParamsExecutionId)
	return c
}

// FilterParamsParameterKey sets the optional parameter
// "filterParams.parameterKey": Param key. DEPRECATED. User
// parameter_pair_key instead.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsParameterKey(filterParamsParameterKey string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterKey", filterParamsParameterKey)
	return c
}

// FilterParamsParameterPairKey sets the optional parameter
// "filterParams.parameterPairKey": Param key in the key value pair
// filter.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsParameterPairKey(filterParamsParameterPairKey string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterPairKey", filterParamsParameterPairKey)
	return c
}

// FilterParamsParameterPairValue sets the optional parameter
// "filterParams.parameterPairValue": Param value in the key value pair
// filter.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsParameterPairValue(filterParamsParameterPairValue string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterPairValue", filterParamsParameterPairValue)
	return c
}

// FilterParamsParameterType sets the optional parameter
// "filterParams.parameterType": Param type.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsParameterType(filterParamsParameterType string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterType", filterParamsParameterType)
	return c
}

// FilterParamsParameterValue sets the optional parameter
// "filterParams.parameterValue": Param value. DEPRECATED. User
// parameter_pair_value instead.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsParameterValue(filterParamsParameterValue string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterValue", filterParamsParameterValue)
	return c
}

// FilterParamsStartTime sets the optional parameter
// "filterParams.startTime": Start timestamp.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsStartTime(filterParamsStartTime int64) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.startTime", fmt.Sprint(filterParamsStartTime))
	return c
}

// FilterParamsTaskStatuses sets the optional parameter
// "filterParams.taskStatuses": List of possible task statuses.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsTaskStatuses(filterParamsTaskStatuses ...string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.SetMulti("filterParams.taskStatuses", append([]string{}, filterParamsTaskStatuses...))
	return c
}

// FilterParamsWorkflowName sets the optional parameter
// "filterParams.workflowName": Workflow name.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) FilterParamsWorkflowName(filterParamsWorkflowName string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.workflowName", filterParamsWorkflowName)
	return c
}

// OrderBy sets the optional parameter "orderBy": The results would be
// returned in order you specified here. Currently supporting
// "last_modified_time" and "create_time".
func (c *ProjectsLocationsIntegrationsExecutionsListCall) OrderBy(orderBy string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) PageSize(pageSize int64) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) PageToken(pageToken string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": View mask for the
// response data. If set, only the field specified will be returned as
// part of the result. If not set, all fields in event execution info
// will be filled and returned.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) ReadMask(readMask string) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("readMask", readMask)
	return c
}

// RefreshAcl sets the optional parameter "refreshAcl": If true, the
// service will use the most recent acl information to list event
// execution infos and renew the acl cache. Note that fetching the most
// recent acl is synchronous, so it will increase RPC call latency.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) RefreshAcl(refreshAcl bool) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("refreshAcl", fmt.Sprint(refreshAcl))
	return c
}

// TruncateParams sets the optional parameter "truncateParams": If true,
// the service will truncate the params to only keep the first 1000
// characters of string params and empty the executions in order to make
// response smaller. Only works for UI and when the params fields are
// not filtered out.
func (c *ProjectsLocationsIntegrationsExecutionsListCall) TruncateParams(truncateParams bool) *ProjectsLocationsIntegrationsExecutionsListCall {
	c.urlParams_.Set("truncateParams", fmt.Sprint(truncateParams))
	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 *ProjectsLocationsIntegrationsExecutionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsExecutionsListCall {
	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 *ProjectsLocationsIntegrationsExecutionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsIntegrationsExecutionsListCall {
	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 *ProjectsLocationsIntegrationsExecutionsListCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsExecutionsListCall {
	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 *ProjectsLocationsIntegrationsExecutionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsExecutionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/executions")
	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 "integrations.projects.locations.integrations.executions.list" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaListExecutionsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaListExecutionsResponse.ServerResponse.H
// eader 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 *ProjectsLocationsIntegrationsExecutionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListExecutionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListExecutionsResponse{
		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 the results of all the integration executions. The response includes the same information as the [execution log](https://cloud.google.com/application-integration/docs/viewing-logs) in the Integration UI.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/executions",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.integrations.executions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Optional. Standard filter field, we support filtering on following fields: workflow_name: the name of the integration. CreateTimestamp: the execution created time. event_execution_state: the state of the executions. execution_id: the id of the execution. trigger_id: the id of the trigger. parameter_type: the type of the parameters involved in the execution. All fields support for EQUALS, in additional: CreateTimestamp support for LESS_THAN, GREATER_THAN ParameterType support for HAS For example: \"parameter_type\" HAS \\\"string\\\" Also supports operators like AND, OR, NOT For example, trigger_id=\\\"id1\\\" AND workflow_name=\\\"testWorkflow\\\"",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.customFilter": {
	//       "description": "Optional user-provided custom filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.endTime": {
	//       "description": "End timestamp.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.eventStatuses": {
	//       "description": "List of possible event statuses.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "filterParams.executionId": {
	//       "description": "Execution id.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterKey": {
	//       "deprecated": true,
	//       "description": "Param key. DEPRECATED. User parameter_pair_key instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterPairKey": {
	//       "description": "Param key in the key value pair filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterPairValue": {
	//       "description": "Param value in the key value pair filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterType": {
	//       "description": "Param type.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterValue": {
	//       "deprecated": true,
	//       "description": "Param value. DEPRECATED. User parameter_pair_value instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.startTime": {
	//       "description": "Start timestamp.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.taskStatuses": {
	//       "deprecated": true,
	//       "description": "List of possible task statuses.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "filterParams.workflowName": {
	//       "description": "Workflow name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Optional. The results would be returned in order you specified here. Currently supporting \"last_modified_time\" and \"create_time\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The size of entries in the response.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource name of the integration execution.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "Optional. View mask for the response data. If set, only the field specified will be returned as part of the result. If not set, all fields in event execution info will be filled and returned.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "refreshAcl": {
	//       "description": "Optional. If true, the service will use the most recent acl information to list event execution infos and renew the acl cache. Note that fetching the most recent acl is synchronous, so it will increase RPC call latency.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "truncateParams": {
	//       "deprecated": true,
	//       "description": "Optional. If true, the service will truncate the params to only keep the first 1000 characters of string params and empty the executions in order to make response smaller. Only works for UI and when the params fields are not filtered out.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/executions",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListExecutionsResponse"
	//   },
	//   "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 *ProjectsLocationsIntegrationsExecutionsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListExecutionsResponse) 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 "integrations.projects.locations.integrations.executions.suspensions.lift":

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

// Lift: * Lifts suspension for advanced suspension task. Fetch
// corresponding suspension with provided suspension Id, resolve
// suspension, and set up suspension result for the Suspension Task.
//
//   - name: The resource that the suspension belongs to.
//     "projects/{project}/locations/{location}/products/{product}/integrat
//     ions/{integration}/executions/{execution}/suspensions/{suspenion}"
//     format.
func (r *ProjectsLocationsIntegrationsExecutionsSuspensionsService) Lift(name string, googlecloudintegrationsv1alphaliftsuspensionrequest *GoogleCloudIntegrationsV1alphaLiftSuspensionRequest) *ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall {
	c := &ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaliftsuspensionrequest = googlecloudintegrationsv1alphaliftsuspensionrequest
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall {
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall {
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaliftsuspensionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:lift")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.integrations.executions.suspensions.lift" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaLiftSuspensionResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaLiftSuspensionResponse.ServerResponse.H
// eader 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 *ProjectsLocationsIntegrationsExecutionsSuspensionsLiftCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaLiftSuspensionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaLiftSuspensionResponse{
		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": "* Lifts suspension for advanced suspension task. Fetch corresponding suspension with provided suspension Id, resolve suspension, and set up suspension result for the Suspension Task.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/executions/{executionsId}/suspensions/{suspensionsId}:lift",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.executions.suspensions.lift",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource that the suspension belongs to. \"projects/{project}/locations/{location}/products/{product}/integrations/{integration}/executions/{execution}/suspensions/{suspenion}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/executions/[^/]+/suspensions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:lift",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaLiftSuspensionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaLiftSuspensionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.executions.suspensions.list":

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

// List: * Lists suspensions associated with a specific execution. Only
// those with permissions to resolve the relevant suspensions will be
// able to view them.
//
//   - parent:
//     projects/{gcp_project_id}/locations/{location}/products/{product}/in
//     tegrations/{integration_name}/executions/{execution_name}.
func (r *ProjectsLocationsIntegrationsExecutionsSuspensionsService) List(parent string) *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall {
	c := &ProjectsLocationsIntegrationsExecutionsSuspensionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Standard filter field.
func (c *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) Filter(filter string) *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field name to order
// by.
func (c *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) OrderBy(orderBy string) *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// entries in the response.
func (c *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) PageSize(pageSize int64) *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to retrieve
// a specific page.
func (c *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) PageToken(pageToken string) *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall {
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall {
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall {
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall {
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/suspensions")
	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 "integrations.projects.locations.integrations.executions.suspensions.list" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaListSuspensionsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaListSuspensionsResponse.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 *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListSuspensionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListSuspensionsResponse{
		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 suspensions associated with a specific execution. Only those with permissions to resolve the relevant suspensions will be able to view them.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/executions/{executionsId}/suspensions",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.integrations.executions.suspensions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Standard filter field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field name to order by.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of entries in the response.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to retrieve a specific page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. projects/{gcp_project_id}/locations/{location}/products/{product}/integrations/{integration_name}/executions/{execution_name}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/executions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/suspensions",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListSuspensionsResponse"
	//   },
	//   "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 *ProjectsLocationsIntegrationsExecutionsSuspensionsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListSuspensionsResponse) 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 "integrations.projects.locations.integrations.executions.suspensions.resolve":

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

// Resolve: * Resolves (lifts/rejects) any number of suspensions. If the
// integration is already running, only the status of the suspension is
// updated. Otherwise, the suspended integration will begin execution
// again.
//
//   - name:
//     projects/{gcp_project_id}/locations/{location}/products/{product}/in
//     tegrations/{integration_name}/executions/{execution_name}/suspension
//     s/{suspension_id}.
func (r *ProjectsLocationsIntegrationsExecutionsSuspensionsService) Resolve(name string, googlecloudintegrationsv1alpharesolvesuspensionrequest *GoogleCloudIntegrationsV1alphaResolveSuspensionRequest) *ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall {
	c := &ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alpharesolvesuspensionrequest = googlecloudintegrationsv1alpharesolvesuspensionrequest
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall {
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall {
	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 *ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alpharesolvesuspensionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:resolve")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.integrations.executions.suspensions.resolve" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaResolveSuspensionResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaResolveSuspensionResponse.ServerRespons
// e.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 *ProjectsLocationsIntegrationsExecutionsSuspensionsResolveCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaResolveSuspensionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaResolveSuspensionResponse{
		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": "* Resolves (lifts/rejects) any number of suspensions. If the integration is already running, only the status of the suspension is updated. Otherwise, the suspended integration will begin execution again.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/executions/{executionsId}/suspensions/{suspensionsId}:resolve",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.executions.suspensions.resolve",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. projects/{gcp_project_id}/locations/{location}/products/{product}/integrations/{integration_name}/executions/{execution_name}/suspensions/{suspension_id}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/executions/[^/]+/suspensions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:resolve",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaResolveSuspensionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaResolveSuspensionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.create":

type ProjectsLocationsIntegrationsVersionsCreateCall struct {
	s                                                *Service
	parent                                           string
	googlecloudintegrationsv1alphaintegrationversion *GoogleCloudIntegrationsV1alphaIntegrationVersion
	urlParams_                                       gensupport.URLParams
	ctx_                                             context.Context
	header_                                          http.Header
}

// Create: Create a integration with a draft version in the specified
// project.
//
//   - parent: The parent resource where this version will be created.
//     Format:
//     projects/{project}/locations/{location}/integrations/{integration}.
func (r *ProjectsLocationsIntegrationsVersionsService) Create(parent string, googlecloudintegrationsv1alphaintegrationversion *GoogleCloudIntegrationsV1alphaIntegrationVersion) *ProjectsLocationsIntegrationsVersionsCreateCall {
	c := &ProjectsLocationsIntegrationsVersionsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphaintegrationversion = googlecloudintegrationsv1alphaintegrationversion
	return c
}

// NewIntegration sets the optional parameter "newIntegration": Set this
// flag to true, if draft version is to be created for a brand new
// integration. False, if the request is for an existing integration.
// For backward compatibility reasons, even if this flag is set to
// `false` and no existing integration is found, a new draft integration
// will still be created.
func (c *ProjectsLocationsIntegrationsVersionsCreateCall) NewIntegration(newIntegration bool) *ProjectsLocationsIntegrationsVersionsCreateCall {
	c.urlParams_.Set("newIntegration", fmt.Sprint(newIntegration))
	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 *ProjectsLocationsIntegrationsVersionsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsCreateCall {
	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 *ProjectsLocationsIntegrationsVersionsCreateCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsCreateCall {
	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 *ProjectsLocationsIntegrationsVersionsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsVersionsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaintegrationversion)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/versions")
	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 "integrations.projects.locations.integrations.versions.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaIntegrationVersion or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaIntegrationVersion.ServerResponse.Heade
// r 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 *ProjectsLocationsIntegrationsVersionsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaIntegrationVersion, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaIntegrationVersion{
		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 integration with a draft version in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.versions.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "newIntegration": {
	//       "description": "Set this flag to true, if draft version is to be created for a brand new integration. False, if the request is for an existing integration. For backward compatibility reasons, even if this flag is set to `false` and no existing integration is found, a new draft integration will still be created.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource where this version will be created. Format: projects/{project}/locations/{location}/integrations/{integration}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/versions",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.delete":

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

// Delete: Soft-deletes the integration. Changes the status of the
// integration to ARCHIVED. If the integration being ARCHIVED is tagged
// as "HEAD", the tag is removed from this snapshot and set to the
// previous non-ARCHIVED snapshot. The PUBLISH_REQUESTED,
// DUE_FOR_DELETION tags are removed too. This RPC throws an exception
// if the version being deleted is DRAFT, and if the `locked_by` user is
// not the same as the user performing the Delete. Audit fields updated
// include last_modified_timestamp, last_modified_by. Any existing lock
// is released when Deleting a integration. Currently, there is no
// undelete mechanism.
//
//   - name: The version to delete. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsIntegrationsVersionsService) Delete(name string) *ProjectsLocationsIntegrationsVersionsDeleteCall {
	c := &ProjectsLocationsIntegrationsVersionsDeleteCall{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 *ProjectsLocationsIntegrationsVersionsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsDeleteCall {
	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 *ProjectsLocationsIntegrationsVersionsDeleteCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsDeleteCall {
	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 *ProjectsLocationsIntegrationsVersionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.integrations.versions.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsIntegrationsVersionsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		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": "Soft-deletes the integration. Changes the status of the integration to ARCHIVED. If the integration being ARCHIVED is tagged as \"HEAD\", the tag is removed from this snapshot and set to the previous non-ARCHIVED snapshot. The PUBLISH_REQUESTED, DUE_FOR_DELETION tags are removed too. This RPC throws an exception if the version being deleted is DRAFT, and if the `locked_by` user is not the same as the user performing the Delete. Audit fields updated include last_modified_timestamp, last_modified_by. Any existing lock is released when Deleting a integration. Currently, there is no undelete mechanism.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions/{versionsId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.integrations.versions.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The version to delete. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.download":

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

// Download: Downloads an integration. Retrieves the
// `IntegrationVersion` for a given `integration_id` and returns the
// response as a string.
//
//   - name: The version to download. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsIntegrationsVersionsService) Download(name string) *ProjectsLocationsIntegrationsVersionsDownloadCall {
	c := &ProjectsLocationsIntegrationsVersionsDownloadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// FileFormat sets the optional parameter "fileFormat": File format for
// download request.
//
// Possible values:
//
//	"FILE_FORMAT_UNSPECIFIED" - Unspecified file format
//	"JSON" - JSON File Format
//	"YAML" - YAML File Format
func (c *ProjectsLocationsIntegrationsVersionsDownloadCall) FileFormat(fileFormat string) *ProjectsLocationsIntegrationsVersionsDownloadCall {
	c.urlParams_.Set("fileFormat", fileFormat)
	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 *ProjectsLocationsIntegrationsVersionsDownloadCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsDownloadCall {
	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 *ProjectsLocationsIntegrationsVersionsDownloadCall) IfNoneMatch(entityTag string) *ProjectsLocationsIntegrationsVersionsDownloadCall {
	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 *ProjectsLocationsIntegrationsVersionsDownloadCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsDownloadCall {
	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 *ProjectsLocationsIntegrationsVersionsDownloadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsVersionsDownloadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:download")
	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 "integrations.projects.locations.integrations.versions.download" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse.Serv
// erResponse.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 *ProjectsLocationsIntegrationsVersionsDownloadCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse{
		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": "Downloads an integration. Retrieves the `IntegrationVersion` for a given `integration_id` and returns the response as a string.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions/{versionsId}:download",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.integrations.versions.download",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "fileFormat": {
	//       "description": "File format for download request.",
	//       "enum": [
	//         "FILE_FORMAT_UNSPECIFIED",
	//         "JSON",
	//         "YAML"
	//       ],
	//       "enumDescriptions": [
	//         "Unspecified file format",
	//         "JSON File Format",
	//         "YAML File Format"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The version to download. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:download",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.get":

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

// Get: Get a integration in the specified project.
//
//   - name: The version to retrieve. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsIntegrationsVersionsService) Get(name string) *ProjectsLocationsIntegrationsVersionsGetCall {
	c := &ProjectsLocationsIntegrationsVersionsGetCall{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 *ProjectsLocationsIntegrationsVersionsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsGetCall {
	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 *ProjectsLocationsIntegrationsVersionsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsIntegrationsVersionsGetCall {
	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 *ProjectsLocationsIntegrationsVersionsGetCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsGetCall {
	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 *ProjectsLocationsIntegrationsVersionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.integrations.versions.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaIntegrationVersion or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaIntegrationVersion.ServerResponse.Heade
// r 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 *ProjectsLocationsIntegrationsVersionsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaIntegrationVersion, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaIntegrationVersion{
		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 a integration in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions/{versionsId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.integrations.versions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The version to retrieve. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.list":

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

// List: Returns the list of all integration versions in the specified
// project.
//
//   - parent: The parent resource where this version will be created.
//     Format:
//     projects/{project}/locations/{location}/integrations/{integration}
//     Specifically, when parent equals: 1.
//     projects//locations//integrations/, Meaning: "List versions (with
//     filter) for a particular integration". 2.
//     projects//locations//integrations/- Meaning: "List versions (with
//     filter) for a client within a particular region". 3.
//     projects//locations/-/integrations/- Meaning: "List versions (with
//     filter) for a client".
func (r *ProjectsLocationsIntegrationsVersionsService) List(parent string) *ProjectsLocationsIntegrationsVersionsListCall {
	c := &ProjectsLocationsIntegrationsVersionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// FieldMask sets the optional parameter "fieldMask": The field mask
// which specifies the particular data to be returned.
func (c *ProjectsLocationsIntegrationsVersionsListCall) FieldMask(fieldMask string) *ProjectsLocationsIntegrationsVersionsListCall {
	c.urlParams_.Set("fieldMask", fieldMask)
	return c
}

// Filter sets the optional parameter "filter": Filter on fields of
// IntegrationVersion. Fields can be compared with literal values by use
// of ":" (containment), "=" (equality), ">" (greater), "<" (less than),
// >=" (greater than or equal to), "<=" (less than or equal to), and
// "!=" (inequality) operators. Negation, conjunction, and disjunction
// are written using NOT, AND, and OR keywords. For example,
// organization_id=\"1\" AND state=ACTIVE AND description:"test".
// Filtering cannot be performed on repeated fields like `task_config`.
func (c *ProjectsLocationsIntegrationsVersionsListCall) Filter(filter string) *ProjectsLocationsIntegrationsVersionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": The results would be
// returned in order you specified here. Currently supported sort keys
// are: Descending sort order for "last_modified_time", "created_time",
// "snapshot_number" Ascending sort order for "name".
func (c *ProjectsLocationsIntegrationsVersionsListCall) OrderBy(orderBy string) *ProjectsLocationsIntegrationsVersionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of versions to return. The service may return fewer than this value.
// If unspecified, at most 50 versions will be returned. The maximum
// value is 1000; values above 1000 will be coerced to 1000.
func (c *ProjectsLocationsIntegrationsVersionsListCall) PageSize(pageSize int64) *ProjectsLocationsIntegrationsVersionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token,
// received from a previous `ListIntegrationVersions` call. Provide this
// to retrieve the subsequent page. When paginating, all other
// parameters provided to `ListIntegrationVersions` must match the call
// that provided the page token.
func (c *ProjectsLocationsIntegrationsVersionsListCall) PageToken(pageToken string) *ProjectsLocationsIntegrationsVersionsListCall {
	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 *ProjectsLocationsIntegrationsVersionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsListCall {
	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 *ProjectsLocationsIntegrationsVersionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsIntegrationsVersionsListCall {
	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 *ProjectsLocationsIntegrationsVersionsListCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsListCall {
	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 *ProjectsLocationsIntegrationsVersionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsVersionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/versions")
	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 "integrations.projects.locations.integrations.versions.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse.ServerR
// esponse.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 *ProjectsLocationsIntegrationsVersionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the list of all integration versions in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.integrations.versions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "fieldMask": {
	//       "description": "The field mask which specifies the particular data to be returned.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Filter on fields of IntegrationVersion. Fields can be compared with literal values by use of \":\" (containment), \"=\" (equality), \"\u003e\" (greater), \"\u003c\" (less than), \u003e=\" (greater than or equal to), \"\u003c=\" (less than or equal to), and \"!=\" (inequality) operators. Negation, conjunction, and disjunction are written using NOT, AND, and OR keywords. For example, organization_id=\\\"1\\\" AND state=ACTIVE AND description:\"test\". Filtering cannot be performed on repeated fields like `task_config`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "The results would be returned in order you specified here. Currently supported sort keys are: Descending sort order for \"last_modified_time\", \"created_time\", \"snapshot_number\" Ascending sort order for \"name\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of versions to return. The service may return fewer than this value. If unspecified, at most 50 versions will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A page token, received from a previous `ListIntegrationVersions` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListIntegrationVersions` must match the call that provided the page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource where this version will be created. Format: projects/{project}/locations/{location}/integrations/{integration} Specifically, when parent equals: 1. projects//locations//integrations/, Meaning: \"List versions (with filter) for a particular integration\". 2. projects//locations//integrations/- Meaning: \"List versions (with filter) for a client within a particular region\". 3. projects//locations/-/integrations/- Meaning: \"List versions (with filter) for a client\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/versions",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse"
	//   },
	//   "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 *ProjectsLocationsIntegrationsVersionsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse) 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 "integrations.projects.locations.integrations.versions.patch":

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

// Patch: Update a integration with a draft version in the specified
// project.
//
// - name: Output only. Auto-generated primary key.
func (r *ProjectsLocationsIntegrationsVersionsService) Patch(name string, googlecloudintegrationsv1alphaintegrationversion *GoogleCloudIntegrationsV1alphaIntegrationVersion) *ProjectsLocationsIntegrationsVersionsPatchCall {
	c := &ProjectsLocationsIntegrationsVersionsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaintegrationversion = googlecloudintegrationsv1alphaintegrationversion
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above integration that have been
// modified and need to be updated.
func (c *ProjectsLocationsIntegrationsVersionsPatchCall) UpdateMask(updateMask string) *ProjectsLocationsIntegrationsVersionsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.integrations.versions.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaIntegrationVersion or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaIntegrationVersion.ServerResponse.Heade
// r 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 *ProjectsLocationsIntegrationsVersionsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaIntegrationVersion, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaIntegrationVersion{
		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": "Update a integration with a draft version in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions/{versionsId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.integrations.versions.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Output only. Auto-generated primary key.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above integration that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.publish":

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

// Publish: This RPC throws an exception if the integration is in
// ARCHIVED or ACTIVE state. This RPC throws an exception if the version
// being published is DRAFT, and if the `locked_by` user is not the same
// as the user performing the Publish. Audit fields updated include
// last_published_timestamp, last_published_by, last_modified_timestamp,
// last_modified_by. Any existing lock is on this integration is
// released.
//
//   - name: The version to publish. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsIntegrationsVersionsService) Publish(name string, googlecloudintegrationsv1alphapublishintegrationversionrequest *GoogleCloudIntegrationsV1alphaPublishIntegrationVersionRequest) *ProjectsLocationsIntegrationsVersionsPublishCall {
	c := &ProjectsLocationsIntegrationsVersionsPublishCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphapublishintegrationversionrequest = googlecloudintegrationsv1alphapublishintegrationversionrequest
	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 *ProjectsLocationsIntegrationsVersionsPublishCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsPublishCall {
	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 *ProjectsLocationsIntegrationsVersionsPublishCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsPublishCall {
	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 *ProjectsLocationsIntegrationsVersionsPublishCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsVersionsPublishCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphapublishintegrationversionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:publish")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.integrations.versions.publish" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse.Serve
// rResponse.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 *ProjectsLocationsIntegrationsVersionsPublishCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse{
		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": "This RPC throws an exception if the integration is in ARCHIVED or ACTIVE state. This RPC throws an exception if the version being published is DRAFT, and if the `locked_by` user is not the same as the user performing the Publish. Audit fields updated include last_published_timestamp, last_published_by, last_modified_timestamp, last_modified_by. Any existing lock is on this integration is released.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions/{versionsId}:publish",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.versions.publish",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The version to publish. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:publish",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaPublishIntegrationVersionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.takeoverEditLock":

type ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall struct {
	s                                                     *Service
	integrationVersion                                    string
	googlecloudintegrationsv1alphatakeovereditlockrequest *GoogleCloudIntegrationsV1alphaTakeoverEditLockRequest
	urlParams_                                            gensupport.URLParams
	ctx_                                                  context.Context
	header_                                               http.Header
}

// TakeoverEditLock: Clears the `locked_by` and `locked_at_timestamp`in
// the DRAFT version of this integration. It then performs the same
// action as the CreateDraftIntegrationVersion (i.e., copies the DRAFT
// version of the integration as a SNAPSHOT and then creates a new DRAFT
// version with the `locked_by` set to the `user_taking_over` and the
// `locked_at_timestamp` set to the current timestamp). Both the
// `locked_by` and `user_taking_over` are notified via email about the
// takeover. This RPC throws an exception if the integration is not in
// DRAFT status or if the `locked_by` and `locked_at_timestamp` fields
// are not set.The TakeoverEdit lock is treated the same as an edit of
// the integration, and hence shares ACLs with edit. Audit fields
// updated include last_modified_timestamp, last_modified_by.
//
//   - integrationVersion: The version to take over edit lock. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsIntegrationsVersionsService) TakeoverEditLock(integrationVersion string, googlecloudintegrationsv1alphatakeovereditlockrequest *GoogleCloudIntegrationsV1alphaTakeoverEditLockRequest) *ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall {
	c := &ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.integrationVersion = integrationVersion
	c.googlecloudintegrationsv1alphatakeovereditlockrequest = googlecloudintegrationsv1alphatakeovereditlockrequest
	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 *ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall {
	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 *ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall {
	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 *ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphatakeovereditlockrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+integrationVersion}:takeoverEditLock")
	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{
		"integrationVersion": c.integrationVersion,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.integrations.versions.takeoverEditLock" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse.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 *ProjectsLocationsIntegrationsVersionsTakeoverEditLockCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse{
		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": "Clears the `locked_by` and `locked_at_timestamp`in the DRAFT version of this integration. It then performs the same action as the CreateDraftIntegrationVersion (i.e., copies the DRAFT version of the integration as a SNAPSHOT and then creates a new DRAFT version with the `locked_by` set to the `user_taking_over` and the `locked_at_timestamp` set to the current timestamp). Both the `locked_by` and `user_taking_over` are notified via email about the takeover. This RPC throws an exception if the integration is not in DRAFT status or if the `locked_by` and `locked_at_timestamp` fields are not set.The TakeoverEdit lock is treated the same as an edit of the integration, and hence shares ACLs with edit. Audit fields updated include last_modified_timestamp, last_modified_by.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions/{versionsId}:takeoverEditLock",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.versions.takeoverEditLock",
	//   "parameterOrder": [
	//     "integrationVersion"
	//   ],
	//   "parameters": {
	//     "integrationVersion": {
	//       "description": "Required. The version to take over edit lock. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+integrationVersion}:takeoverEditLock",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaTakeoverEditLockRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.unpublish":

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

// Unpublish: Sets the status of the ACTIVE integration to SNAPSHOT with
// a new tag "PREVIOUSLY_PUBLISHED" after validating it. The "HEAD" and
// "PUBLISH_REQUESTED" tags do not change. This RPC throws an exception
// if the version being snapshot is not ACTIVE. Audit fields added
// include action, action_by, action_timestamp.
//
//   - name: The version to deactivate. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsIntegrationsVersionsService) Unpublish(name string, googlecloudintegrationsv1alphaunpublishintegrationversionrequest *GoogleCloudIntegrationsV1alphaUnpublishIntegrationVersionRequest) *ProjectsLocationsIntegrationsVersionsUnpublishCall {
	c := &ProjectsLocationsIntegrationsVersionsUnpublishCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaunpublishintegrationversionrequest = googlecloudintegrationsv1alphaunpublishintegrationversionrequest
	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 *ProjectsLocationsIntegrationsVersionsUnpublishCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsUnpublishCall {
	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 *ProjectsLocationsIntegrationsVersionsUnpublishCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsUnpublishCall {
	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 *ProjectsLocationsIntegrationsVersionsUnpublishCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsVersionsUnpublishCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaunpublishintegrationversionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:unpublish")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.integrations.versions.unpublish" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsIntegrationsVersionsUnpublishCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		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 status of the ACTIVE integration to SNAPSHOT with a new tag \"PREVIOUSLY_PUBLISHED\" after validating it. The \"HEAD\" and \"PUBLISH_REQUESTED\" tags do not change. This RPC throws an exception if the version being snapshot is not ACTIVE. Audit fields added include action, action_by, action_timestamp.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions/{versionsId}:unpublish",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.versions.unpublish",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The version to deactivate. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:unpublish",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaUnpublishIntegrationVersionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.integrations.versions.upload":

type ProjectsLocationsIntegrationsVersionsUploadCall struct {
	s                                                             *Service
	parent                                                        string
	googlecloudintegrationsv1alphauploadintegrationversionrequest *GoogleCloudIntegrationsV1alphaUploadIntegrationVersionRequest
	urlParams_                                                    gensupport.URLParams
	ctx_                                                          context.Context
	header_                                                       http.Header
}

// Upload: Uploads an integration. The content can be a previously
// downloaded integration. Performs the same function as
// CreateDraftIntegrationVersion, but accepts input in a string format,
// which holds the complete representation of the IntegrationVersion
// content.
//
//   - parent: The version to upload. Format:
//     projects/{project}/locations/{location}/integrations/{integration}.
func (r *ProjectsLocationsIntegrationsVersionsService) Upload(parent string, googlecloudintegrationsv1alphauploadintegrationversionrequest *GoogleCloudIntegrationsV1alphaUploadIntegrationVersionRequest) *ProjectsLocationsIntegrationsVersionsUploadCall {
	c := &ProjectsLocationsIntegrationsVersionsUploadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphauploadintegrationversionrequest = googlecloudintegrationsv1alphauploadintegrationversionrequest
	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 *ProjectsLocationsIntegrationsVersionsUploadCall) Fields(s ...googleapi.Field) *ProjectsLocationsIntegrationsVersionsUploadCall {
	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 *ProjectsLocationsIntegrationsVersionsUploadCall) Context(ctx context.Context) *ProjectsLocationsIntegrationsVersionsUploadCall {
	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 *ProjectsLocationsIntegrationsVersionsUploadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsIntegrationsVersionsUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphauploadintegrationversionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/versions:upload")
	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 "integrations.projects.locations.integrations.versions.upload" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse.Server
// Response.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 *ProjectsLocationsIntegrationsVersionsUploadCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse{
		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": "Uploads an integration. The content can be a previously downloaded integration. Performs the same function as CreateDraftIntegrationVersion, but accepts input in a string format, which holds the complete representation of the IntegrationVersion content.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/integrations/{integrationsId}/versions:upload",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.integrations.versions.upload",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The version to upload. Format: projects/{project}/locations/{location}/integrations/{integration}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/versions:upload",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaUploadIntegrationVersionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.authConfigs.create":

type ProjectsLocationsProductsAuthConfigsCreateCall struct {
	s                                        *Service
	parent                                   string
	googlecloudintegrationsv1alphaauthconfig *GoogleCloudIntegrationsV1alphaAuthConfig
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// Create: Creates an auth config record. Fetch corresponding
// credentials for specific auth types, e.g. access token for OAuth 2.0,
// JWT token for JWT. Encrypt the auth config with Cloud KMS and store
// the encrypted credentials in Spanner. Returns the encrypted auth
// config.
//
// - parent: "projects/{project}/locations/{location}" format.
func (r *ProjectsLocationsProductsAuthConfigsService) Create(parent string, googlecloudintegrationsv1alphaauthconfig *GoogleCloudIntegrationsV1alphaAuthConfig) *ProjectsLocationsProductsAuthConfigsCreateCall {
	c := &ProjectsLocationsProductsAuthConfigsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphaauthconfig = googlecloudintegrationsv1alphaauthconfig
	return c
}

// ClientCertificateEncryptedPrivateKey sets the optional parameter
// "clientCertificate.encryptedPrivateKey": The ssl certificate encoded
// in PEM format. This string must include the begin header and end
// footer lines. For example, -----BEGIN CERTIFICATE-----
// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
func (c *ProjectsLocationsProductsAuthConfigsCreateCall) ClientCertificateEncryptedPrivateKey(clientCertificateEncryptedPrivateKey string) *ProjectsLocationsProductsAuthConfigsCreateCall {
	c.urlParams_.Set("clientCertificate.encryptedPrivateKey", clientCertificateEncryptedPrivateKey)
	return c
}

// ClientCertificatePassphrase sets the optional parameter
// "clientCertificate.passphrase": 'passphrase' should be left unset if
// private key is not encrypted. Note that 'passphrase' is not the
// password for web server, but an extra layer of security to protected
// private key.
func (c *ProjectsLocationsProductsAuthConfigsCreateCall) ClientCertificatePassphrase(clientCertificatePassphrase string) *ProjectsLocationsProductsAuthConfigsCreateCall {
	c.urlParams_.Set("clientCertificate.passphrase", clientCertificatePassphrase)
	return c
}

// ClientCertificateSslCertificate sets the optional parameter
// "clientCertificate.sslCertificate": The ssl certificate encoded in
// PEM format. This string must include the begin header and end footer
// lines. For example, -----BEGIN CERTIFICATE-----
// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
func (c *ProjectsLocationsProductsAuthConfigsCreateCall) ClientCertificateSslCertificate(clientCertificateSslCertificate string) *ProjectsLocationsProductsAuthConfigsCreateCall {
	c.urlParams_.Set("clientCertificate.sslCertificate", clientCertificateSslCertificate)
	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 *ProjectsLocationsProductsAuthConfigsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsAuthConfigsCreateCall {
	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 *ProjectsLocationsProductsAuthConfigsCreateCall) Context(ctx context.Context) *ProjectsLocationsProductsAuthConfigsCreateCall {
	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 *ProjectsLocationsProductsAuthConfigsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsAuthConfigsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaauthconfig)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/authConfigs")
	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 "integrations.projects.locations.products.authConfigs.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaAuthConfig or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaAuthConfig.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 *ProjectsLocationsProductsAuthConfigsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaAuthConfig, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaAuthConfig{
		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 an auth config record. Fetch corresponding credentials for specific auth types, e.g. access token for OAuth 2.0, JWT token for JWT. Encrypt the auth config with Cloud KMS and store the encrypted credentials in Spanner. Returns the encrypted auth config.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/authConfigs",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.authConfigs.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "clientCertificate.encryptedPrivateKey": {
	//       "description": "The ssl certificate encoded in PEM format. This string must include the begin header and end footer lines. For example, -----BEGIN CERTIFICATE----- MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1 JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientCertificate.passphrase": {
	//       "description": "'passphrase' should be left unset if private key is not encrypted. Note that 'passphrase' is not the password for web server, but an extra layer of security to protected private key.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientCertificate.sslCertificate": {
	//       "description": "The ssl certificate encoded in PEM format. This string must include the begin header and end footer lines. For example, -----BEGIN CERTIFICATE----- MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1 JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. \"projects/{project}/locations/{location}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/authConfigs",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.authConfigs.delete":

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

// Delete: Deletes an auth config.
//
// - name: The name that is associated with the AuthConfig.
func (r *ProjectsLocationsProductsAuthConfigsService) Delete(name string) *ProjectsLocationsProductsAuthConfigsDeleteCall {
	c := &ProjectsLocationsProductsAuthConfigsDeleteCall{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 *ProjectsLocationsProductsAuthConfigsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsAuthConfigsDeleteCall {
	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 *ProjectsLocationsProductsAuthConfigsDeleteCall) Context(ctx context.Context) *ProjectsLocationsProductsAuthConfigsDeleteCall {
	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 *ProjectsLocationsProductsAuthConfigsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.authConfigs.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsProductsAuthConfigsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an auth config.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/authConfigs/{authConfigsId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.products.authConfigs.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the AuthConfig.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/authConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.authConfigs.get":

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

// Get: Gets a complete auth config. If the auth config doesn't exist,
// Code.NOT_FOUND exception will be thrown. Returns the decrypted auth
// config.
//
// - name: The name that is associated with the AuthConfig.
func (r *ProjectsLocationsProductsAuthConfigsService) Get(name string) *ProjectsLocationsProductsAuthConfigsGetCall {
	c := &ProjectsLocationsProductsAuthConfigsGetCall{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 *ProjectsLocationsProductsAuthConfigsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsAuthConfigsGetCall {
	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 *ProjectsLocationsProductsAuthConfigsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsAuthConfigsGetCall {
	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 *ProjectsLocationsProductsAuthConfigsGetCall) Context(ctx context.Context) *ProjectsLocationsProductsAuthConfigsGetCall {
	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 *ProjectsLocationsProductsAuthConfigsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.authConfigs.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaAuthConfig or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaAuthConfig.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 *ProjectsLocationsProductsAuthConfigsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaAuthConfig, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaAuthConfig{
		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 a complete auth config. If the auth config doesn't exist, Code.NOT_FOUND exception will be thrown. Returns the decrypted auth config.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/authConfigs/{authConfigsId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.authConfigs.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the AuthConfig.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/authConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.authConfigs.list":

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

// List: Lists all auth configs that match the filter. Restrict to auth
// configs belong to the current client only.
//
// - parent: The client, which owns this collection of AuthConfigs.
func (r *ProjectsLocationsProductsAuthConfigsService) List(parent string) *ProjectsLocationsProductsAuthConfigsListCall {
	c := &ProjectsLocationsProductsAuthConfigsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filtering as supported
// in
// https://developers.google.com/authorized-buyers/apis/guides/list-filters.
func (c *ProjectsLocationsProductsAuthConfigsListCall) Filter(filter string) *ProjectsLocationsProductsAuthConfigsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response. If unspecified, defaults to 100.
func (c *ProjectsLocationsProductsAuthConfigsListCall) PageSize(pageSize int64) *ProjectsLocationsProductsAuthConfigsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsProductsAuthConfigsListCall) PageToken(pageToken string) *ProjectsLocationsProductsAuthConfigsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": The mask which
// specifies fields that need to be returned in the AuthConfig's
// response.
func (c *ProjectsLocationsProductsAuthConfigsListCall) ReadMask(readMask string) *ProjectsLocationsProductsAuthConfigsListCall {
	c.urlParams_.Set("readMask", readMask)
	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 *ProjectsLocationsProductsAuthConfigsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsAuthConfigsListCall {
	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 *ProjectsLocationsProductsAuthConfigsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsAuthConfigsListCall {
	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 *ProjectsLocationsProductsAuthConfigsListCall) Context(ctx context.Context) *ProjectsLocationsProductsAuthConfigsListCall {
	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 *ProjectsLocationsProductsAuthConfigsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsAuthConfigsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/authConfigs")
	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 "integrations.projects.locations.products.authConfigs.list" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaListAuthConfigsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaListAuthConfigsResponse.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 *ProjectsLocationsProductsAuthConfigsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListAuthConfigsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListAuthConfigsResponse{
		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 all auth configs that match the filter. Restrict to auth configs belong to the current client only.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/authConfigs",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.authConfigs.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filtering as supported in https://developers.google.com/authorized-buyers/apis/guides/list-filters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The size of entries in the response. If unspecified, defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The client, which owns this collection of AuthConfigs.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "The mask which specifies fields that need to be returned in the AuthConfig's response.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/authConfigs",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListAuthConfigsResponse"
	//   },
	//   "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 *ProjectsLocationsProductsAuthConfigsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListAuthConfigsResponse) 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 "integrations.projects.locations.products.authConfigs.patch":

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

// Patch: Updates an auth config. If credential is updated, fetch the
// encrypted auth config from Spanner, decrypt with Cloud KMS key,
// update the credential fields, re-encrypt with Cloud KMS key and
// update the Spanner record. For other fields, directly update the
// Spanner record. Returns the encrypted auth config.
//
//   - name: Resource name of the SFDC instance
//     projects/{project}/locations/{location}/authConfigs/{authConfig}.
func (r *ProjectsLocationsProductsAuthConfigsService) Patch(name string, googlecloudintegrationsv1alphaauthconfig *GoogleCloudIntegrationsV1alphaAuthConfig) *ProjectsLocationsProductsAuthConfigsPatchCall {
	c := &ProjectsLocationsProductsAuthConfigsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaauthconfig = googlecloudintegrationsv1alphaauthconfig
	return c
}

// ClientCertificateEncryptedPrivateKey sets the optional parameter
// "clientCertificate.encryptedPrivateKey": The ssl certificate encoded
// in PEM format. This string must include the begin header and end
// footer lines. For example, -----BEGIN CERTIFICATE-----
// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
func (c *ProjectsLocationsProductsAuthConfigsPatchCall) ClientCertificateEncryptedPrivateKey(clientCertificateEncryptedPrivateKey string) *ProjectsLocationsProductsAuthConfigsPatchCall {
	c.urlParams_.Set("clientCertificate.encryptedPrivateKey", clientCertificateEncryptedPrivateKey)
	return c
}

// ClientCertificatePassphrase sets the optional parameter
// "clientCertificate.passphrase": 'passphrase' should be left unset if
// private key is not encrypted. Note that 'passphrase' is not the
// password for web server, but an extra layer of security to protected
// private key.
func (c *ProjectsLocationsProductsAuthConfigsPatchCall) ClientCertificatePassphrase(clientCertificatePassphrase string) *ProjectsLocationsProductsAuthConfigsPatchCall {
	c.urlParams_.Set("clientCertificate.passphrase", clientCertificatePassphrase)
	return c
}

// ClientCertificateSslCertificate sets the optional parameter
// "clientCertificate.sslCertificate": The ssl certificate encoded in
// PEM format. This string must include the begin header and end footer
// lines. For example, -----BEGIN CERTIFICATE-----
// MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV
// BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw
// MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET
// MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
// vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1
// JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB
// xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P
// AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
// Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey
// Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW
// JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr
// 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H
// wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----
func (c *ProjectsLocationsProductsAuthConfigsPatchCall) ClientCertificateSslCertificate(clientCertificateSslCertificate string) *ProjectsLocationsProductsAuthConfigsPatchCall {
	c.urlParams_.Set("clientCertificate.sslCertificate", clientCertificateSslCertificate)
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above AuthConfig that have been modified
// and need to be updated.
func (c *ProjectsLocationsProductsAuthConfigsPatchCall) UpdateMask(updateMask string) *ProjectsLocationsProductsAuthConfigsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.products.authConfigs.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaAuthConfig or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaAuthConfig.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 *ProjectsLocationsProductsAuthConfigsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaAuthConfig, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaAuthConfig{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an auth config. If credential is updated, fetch the encrypted auth config from Spanner, decrypt with Cloud KMS key, update the credential fields, re-encrypt with Cloud KMS key and update the Spanner record. For other fields, directly update the Spanner record. Returns the encrypted auth config.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/authConfigs/{authConfigsId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.products.authConfigs.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "clientCertificate.encryptedPrivateKey": {
	//       "description": "The ssl certificate encoded in PEM format. This string must include the begin header and end footer lines. For example, -----BEGIN CERTIFICATE----- MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1 JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientCertificate.passphrase": {
	//       "description": "'passphrase' should be left unset if private key is not encrypted. Note that 'passphrase' is not the password for web server, but an extra layer of security to protected private key.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "clientCertificate.sslCertificate": {
	//       "description": "The ssl certificate encoded in PEM format. This string must include the begin header and end footer lines. For example, -----BEGIN CERTIFICATE----- MIICTTCCAbagAwIBAgIJAPT0tSKNxan/MA0GCSqGSIb3DQEBCwUAMCoxFzAVBgNV BAoTDkdvb2dsZSBURVNUSU5HMQ8wDQYDVQQDEwZ0ZXN0Q0EwHhcNMTUwMTAxMDAw MDAwWhcNMjUwMTAxMDAwMDAwWjAuMRcwFQYDVQQKEw5Hb29nbGUgVEVTVElORzET MBEGA1UEAwwKam9lQGJhbmFuYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vDYFgMgxi5W488d9J7UpCInl0NXmZQpJDEHE4hvkaRlH7pnC71H0DLt0/3zATRP1 JzY2+eqBmbGl4/sgZKYv8UrLnNyQNUTsNx1iZAfPUflf5FwgVsai8BM0pUciq1NB xD429VFcrGZNucvFLh72RuRFIKH8WUpiK/iZNFkWhZ0CAwEAAaN3MHUwDgYDVR0P AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB Af8EAjAAMBkGA1UdDgQSBBCVgnFBCWgL/iwCqnGrhTPQMBsGA1UdIwQUMBKAEKey Um2o4k2WiEVA0ldQvNYwDQYJKoZIhvcNAQELBQADgYEAYK986R4E3L1v+Q6esBtW JrUwA9UmJRSQr0N5w3o9XzarU37/bkjOP0Fw0k/A6Vv1n3vlciYfBFaBIam1qRHr 5dMsYf4CZS6w50r7hyzqyrwDoyNxkLnd2PdcHT/sym1QmflsjEs7pejtnohO6N2H wQW6M0H7Zt8claGRla4fKkg= -----END CERTIFICATE-----",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Resource name of the SFDC instance projects/{project}/locations/{location}/authConfigs/{authConfig}.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/authConfigs/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above AuthConfig that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaAuthConfig"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.certificates.create":

type ProjectsLocationsProductsCertificatesCreateCall struct {
	s                                         *Service
	parent                                    string
	googlecloudintegrationsv1alphacertificate *GoogleCloudIntegrationsV1alphaCertificate
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// Create: Creates a new certificate. The certificate will be registered
// to the trawler service and will be encrypted using cloud KMS and
// stored in Spanner Returns the certificate.
//
// - parent: "projects/{project}/locations/{location}" format.
func (r *ProjectsLocationsProductsCertificatesService) Create(parent string, googlecloudintegrationsv1alphacertificate *GoogleCloudIntegrationsV1alphaCertificate) *ProjectsLocationsProductsCertificatesCreateCall {
	c := &ProjectsLocationsProductsCertificatesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphacertificate = googlecloudintegrationsv1alphacertificate
	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 *ProjectsLocationsProductsCertificatesCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsCertificatesCreateCall {
	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 *ProjectsLocationsProductsCertificatesCreateCall) Context(ctx context.Context) *ProjectsLocationsProductsCertificatesCreateCall {
	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 *ProjectsLocationsProductsCertificatesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsCertificatesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphacertificate)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/certificates")
	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 "integrations.projects.locations.products.certificates.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaCertificate or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaCertificate.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 *ProjectsLocationsProductsCertificatesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaCertificate, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaCertificate{
		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 certificate. The certificate will be registered to the trawler service and will be encrypted using cloud KMS and stored in Spanner Returns the certificate.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/certificates",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.certificates.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. \"projects/{project}/locations/{location}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/certificates",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCertificate"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCertificate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.certificates.delete":

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

// Delete: Delete a certificate
//
// - name: The name that is associated with the Certificate.
func (r *ProjectsLocationsProductsCertificatesService) Delete(name string) *ProjectsLocationsProductsCertificatesDeleteCall {
	c := &ProjectsLocationsProductsCertificatesDeleteCall{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 *ProjectsLocationsProductsCertificatesDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsCertificatesDeleteCall {
	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 *ProjectsLocationsProductsCertificatesDeleteCall) Context(ctx context.Context) *ProjectsLocationsProductsCertificatesDeleteCall {
	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 *ProjectsLocationsProductsCertificatesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.certificates.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsProductsCertificatesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		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 certificate",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/certificates/{certificatesId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.products.certificates.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the Certificate.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/certificates/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.certificates.get":

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

// Get: Get a certificates in the specified project.
//
//   - name: The certificate to retrieve. Format:
//     projects/{project}/locations/{location}/certificates/{certificate}.
func (r *ProjectsLocationsProductsCertificatesService) Get(name string) *ProjectsLocationsProductsCertificatesGetCall {
	c := &ProjectsLocationsProductsCertificatesGetCall{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 *ProjectsLocationsProductsCertificatesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsCertificatesGetCall {
	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 *ProjectsLocationsProductsCertificatesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsCertificatesGetCall {
	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 *ProjectsLocationsProductsCertificatesGetCall) Context(ctx context.Context) *ProjectsLocationsProductsCertificatesGetCall {
	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 *ProjectsLocationsProductsCertificatesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.certificates.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaCertificate or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaCertificate.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 *ProjectsLocationsProductsCertificatesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaCertificate, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaCertificate{
		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 a certificates in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/certificates/{certificatesId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.certificates.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The certificate to retrieve. Format: projects/{project}/locations/{location}/certificates/{certificate}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/certificates/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCertificate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.certificates.list":

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

// List: List all the certificates that match the filter. Restrict to
// certificate of current client only.
//
// - parent: The client, which owns this collection of Certificates.
func (r *ProjectsLocationsProductsCertificatesService) List(parent string) *ProjectsLocationsProductsCertificatesListCall {
	c := &ProjectsLocationsProductsCertificatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filtering as supported
// in
// https://developers.google.com/authorized-buyers/apis/guides/list-filters.
func (c *ProjectsLocationsProductsCertificatesListCall) Filter(filter string) *ProjectsLocationsProductsCertificatesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response. If unspecified, defaults to 100.
func (c *ProjectsLocationsProductsCertificatesListCall) PageSize(pageSize int64) *ProjectsLocationsProductsCertificatesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsProductsCertificatesListCall) PageToken(pageToken string) *ProjectsLocationsProductsCertificatesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": The mask which
// specifies fields that need to be returned in the Certificate's
// response.
func (c *ProjectsLocationsProductsCertificatesListCall) ReadMask(readMask string) *ProjectsLocationsProductsCertificatesListCall {
	c.urlParams_.Set("readMask", readMask)
	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 *ProjectsLocationsProductsCertificatesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsCertificatesListCall {
	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 *ProjectsLocationsProductsCertificatesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsCertificatesListCall {
	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 *ProjectsLocationsProductsCertificatesListCall) Context(ctx context.Context) *ProjectsLocationsProductsCertificatesListCall {
	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 *ProjectsLocationsProductsCertificatesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsCertificatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/certificates")
	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 "integrations.projects.locations.products.certificates.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListCertificatesResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaListCertificatesResponse.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 *ProjectsLocationsProductsCertificatesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListCertificatesResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListCertificatesResponse{
		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 all the certificates that match the filter. Restrict to certificate of current client only.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/certificates",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.certificates.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filtering as supported in https://developers.google.com/authorized-buyers/apis/guides/list-filters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The size of entries in the response. If unspecified, defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The client, which owns this collection of Certificates.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "The mask which specifies fields that need to be returned in the Certificate's response.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/certificates",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListCertificatesResponse"
	//   },
	//   "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 *ProjectsLocationsProductsCertificatesListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListCertificatesResponse) 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 "integrations.projects.locations.products.certificates.patch":

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

// Patch: Updates the certificate by id. If new certificate file is
// updated, it will register with the trawler service, re-encrypt with
// cloud KMS and update the Spanner record. Other fields will directly
// update the Spanner record. Returns the Certificate.
//
// - name: Output only. Auto generated primary key.
func (r *ProjectsLocationsProductsCertificatesService) Patch(name string, googlecloudintegrationsv1alphacertificate *GoogleCloudIntegrationsV1alphaCertificate) *ProjectsLocationsProductsCertificatesPatchCall {
	c := &ProjectsLocationsProductsCertificatesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphacertificate = googlecloudintegrationsv1alphacertificate
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above Certificate that have been
// modified and need to be updated.
func (c *ProjectsLocationsProductsCertificatesPatchCall) UpdateMask(updateMask string) *ProjectsLocationsProductsCertificatesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.products.certificates.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaCertificate or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaCertificate.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 *ProjectsLocationsProductsCertificatesPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaCertificate, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaCertificate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the certificate by id. If new certificate file is updated, it will register with the trawler service, re-encrypt with cloud KMS and update the Spanner record. Other fields will directly update the Spanner record. Returns the Certificate.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/certificates/{certificatesId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.products.certificates.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Output only. Auto generated primary key",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/certificates/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above Certificate that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCertificate"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCertificate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.delete":

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

// Delete: Delete the selected integration and all versions inside
//
// - name: The location resource of the request.
func (r *ProjectsLocationsProductsIntegrationsService) Delete(name string) *ProjectsLocationsProductsIntegrationsDeleteCall {
	c := &ProjectsLocationsProductsIntegrationsDeleteCall{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 *ProjectsLocationsProductsIntegrationsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsDeleteCall {
	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 *ProjectsLocationsProductsIntegrationsDeleteCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsDeleteCall {
	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 *ProjectsLocationsProductsIntegrationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.integrations.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsProductsIntegrationsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		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 the selected integration and all versions inside",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.products.integrations.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The location resource of the request.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.execute":

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

// Execute: Executes integrations synchronously by passing the trigger
// id in the request body. The request is not returned until the
// requested executions are either fulfilled or experienced an error. If
// the integration name is not specified (passing `-`), all of the
// associated integration under the given trigger_id will be executed.
// Otherwise only the specified integration for the given `trigger_id`
// is executed. This is helpful for execution the integration from UI.
//
// - name: The integration resource name.
func (r *ProjectsLocationsProductsIntegrationsService) Execute(name string, googlecloudintegrationsv1alphaexecuteintegrationsrequest *GoogleCloudIntegrationsV1alphaExecuteIntegrationsRequest) *ProjectsLocationsProductsIntegrationsExecuteCall {
	c := &ProjectsLocationsProductsIntegrationsExecuteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaexecuteintegrationsrequest = googlecloudintegrationsv1alphaexecuteintegrationsrequest
	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 *ProjectsLocationsProductsIntegrationsExecuteCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsExecuteCall {
	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 *ProjectsLocationsProductsIntegrationsExecuteCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsExecuteCall {
	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 *ProjectsLocationsProductsIntegrationsExecuteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsExecuteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaexecuteintegrationsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:execute")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.products.integrations.execute" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse.ServerRespo
// nse.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 *ProjectsLocationsProductsIntegrationsExecuteCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse{
		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": "Executes integrations synchronously by passing the trigger id in the request body. The request is not returned until the requested executions are either fulfilled or experienced an error. If the integration name is not specified (passing `-`), all of the associated integration under the given trigger_id will be executed. Otherwise only the specified integration for the given `trigger_id` is executed. This is helpful for execution the integration from UI.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}:execute",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.execute",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The integration resource name.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:execute",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaExecuteIntegrationsRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaExecuteIntegrationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.list":

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

// List: Returns the list of all integrations in the specified project.
//
//   - parent: Project and location from which the integrations should be
//     listed. Format: projects/{project}.
func (r *ProjectsLocationsProductsIntegrationsService) List(parent string) *ProjectsLocationsProductsIntegrationsListCall {
	c := &ProjectsLocationsProductsIntegrationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filter on fields of
// IntegrationVersion. Fields can be compared with literal values by use
// of ":" (containment), "=" (equality), ">" (greater), "<" (less than),
// >=" (greater than or equal to), "<=" (less than or equal to), and
// "!=" (inequality) operators. Negation, conjunction, and disjunction
// are written using NOT, AND, and OR keywords. For example,
// organization_id=\"1\" AND state=ACTIVE AND description:"test".
// Filtering cannot be performed on repeated fields like `task_config`.
func (c *ProjectsLocationsProductsIntegrationsListCall) Filter(filter string) *ProjectsLocationsProductsIntegrationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": The results would be
// returned in order you specified here. Supported sort keys are:
// Descending sort order by "last_modified_time", "created_time",
// "snapshot_number". Ascending sort order by the integration name.
func (c *ProjectsLocationsProductsIntegrationsListCall) OrderBy(orderBy string) *ProjectsLocationsProductsIntegrationsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The page size for
// the resquest.
func (c *ProjectsLocationsProductsIntegrationsListCall) PageSize(pageSize int64) *ProjectsLocationsProductsIntegrationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

func (c *ProjectsLocationsProductsIntegrationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/integrations")
	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 "integrations.projects.locations.products.integrations.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListIntegrationsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaListIntegrationsResponse.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 *ProjectsLocationsProductsIntegrationsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListIntegrationsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListIntegrationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the list of all integrations in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrations.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filter on fields of IntegrationVersion. Fields can be compared with literal values by use of \":\" (containment), \"=\" (equality), \"\u003e\" (greater), \"\u003c\" (less than), \u003e=\" (greater than or equal to), \"\u003c=\" (less than or equal to), and \"!=\" (inequality) operators. Negation, conjunction, and disjunction are written using NOT, AND, and OR keywords. For example, organization_id=\\\"1\\\" AND state=ACTIVE AND description:\"test\". Filtering cannot be performed on repeated fields like `task_config`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "The results would be returned in order you specified here. Supported sort keys are: Descending sort order by \"last_modified_time\", \"created_time\", \"snapshot_number\". Ascending sort order by the integration name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The page size for the resquest.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The page token for the resquest.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Project and location from which the integrations should be listed. Format: projects/{project}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/integrations",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListIntegrationsResponse"
	//   },
	//   "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 *ProjectsLocationsProductsIntegrationsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListIntegrationsResponse) 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 "integrations.projects.locations.products.integrations.schedule":

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

// Schedule: Schedules an integration for execution by passing the
// trigger id and the scheduled time in the request body.
//
// - name: The integration resource name.
func (r *ProjectsLocationsProductsIntegrationsService) Schedule(name string, googlecloudintegrationsv1alphascheduleintegrationsrequest *GoogleCloudIntegrationsV1alphaScheduleIntegrationsRequest) *ProjectsLocationsProductsIntegrationsScheduleCall {
	c := &ProjectsLocationsProductsIntegrationsScheduleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphascheduleintegrationsrequest = googlecloudintegrationsv1alphascheduleintegrationsrequest
	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 *ProjectsLocationsProductsIntegrationsScheduleCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsScheduleCall {
	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 *ProjectsLocationsProductsIntegrationsScheduleCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsScheduleCall {
	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 *ProjectsLocationsProductsIntegrationsScheduleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsScheduleCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphascheduleintegrationsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:schedule")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.products.integrations.schedule" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse.ServerResp
// onse.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 *ProjectsLocationsProductsIntegrationsScheduleCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse{
		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": "Schedules an integration for execution by passing the trigger id and the scheduled time in the request body.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}:schedule",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.schedule",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The integration resource name.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:schedule",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaScheduleIntegrationsRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaScheduleIntegrationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.executions.cancel":

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

// Cancel: Cancellation of an execution
//
//   - name: The execution resource name. Format:
//     projects/{gcp_project_id}/locations/{location}/products/{product}/in
//     tegrations/{integration_id}/executions/{execution_id}.
func (r *ProjectsLocationsProductsIntegrationsExecutionsService) Cancel(name string, googlecloudintegrationsv1alphacancelexecutionrequest *GoogleCloudIntegrationsV1alphaCancelExecutionRequest) *ProjectsLocationsProductsIntegrationsExecutionsCancelCall {
	c := &ProjectsLocationsProductsIntegrationsExecutionsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphacancelexecutionrequest = googlecloudintegrationsv1alphacancelexecutionrequest
	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 *ProjectsLocationsProductsIntegrationsExecutionsCancelCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsExecutionsCancelCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsCancelCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsExecutionsCancelCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsExecutionsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphacancelexecutionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.products.integrations.executions.cancel" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaCancelExecutionResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaCancelExecutionResponse.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 *ProjectsLocationsProductsIntegrationsExecutionsCancelCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaCancelExecutionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaCancelExecutionResponse{
		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": "Cancellation of an execution",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/executions/{executionsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.executions.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The execution resource name. Format: projects/{gcp_project_id}/locations/{location}/products/{product}/integrations/{integration_id}/executions/{execution_id}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/executions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:cancel",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCancelExecutionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaCancelExecutionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.executions.get":

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

// Get: Get an execution in the specified project.
//
//   - name: The execution resource name. Format:
//     projects/{gcp_project_id}/locations/{location}/products/{product}/in
//     tegrations/{integration_id}/executions/{execution_id}.
func (r *ProjectsLocationsProductsIntegrationsExecutionsService) Get(name string) *ProjectsLocationsProductsIntegrationsExecutionsGetCall {
	c := &ProjectsLocationsProductsIntegrationsExecutionsGetCall{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 *ProjectsLocationsProductsIntegrationsExecutionsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsExecutionsGetCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsIntegrationsExecutionsGetCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsGetCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsExecutionsGetCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.integrations.executions.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaExecution or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaExecution.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 *ProjectsLocationsProductsIntegrationsExecutionsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaExecution, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaExecution{
		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 an execution in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/executions/{executionsId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrations.executions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The execution resource name. Format: projects/{gcp_project_id}/locations/{location}/products/{product}/integrations/{integration_id}/executions/{execution_id}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/executions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaExecution"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.executions.list":

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

// List: Lists the results of all the integration executions. The
// response includes the same information as the execution log
// (https://cloud.google.com/application-integration/docs/viewing-logs)
// in the Integration UI.
//
// - parent: The parent resource name of the integration execution.
func (r *ProjectsLocationsProductsIntegrationsExecutionsService) List(parent string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c := &ProjectsLocationsProductsIntegrationsExecutionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Standard filter field,
// we support filtering on following fields: workflow_name: the name of
// the integration. CreateTimestamp: the execution created time.
// event_execution_state: the state of the executions. execution_id: the
// id of the execution. trigger_id: the id of the trigger.
// parameter_type: the type of the parameters involved in the execution.
// All fields support for EQUALS, in additional: CreateTimestamp support
// for LESS_THAN, GREATER_THAN ParameterType support for HAS For
// example: "parameter_type" HAS \"string\" Also supports operators like
// AND, OR, NOT For example, trigger_id=\"id1\" AND
// workflow_name=\"testWorkflow\"
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) Filter(filter string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// FilterParamsCustomFilter sets the optional parameter
// "filterParams.customFilter": Optional user-provided custom filter.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsCustomFilter(filterParamsCustomFilter string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.customFilter", filterParamsCustomFilter)
	return c
}

// FilterParamsEndTime sets the optional parameter
// "filterParams.endTime": End timestamp.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsEndTime(filterParamsEndTime int64) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.endTime", fmt.Sprint(filterParamsEndTime))
	return c
}

// FilterParamsEventStatuses sets the optional parameter
// "filterParams.eventStatuses": List of possible event statuses.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsEventStatuses(filterParamsEventStatuses ...string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.SetMulti("filterParams.eventStatuses", append([]string{}, filterParamsEventStatuses...))
	return c
}

// FilterParamsExecutionId sets the optional parameter
// "filterParams.executionId": Execution id.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsExecutionId(filterParamsExecutionId string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.executionId", filterParamsExecutionId)
	return c
}

// FilterParamsParameterKey sets the optional parameter
// "filterParams.parameterKey": Param key. DEPRECATED. User
// parameter_pair_key instead.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsParameterKey(filterParamsParameterKey string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterKey", filterParamsParameterKey)
	return c
}

// FilterParamsParameterPairKey sets the optional parameter
// "filterParams.parameterPairKey": Param key in the key value pair
// filter.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsParameterPairKey(filterParamsParameterPairKey string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterPairKey", filterParamsParameterPairKey)
	return c
}

// FilterParamsParameterPairValue sets the optional parameter
// "filterParams.parameterPairValue": Param value in the key value pair
// filter.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsParameterPairValue(filterParamsParameterPairValue string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterPairValue", filterParamsParameterPairValue)
	return c
}

// FilterParamsParameterType sets the optional parameter
// "filterParams.parameterType": Param type.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsParameterType(filterParamsParameterType string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterType", filterParamsParameterType)
	return c
}

// FilterParamsParameterValue sets the optional parameter
// "filterParams.parameterValue": Param value. DEPRECATED. User
// parameter_pair_value instead.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsParameterValue(filterParamsParameterValue string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.parameterValue", filterParamsParameterValue)
	return c
}

// FilterParamsStartTime sets the optional parameter
// "filterParams.startTime": Start timestamp.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsStartTime(filterParamsStartTime int64) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.startTime", fmt.Sprint(filterParamsStartTime))
	return c
}

// FilterParamsTaskStatuses sets the optional parameter
// "filterParams.taskStatuses": List of possible task statuses.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsTaskStatuses(filterParamsTaskStatuses ...string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.SetMulti("filterParams.taskStatuses", append([]string{}, filterParamsTaskStatuses...))
	return c
}

// FilterParamsWorkflowName sets the optional parameter
// "filterParams.workflowName": Workflow name.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) FilterParamsWorkflowName(filterParamsWorkflowName string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("filterParams.workflowName", filterParamsWorkflowName)
	return c
}

// OrderBy sets the optional parameter "orderBy": The results would be
// returned in order you specified here. Currently supporting
// "last_modified_time" and "create_time".
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) OrderBy(orderBy string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) PageSize(pageSize int64) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) PageToken(pageToken string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": View mask for the
// response data. If set, only the field specified will be returned as
// part of the result. If not set, all fields in event execution info
// will be filled and returned.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) ReadMask(readMask string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("readMask", readMask)
	return c
}

// RefreshAcl sets the optional parameter "refreshAcl": If true, the
// service will use the most recent acl information to list event
// execution infos and renew the acl cache. Note that fetching the most
// recent acl is synchronous, so it will increase RPC call latency.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) RefreshAcl(refreshAcl bool) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("refreshAcl", fmt.Sprint(refreshAcl))
	return c
}

// TruncateParams sets the optional parameter "truncateParams": If true,
// the service will truncate the params to only keep the first 1000
// characters of string params and empty the executions in order to make
// response smaller. Only works for UI and when the params fields are
// not filtered out.
func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) TruncateParams(truncateParams bool) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	c.urlParams_.Set("truncateParams", fmt.Sprint(truncateParams))
	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 *ProjectsLocationsProductsIntegrationsExecutionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsListCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsExecutionsListCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsExecutionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/executions")
	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 "integrations.projects.locations.products.integrations.executions.list" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaListExecutionsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaListExecutionsResponse.ServerResponse.H
// eader 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 *ProjectsLocationsProductsIntegrationsExecutionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListExecutionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListExecutionsResponse{
		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 the results of all the integration executions. The response includes the same information as the [execution log](https://cloud.google.com/application-integration/docs/viewing-logs) in the Integration UI.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/executions",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrations.executions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Optional. Standard filter field, we support filtering on following fields: workflow_name: the name of the integration. CreateTimestamp: the execution created time. event_execution_state: the state of the executions. execution_id: the id of the execution. trigger_id: the id of the trigger. parameter_type: the type of the parameters involved in the execution. All fields support for EQUALS, in additional: CreateTimestamp support for LESS_THAN, GREATER_THAN ParameterType support for HAS For example: \"parameter_type\" HAS \\\"string\\\" Also supports operators like AND, OR, NOT For example, trigger_id=\\\"id1\\\" AND workflow_name=\\\"testWorkflow\\\"",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.customFilter": {
	//       "description": "Optional user-provided custom filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.endTime": {
	//       "description": "End timestamp.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.eventStatuses": {
	//       "description": "List of possible event statuses.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "filterParams.executionId": {
	//       "description": "Execution id.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterKey": {
	//       "deprecated": true,
	//       "description": "Param key. DEPRECATED. User parameter_pair_key instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterPairKey": {
	//       "description": "Param key in the key value pair filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterPairValue": {
	//       "description": "Param value in the key value pair filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterType": {
	//       "description": "Param type.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.parameterValue": {
	//       "deprecated": true,
	//       "description": "Param value. DEPRECATED. User parameter_pair_value instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.startTime": {
	//       "description": "Start timestamp.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filterParams.taskStatuses": {
	//       "deprecated": true,
	//       "description": "List of possible task statuses.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "filterParams.workflowName": {
	//       "description": "Workflow name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Optional. The results would be returned in order you specified here. Currently supporting \"last_modified_time\" and \"create_time\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The size of entries in the response.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource name of the integration execution.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "Optional. View mask for the response data. If set, only the field specified will be returned as part of the result. If not set, all fields in event execution info will be filled and returned.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "refreshAcl": {
	//       "description": "Optional. If true, the service will use the most recent acl information to list event execution infos and renew the acl cache. Note that fetching the most recent acl is synchronous, so it will increase RPC call latency.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "truncateParams": {
	//       "deprecated": true,
	//       "description": "Optional. If true, the service will truncate the params to only keep the first 1000 characters of string params and empty the executions in order to make response smaller. Only works for UI and when the params fields are not filtered out.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/executions",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListExecutionsResponse"
	//   },
	//   "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 *ProjectsLocationsProductsIntegrationsExecutionsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListExecutionsResponse) 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 "integrations.projects.locations.products.integrations.executions.suspensions.lift":

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

// Lift: * Lifts suspension for advanced suspension task. Fetch
// corresponding suspension with provided suspension Id, resolve
// suspension, and set up suspension result for the Suspension Task.
//
//   - name: The resource that the suspension belongs to.
//     "projects/{project}/locations/{location}/products/{product}/integrat
//     ions/{integration}/executions/{execution}/suspensions/{suspenion}"
//     format.
func (r *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsService) Lift(name string, googlecloudintegrationsv1alphaliftsuspensionrequest *GoogleCloudIntegrationsV1alphaLiftSuspensionRequest) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall {
	c := &ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaliftsuspensionrequest = googlecloudintegrationsv1alphaliftsuspensionrequest
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaliftsuspensionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:lift")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.products.integrations.executions.suspensions.lift" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaLiftSuspensionResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaLiftSuspensionResponse.ServerResponse.H
// eader 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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsLiftCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaLiftSuspensionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaLiftSuspensionResponse{
		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": "* Lifts suspension for advanced suspension task. Fetch corresponding suspension with provided suspension Id, resolve suspension, and set up suspension result for the Suspension Task.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/executions/{executionsId}/suspensions/{suspensionsId}:lift",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.executions.suspensions.lift",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource that the suspension belongs to. \"projects/{project}/locations/{location}/products/{product}/integrations/{integration}/executions/{execution}/suspensions/{suspenion}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/executions/[^/]+/suspensions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:lift",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaLiftSuspensionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaLiftSuspensionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.executions.suspensions.list":

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

// List: * Lists suspensions associated with a specific execution. Only
// those with permissions to resolve the relevant suspensions will be
// able to view them.
//
//   - parent:
//     projects/{gcp_project_id}/locations/{location}/products/{product}/in
//     tegrations/{integration_name}/executions/{execution_name}.
func (r *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsService) List(parent string) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall {
	c := &ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Standard filter field.
func (c *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) Filter(filter string) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field name to order
// by.
func (c *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) OrderBy(orderBy string) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// entries in the response.
func (c *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) PageSize(pageSize int64) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to retrieve
// a specific page.
func (c *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) PageToken(pageToken string) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/suspensions")
	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 "integrations.projects.locations.products.integrations.executions.suspensions.list" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaListSuspensionsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaListSuspensionsResponse.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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListSuspensionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListSuspensionsResponse{
		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 suspensions associated with a specific execution. Only those with permissions to resolve the relevant suspensions will be able to view them.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/executions/{executionsId}/suspensions",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrations.executions.suspensions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Standard filter field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field name to order by.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of entries in the response.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to retrieve a specific page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. projects/{gcp_project_id}/locations/{location}/products/{product}/integrations/{integration_name}/executions/{execution_name}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/executions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/suspensions",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListSuspensionsResponse"
	//   },
	//   "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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListSuspensionsResponse) 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 "integrations.projects.locations.products.integrations.executions.suspensions.resolve":

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

// Resolve: * Resolves (lifts/rejects) any number of suspensions. If the
// integration is already running, only the status of the suspension is
// updated. Otherwise, the suspended integration will begin execution
// again.
//
//   - name:
//     projects/{gcp_project_id}/locations/{location}/products/{product}/in
//     tegrations/{integration_name}/executions/{execution_name}/suspension
//     s/{suspension_id}.
func (r *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsService) Resolve(name string, googlecloudintegrationsv1alpharesolvesuspensionrequest *GoogleCloudIntegrationsV1alphaResolveSuspensionRequest) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall {
	c := &ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alpharesolvesuspensionrequest = googlecloudintegrationsv1alpharesolvesuspensionrequest
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall {
	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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alpharesolvesuspensionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:resolve")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.products.integrations.executions.suspensions.resolve" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaResolveSuspensionResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaResolveSuspensionResponse.ServerRespons
// e.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 *ProjectsLocationsProductsIntegrationsExecutionsSuspensionsResolveCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaResolveSuspensionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaResolveSuspensionResponse{
		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": "* Resolves (lifts/rejects) any number of suspensions. If the integration is already running, only the status of the suspension is updated. Otherwise, the suspended integration will begin execution again.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/executions/{executionsId}/suspensions/{suspensionsId}:resolve",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.executions.suspensions.resolve",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. projects/{gcp_project_id}/locations/{location}/products/{product}/integrations/{integration_name}/executions/{execution_name}/suspensions/{suspension_id}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/executions/[^/]+/suspensions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:resolve",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaResolveSuspensionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaResolveSuspensionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.create":

type ProjectsLocationsProductsIntegrationsVersionsCreateCall struct {
	s                                                *Service
	parent                                           string
	googlecloudintegrationsv1alphaintegrationversion *GoogleCloudIntegrationsV1alphaIntegrationVersion
	urlParams_                                       gensupport.URLParams
	ctx_                                             context.Context
	header_                                          http.Header
}

// Create: Create a integration with a draft version in the specified
// project.
//
//   - parent: The parent resource where this version will be created.
//     Format:
//     projects/{project}/locations/{location}/integrations/{integration}.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) Create(parent string, googlecloudintegrationsv1alphaintegrationversion *GoogleCloudIntegrationsV1alphaIntegrationVersion) *ProjectsLocationsProductsIntegrationsVersionsCreateCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphaintegrationversion = googlecloudintegrationsv1alphaintegrationversion
	return c
}

// NewIntegration sets the optional parameter "newIntegration": Set this
// flag to true, if draft version is to be created for a brand new
// integration. False, if the request is for an existing integration.
// For backward compatibility reasons, even if this flag is set to
// `false` and no existing integration is found, a new draft integration
// will still be created.
func (c *ProjectsLocationsProductsIntegrationsVersionsCreateCall) NewIntegration(newIntegration bool) *ProjectsLocationsProductsIntegrationsVersionsCreateCall {
	c.urlParams_.Set("newIntegration", fmt.Sprint(newIntegration))
	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 *ProjectsLocationsProductsIntegrationsVersionsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsCreateCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsCreateCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsCreateCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsVersionsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaintegrationversion)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/versions")
	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 "integrations.projects.locations.products.integrations.versions.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaIntegrationVersion or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaIntegrationVersion.ServerResponse.Heade
// r 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 *ProjectsLocationsProductsIntegrationsVersionsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaIntegrationVersion, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaIntegrationVersion{
		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 integration with a draft version in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.versions.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "newIntegration": {
	//       "description": "Set this flag to true, if draft version is to be created for a brand new integration. False, if the request is for an existing integration. For backward compatibility reasons, even if this flag is set to `false` and no existing integration is found, a new draft integration will still be created.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource where this version will be created. Format: projects/{project}/locations/{location}/integrations/{integration}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/versions",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.delete":

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

// Delete: Soft-deletes the integration. Changes the status of the
// integration to ARCHIVED. If the integration being ARCHIVED is tagged
// as "HEAD", the tag is removed from this snapshot and set to the
// previous non-ARCHIVED snapshot. The PUBLISH_REQUESTED,
// DUE_FOR_DELETION tags are removed too. This RPC throws an exception
// if the version being deleted is DRAFT, and if the `locked_by` user is
// not the same as the user performing the Delete. Audit fields updated
// include last_modified_timestamp, last_modified_by. Any existing lock
// is released when Deleting a integration. Currently, there is no
// undelete mechanism.
//
//   - name: The version to delete. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) Delete(name string) *ProjectsLocationsProductsIntegrationsVersionsDeleteCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsDeleteCall{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 *ProjectsLocationsProductsIntegrationsVersionsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsDeleteCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsDeleteCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsDeleteCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.integrations.versions.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsProductsIntegrationsVersionsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		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": "Soft-deletes the integration. Changes the status of the integration to ARCHIVED. If the integration being ARCHIVED is tagged as \"HEAD\", the tag is removed from this snapshot and set to the previous non-ARCHIVED snapshot. The PUBLISH_REQUESTED, DUE_FOR_DELETION tags are removed too. This RPC throws an exception if the version being deleted is DRAFT, and if the `locked_by` user is not the same as the user performing the Delete. Audit fields updated include last_modified_timestamp, last_modified_by. Any existing lock is released when Deleting a integration. Currently, there is no undelete mechanism.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions/{versionsId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.products.integrations.versions.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The version to delete. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.download":

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

// Download: Downloads an integration. Retrieves the
// `IntegrationVersion` for a given `integration_id` and returns the
// response as a string.
//
//   - name: The version to download. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) Download(name string) *ProjectsLocationsProductsIntegrationsVersionsDownloadCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsDownloadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// FileFormat sets the optional parameter "fileFormat": File format for
// download request.
//
// Possible values:
//
//	"FILE_FORMAT_UNSPECIFIED" - Unspecified file format
//	"JSON" - JSON File Format
//	"YAML" - YAML File Format
func (c *ProjectsLocationsProductsIntegrationsVersionsDownloadCall) FileFormat(fileFormat string) *ProjectsLocationsProductsIntegrationsVersionsDownloadCall {
	c.urlParams_.Set("fileFormat", fileFormat)
	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 *ProjectsLocationsProductsIntegrationsVersionsDownloadCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsDownloadCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsDownloadCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsIntegrationsVersionsDownloadCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsDownloadCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsDownloadCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsDownloadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsVersionsDownloadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:download")
	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 "integrations.projects.locations.products.integrations.versions.download" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse.Serv
// erResponse.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 *ProjectsLocationsProductsIntegrationsVersionsDownloadCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse{
		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": "Downloads an integration. Retrieves the `IntegrationVersion` for a given `integration_id` and returns the response as a string.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions/{versionsId}:download",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrations.versions.download",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "fileFormat": {
	//       "description": "File format for download request.",
	//       "enum": [
	//         "FILE_FORMAT_UNSPECIFIED",
	//         "JSON",
	//         "YAML"
	//       ],
	//       "enumDescriptions": [
	//         "Unspecified file format",
	//         "JSON File Format",
	//         "YAML File Format"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The version to download. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:download",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaDownloadIntegrationVersionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.get":

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

// Get: Get a integration in the specified project.
//
//   - name: The version to retrieve. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) Get(name string) *ProjectsLocationsProductsIntegrationsVersionsGetCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsGetCall{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 *ProjectsLocationsProductsIntegrationsVersionsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsGetCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsIntegrationsVersionsGetCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsGetCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsGetCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.integrations.versions.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaIntegrationVersion or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaIntegrationVersion.ServerResponse.Heade
// r 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 *ProjectsLocationsProductsIntegrationsVersionsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaIntegrationVersion, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaIntegrationVersion{
		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 a integration in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions/{versionsId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrations.versions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The version to retrieve. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.list":

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

// List: Returns the list of all integration versions in the specified
// project.
//
//   - parent: The parent resource where this version will be created.
//     Format:
//     projects/{project}/locations/{location}/integrations/{integration}
//     Specifically, when parent equals: 1.
//     projects//locations//integrations/, Meaning: "List versions (with
//     filter) for a particular integration". 2.
//     projects//locations//integrations/- Meaning: "List versions (with
//     filter) for a client within a particular region". 3.
//     projects//locations/-/integrations/- Meaning: "List versions (with
//     filter) for a client".
func (r *ProjectsLocationsProductsIntegrationsVersionsService) List(parent string) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// FieldMask sets the optional parameter "fieldMask": The field mask
// which specifies the particular data to be returned.
func (c *ProjectsLocationsProductsIntegrationsVersionsListCall) FieldMask(fieldMask string) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	c.urlParams_.Set("fieldMask", fieldMask)
	return c
}

// Filter sets the optional parameter "filter": Filter on fields of
// IntegrationVersion. Fields can be compared with literal values by use
// of ":" (containment), "=" (equality), ">" (greater), "<" (less than),
// >=" (greater than or equal to), "<=" (less than or equal to), and
// "!=" (inequality) operators. Negation, conjunction, and disjunction
// are written using NOT, AND, and OR keywords. For example,
// organization_id=\"1\" AND state=ACTIVE AND description:"test".
// Filtering cannot be performed on repeated fields like `task_config`.
func (c *ProjectsLocationsProductsIntegrationsVersionsListCall) Filter(filter string) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": The results would be
// returned in order you specified here. Currently supported sort keys
// are: Descending sort order for "last_modified_time", "created_time",
// "snapshot_number" Ascending sort order for "name".
func (c *ProjectsLocationsProductsIntegrationsVersionsListCall) OrderBy(orderBy string) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of versions to return. The service may return fewer than this value.
// If unspecified, at most 50 versions will be returned. The maximum
// value is 1000; values above 1000 will be coerced to 1000.
func (c *ProjectsLocationsProductsIntegrationsVersionsListCall) PageSize(pageSize int64) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token,
// received from a previous `ListIntegrationVersions` call. Provide this
// to retrieve the subsequent page. When paginating, all other
// parameters provided to `ListIntegrationVersions` must match the call
// that provided the page token.
func (c *ProjectsLocationsProductsIntegrationsVersionsListCall) PageToken(pageToken string) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsListCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsListCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsVersionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/versions")
	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 "integrations.projects.locations.products.integrations.versions.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse.ServerR
// esponse.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 *ProjectsLocationsProductsIntegrationsVersionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the list of all integration versions in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrations.versions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "fieldMask": {
	//       "description": "The field mask which specifies the particular data to be returned.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Filter on fields of IntegrationVersion. Fields can be compared with literal values by use of \":\" (containment), \"=\" (equality), \"\u003e\" (greater), \"\u003c\" (less than), \u003e=\" (greater than or equal to), \"\u003c=\" (less than or equal to), and \"!=\" (inequality) operators. Negation, conjunction, and disjunction are written using NOT, AND, and OR keywords. For example, organization_id=\\\"1\\\" AND state=ACTIVE AND description:\"test\". Filtering cannot be performed on repeated fields like `task_config`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "The results would be returned in order you specified here. Currently supported sort keys are: Descending sort order for \"last_modified_time\", \"created_time\", \"snapshot_number\" Ascending sort order for \"name\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of versions to return. The service may return fewer than this value. If unspecified, at most 50 versions will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A page token, received from a previous `ListIntegrationVersions` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListIntegrationVersions` must match the call that provided the page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The parent resource where this version will be created. Format: projects/{project}/locations/{location}/integrations/{integration} Specifically, when parent equals: 1. projects//locations//integrations/, Meaning: \"List versions (with filter) for a particular integration\". 2. projects//locations//integrations/- Meaning: \"List versions (with filter) for a client within a particular region\". 3. projects//locations/-/integrations/- Meaning: \"List versions (with filter) for a client\".",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/versions",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse"
	//   },
	//   "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 *ProjectsLocationsProductsIntegrationsVersionsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListIntegrationVersionsResponse) 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 "integrations.projects.locations.products.integrations.versions.patch":

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

// Patch: Update a integration with a draft version in the specified
// project.
//
// - name: Output only. Auto-generated primary key.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) Patch(name string, googlecloudintegrationsv1alphaintegrationversion *GoogleCloudIntegrationsV1alphaIntegrationVersion) *ProjectsLocationsProductsIntegrationsVersionsPatchCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaintegrationversion = googlecloudintegrationsv1alphaintegrationversion
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above integration that have been
// modified and need to be updated.
func (c *ProjectsLocationsProductsIntegrationsVersionsPatchCall) UpdateMask(updateMask string) *ProjectsLocationsProductsIntegrationsVersionsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.products.integrations.versions.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaIntegrationVersion or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaIntegrationVersion.ServerResponse.Heade
// r 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 *ProjectsLocationsProductsIntegrationsVersionsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaIntegrationVersion, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaIntegrationVersion{
		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": "Update a integration with a draft version in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions/{versionsId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.products.integrations.versions.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Output only. Auto-generated primary key.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above integration that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.publish":

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

// Publish: This RPC throws an exception if the integration is in
// ARCHIVED or ACTIVE state. This RPC throws an exception if the version
// being published is DRAFT, and if the `locked_by` user is not the same
// as the user performing the Publish. Audit fields updated include
// last_published_timestamp, last_published_by, last_modified_timestamp,
// last_modified_by. Any existing lock is on this integration is
// released.
//
//   - name: The version to publish. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) Publish(name string, googlecloudintegrationsv1alphapublishintegrationversionrequest *GoogleCloudIntegrationsV1alphaPublishIntegrationVersionRequest) *ProjectsLocationsProductsIntegrationsVersionsPublishCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsPublishCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphapublishintegrationversionrequest = googlecloudintegrationsv1alphapublishintegrationversionrequest
	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 *ProjectsLocationsProductsIntegrationsVersionsPublishCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsPublishCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsPublishCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsPublishCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsPublishCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsVersionsPublishCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphapublishintegrationversionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:publish")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.products.integrations.versions.publish" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse.Serve
// rResponse.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 *ProjectsLocationsProductsIntegrationsVersionsPublishCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse{
		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": "This RPC throws an exception if the integration is in ARCHIVED or ACTIVE state. This RPC throws an exception if the version being published is DRAFT, and if the `locked_by` user is not the same as the user performing the Publish. Audit fields updated include last_published_timestamp, last_published_by, last_modified_timestamp, last_modified_by. Any existing lock is on this integration is released.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions/{versionsId}:publish",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.versions.publish",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The version to publish. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:publish",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaPublishIntegrationVersionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaPublishIntegrationVersionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.takeoverEditLock":

type ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall struct {
	s                                                     *Service
	integrationVersion                                    string
	googlecloudintegrationsv1alphatakeovereditlockrequest *GoogleCloudIntegrationsV1alphaTakeoverEditLockRequest
	urlParams_                                            gensupport.URLParams
	ctx_                                                  context.Context
	header_                                               http.Header
}

// TakeoverEditLock: Clears the `locked_by` and `locked_at_timestamp`in
// the DRAFT version of this integration. It then performs the same
// action as the CreateDraftIntegrationVersion (i.e., copies the DRAFT
// version of the integration as a SNAPSHOT and then creates a new DRAFT
// version with the `locked_by` set to the `user_taking_over` and the
// `locked_at_timestamp` set to the current timestamp). Both the
// `locked_by` and `user_taking_over` are notified via email about the
// takeover. This RPC throws an exception if the integration is not in
// DRAFT status or if the `locked_by` and `locked_at_timestamp` fields
// are not set.The TakeoverEdit lock is treated the same as an edit of
// the integration, and hence shares ACLs with edit. Audit fields
// updated include last_modified_timestamp, last_modified_by.
//
//   - integrationVersion: The version to take over edit lock. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) TakeoverEditLock(integrationVersion string, googlecloudintegrationsv1alphatakeovereditlockrequest *GoogleCloudIntegrationsV1alphaTakeoverEditLockRequest) *ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.integrationVersion = integrationVersion
	c.googlecloudintegrationsv1alphatakeovereditlockrequest = googlecloudintegrationsv1alphatakeovereditlockrequest
	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 *ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphatakeovereditlockrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+integrationVersion}:takeoverEditLock")
	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{
		"integrationVersion": c.integrationVersion,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.products.integrations.versions.takeoverEditLock" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse.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 *ProjectsLocationsProductsIntegrationsVersionsTakeoverEditLockCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse{
		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": "Clears the `locked_by` and `locked_at_timestamp`in the DRAFT version of this integration. It then performs the same action as the CreateDraftIntegrationVersion (i.e., copies the DRAFT version of the integration as a SNAPSHOT and then creates a new DRAFT version with the `locked_by` set to the `user_taking_over` and the `locked_at_timestamp` set to the current timestamp). Both the `locked_by` and `user_taking_over` are notified via email about the takeover. This RPC throws an exception if the integration is not in DRAFT status or if the `locked_by` and `locked_at_timestamp` fields are not set.The TakeoverEdit lock is treated the same as an edit of the integration, and hence shares ACLs with edit. Audit fields updated include last_modified_timestamp, last_modified_by.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions/{versionsId}:takeoverEditLock",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.versions.takeoverEditLock",
	//   "parameterOrder": [
	//     "integrationVersion"
	//   ],
	//   "parameters": {
	//     "integrationVersion": {
	//       "description": "Required. The version to take over edit lock. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+integrationVersion}:takeoverEditLock",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaTakeoverEditLockRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaTakeoverEditLockResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.unpublish":

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

// Unpublish: Sets the status of the ACTIVE integration to SNAPSHOT with
// a new tag "PREVIOUSLY_PUBLISHED" after validating it. The "HEAD" and
// "PUBLISH_REQUESTED" tags do not change. This RPC throws an exception
// if the version being snapshot is not ACTIVE. Audit fields added
// include action, action_by, action_timestamp.
//
//   - name: The version to deactivate. Format:
//     projects/{project}/locations/{location}/integrations/{integration}/v
//     ersions/{version}.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) Unpublish(name string, googlecloudintegrationsv1alphaunpublishintegrationversionrequest *GoogleCloudIntegrationsV1alphaUnpublishIntegrationVersionRequest) *ProjectsLocationsProductsIntegrationsVersionsUnpublishCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsUnpublishCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphaunpublishintegrationversionrequest = googlecloudintegrationsv1alphaunpublishintegrationversionrequest
	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 *ProjectsLocationsProductsIntegrationsVersionsUnpublishCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsUnpublishCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsUnpublishCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsUnpublishCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsUnpublishCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsVersionsUnpublishCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaunpublishintegrationversionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+name}:unpublish")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "integrations.projects.locations.products.integrations.versions.unpublish" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsProductsIntegrationsVersionsUnpublishCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		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 status of the ACTIVE integration to SNAPSHOT with a new tag \"PREVIOUSLY_PUBLISHED\" after validating it. The \"HEAD\" and \"PUBLISH_REQUESTED\" tags do not change. This RPC throws an exception if the version being snapshot is not ACTIVE. Audit fields added include action, action_by, action_timestamp.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions/{versionsId}:unpublish",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.versions.unpublish",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The version to deactivate. Format: projects/{project}/locations/{location}/integrations/{integration}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}:unpublish",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaUnpublishIntegrationVersionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrations.versions.upload":

type ProjectsLocationsProductsIntegrationsVersionsUploadCall struct {
	s                                                             *Service
	parent                                                        string
	googlecloudintegrationsv1alphauploadintegrationversionrequest *GoogleCloudIntegrationsV1alphaUploadIntegrationVersionRequest
	urlParams_                                                    gensupport.URLParams
	ctx_                                                          context.Context
	header_                                                       http.Header
}

// Upload: Uploads an integration. The content can be a previously
// downloaded integration. Performs the same function as
// CreateDraftIntegrationVersion, but accepts input in a string format,
// which holds the complete representation of the IntegrationVersion
// content.
//
//   - parent: The version to upload. Format:
//     projects/{project}/locations/{location}/integrations/{integration}.
func (r *ProjectsLocationsProductsIntegrationsVersionsService) Upload(parent string, googlecloudintegrationsv1alphauploadintegrationversionrequest *GoogleCloudIntegrationsV1alphaUploadIntegrationVersionRequest) *ProjectsLocationsProductsIntegrationsVersionsUploadCall {
	c := &ProjectsLocationsProductsIntegrationsVersionsUploadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphauploadintegrationversionrequest = googlecloudintegrationsv1alphauploadintegrationversionrequest
	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 *ProjectsLocationsProductsIntegrationsVersionsUploadCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationsVersionsUploadCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsUploadCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationsVersionsUploadCall {
	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 *ProjectsLocationsProductsIntegrationsVersionsUploadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationsVersionsUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphauploadintegrationversionrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/versions:upload")
	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 "integrations.projects.locations.products.integrations.versions.upload" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse.Server
// Response.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 *ProjectsLocationsProductsIntegrationsVersionsUploadCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse{
		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": "Uploads an integration. The content can be a previously downloaded integration. Performs the same function as CreateDraftIntegrationVersion, but accepts input in a string format, which holds the complete representation of the IntegrationVersion content.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrations/{integrationsId}/versions:upload",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrations.versions.upload",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The version to upload. Format: projects/{project}/locations/{location}/integrations/{integration}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/versions:upload",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaUploadIntegrationVersionRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaUploadIntegrationVersionResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrationtemplates.versions.create":

type ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall struct {
	s                                                        *Service
	parent                                                   string
	googlecloudintegrationsv1alphaintegrationtemplateversion *GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion
	urlParams_                                               gensupport.URLParams
	ctx_                                                     context.Context
	header_                                                  http.Header
}

// Create: Creates an IntegrationTemplateVersion.
//
//   - parent: The parent resource where this TemplateVersion will be
//     created. Format:
//     projects/{project}/location/{location}/product/{product}/integration
//     templates/{integrationtemplate}.
func (r *ProjectsLocationsProductsIntegrationtemplatesVersionsService) Create(parent string, googlecloudintegrationsv1alphaintegrationtemplateversion *GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion) *ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall {
	c := &ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphaintegrationtemplateversion = googlecloudintegrationsv1alphaintegrationtemplateversion
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphaintegrationtemplateversion)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/versions")
	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 "integrations.projects.locations.products.integrationtemplates.versions.create" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion.ServerRespon
// se.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsProductsIntegrationtemplatesVersionsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion{
		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 an IntegrationTemplateVersion.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrationtemplates/{integrationtemplatesId}/versions",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.integrationtemplates.versions.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The parent resource where this TemplateVersion will be created. Format: projects/{project}/location/{location}/product/{product}/integrationtemplates/{integrationtemplate}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrationtemplates/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/versions",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrationtemplates.versions.get":

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

// Get: Returns an IntegrationTemplateVersion in the specified project.
//
//   - name: The TemplateVersion to retrieve. Format:
//     projects/{project}/locations/{location}/products/{product}/integrati
//     ontemplates/{integrationtemplate}/versions/{version}.
func (r *ProjectsLocationsProductsIntegrationtemplatesVersionsService) Get(name string) *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall {
	c := &ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall{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 *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.integrationtemplates.versions.get" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion.ServerRespon
// se.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsProductsIntegrationtemplatesVersionsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion{
		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 an IntegrationTemplateVersion in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrationtemplates/{integrationtemplatesId}/versions/{versionsId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrationtemplates.versions.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The TemplateVersion to retrieve. Format: projects/{project}/locations/{location}/products/{product}/integrationtemplates/{integrationtemplate}/versions/{version}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrationtemplates/[^/]+/versions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaIntegrationTemplateVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.integrationtemplates.versions.list":

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

// List: Returns the list of all IntegrationTemplateVersions in the
// specified project.
//
//   - parent: Format:
//     projects/{project}/location/{location}/product/{product}/integration
//     templates/{integrationtemplate}.
func (r *ProjectsLocationsProductsIntegrationtemplatesVersionsService) List(parent string) *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall {
	c := &ProjectsLocationsProductsIntegrationtemplatesVersionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filter syntax: defined
// in the EBNF grammar.
func (c *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) Filter(filter string) *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of IntegrationTemplateVersions to return. The service may return
// fewer than this value. If unspecified, at most 50 versions will be
// returned. The maximum value is 1000; values above 1000 will be
// coerced to 1000.
func (c *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) PageSize(pageSize int64) *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token,
// received from a previous `ListIntegrationTemplateVersions` call.
// Provide this to retrieve the subsequent page. When paginating, all
// other parameters provided to `ListIntegrationTemplateVersions` must
// match the call that provided the page token.
func (c *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) PageToken(pageToken string) *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) Context(ctx context.Context) *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall {
	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 *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/versions")
	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 "integrations.projects.locations.products.integrationtemplates.versions.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListIntegrationTemplateVersionsResponse
//
//	or error will be non-nil. Any non-2xx status code is an error.
//
// Response headers are in either
// *GoogleCloudIntegrationsV1alphaListIntegrationTemplateVersionsResponse
// .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 *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListIntegrationTemplateVersionsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListIntegrationTemplateVersionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the list of all IntegrationTemplateVersions in the specified project.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/integrationtemplates/{integrationtemplatesId}/versions",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.integrationtemplates.versions.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filter syntax: defined in the EBNF grammar.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of IntegrationTemplateVersions to return. The service may return fewer than this value. If unspecified, at most 50 versions will be returned. The maximum value is 1000; values above 1000 will be coerced to 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A page token, received from a previous `ListIntegrationTemplateVersions` call. Provide this to retrieve the subsequent page. When paginating, all other parameters provided to `ListIntegrationTemplateVersions` must match the call that provided the page token.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Format: projects/{project}/location/{location}/product/{product}/integrationtemplates/{integrationtemplate}",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/integrationtemplates/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/versions",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListIntegrationTemplateVersionsResponse"
	//   },
	//   "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 *ProjectsLocationsProductsIntegrationtemplatesVersionsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListIntegrationTemplateVersionsResponse) 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 "integrations.projects.locations.products.sfdcInstances.create":

type ProjectsLocationsProductsSfdcInstancesCreateCall struct {
	s                                          *Service
	parent                                     string
	googlecloudintegrationsv1alphasfdcinstance *GoogleCloudIntegrationsV1alphaSfdcInstance
	urlParams_                                 gensupport.URLParams
	ctx_                                       context.Context
	header_                                    http.Header
}

// Create: Creates an sfdc instance record. Store the sfdc instance in
// Spanner. Returns the sfdc instance.
//
// - parent: "projects/{project}/locations/{location}" format.
func (r *ProjectsLocationsProductsSfdcInstancesService) Create(parent string, googlecloudintegrationsv1alphasfdcinstance *GoogleCloudIntegrationsV1alphaSfdcInstance) *ProjectsLocationsProductsSfdcInstancesCreateCall {
	c := &ProjectsLocationsProductsSfdcInstancesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphasfdcinstance = googlecloudintegrationsv1alphasfdcinstance
	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 *ProjectsLocationsProductsSfdcInstancesCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsSfdcInstancesCreateCall {
	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 *ProjectsLocationsProductsSfdcInstancesCreateCall) Context(ctx context.Context) *ProjectsLocationsProductsSfdcInstancesCreateCall {
	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 *ProjectsLocationsProductsSfdcInstancesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsSfdcInstancesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphasfdcinstance)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/sfdcInstances")
	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 "integrations.projects.locations.products.sfdcInstances.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcInstance or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcInstance.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 *ProjectsLocationsProductsSfdcInstancesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcInstance, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcInstance{
		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 an sfdc instance record. Store the sfdc instance in Spanner. Returns the sfdc instance.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.sfdcInstances.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. \"projects/{project}/locations/{location}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/sfdcInstances",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.sfdcInstances.delete":

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

// Delete: Deletes an sfdc instance.
//
// - name: The name that is associated with the SfdcInstance.
func (r *ProjectsLocationsProductsSfdcInstancesService) Delete(name string) *ProjectsLocationsProductsSfdcInstancesDeleteCall {
	c := &ProjectsLocationsProductsSfdcInstancesDeleteCall{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 *ProjectsLocationsProductsSfdcInstancesDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsSfdcInstancesDeleteCall {
	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 *ProjectsLocationsProductsSfdcInstancesDeleteCall) Context(ctx context.Context) *ProjectsLocationsProductsSfdcInstancesDeleteCall {
	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 *ProjectsLocationsProductsSfdcInstancesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.sfdcInstances.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsProductsSfdcInstancesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an sfdc instance.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances/{sfdcInstancesId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.products.sfdcInstances.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the SfdcInstance.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.sfdcInstances.get":

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

// Get: Gets an sfdc instance. If the instance doesn't exist,
// Code.NOT_FOUND exception will be thrown.
//
// - name: The name that is associated with the SfdcInstance.
func (r *ProjectsLocationsProductsSfdcInstancesService) Get(name string) *ProjectsLocationsProductsSfdcInstancesGetCall {
	c := &ProjectsLocationsProductsSfdcInstancesGetCall{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 *ProjectsLocationsProductsSfdcInstancesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsSfdcInstancesGetCall {
	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 *ProjectsLocationsProductsSfdcInstancesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsSfdcInstancesGetCall {
	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 *ProjectsLocationsProductsSfdcInstancesGetCall) Context(ctx context.Context) *ProjectsLocationsProductsSfdcInstancesGetCall {
	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 *ProjectsLocationsProductsSfdcInstancesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.sfdcInstances.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcInstance or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcInstance.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 *ProjectsLocationsProductsSfdcInstancesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcInstance, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcInstance{
		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 an sfdc instance. If the instance doesn't exist, Code.NOT_FOUND exception will be thrown.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances/{sfdcInstancesId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.sfdcInstances.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the SfdcInstance.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.sfdcInstances.list":

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

// List: Lists all sfdc instances that match the filter. Restrict to
// sfdc instances belonging to the current client only.
//
// - parent: The client, which owns this collection of SfdcInstances.
func (r *ProjectsLocationsProductsSfdcInstancesService) List(parent string) *ProjectsLocationsProductsSfdcInstancesListCall {
	c := &ProjectsLocationsProductsSfdcInstancesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filtering as supported
// in
// https://developers.google.com/authorized-buyers/apis/guides/list-filters.
func (c *ProjectsLocationsProductsSfdcInstancesListCall) Filter(filter string) *ProjectsLocationsProductsSfdcInstancesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response. If unspecified, defaults to 100.
func (c *ProjectsLocationsProductsSfdcInstancesListCall) PageSize(pageSize int64) *ProjectsLocationsProductsSfdcInstancesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsProductsSfdcInstancesListCall) PageToken(pageToken string) *ProjectsLocationsProductsSfdcInstancesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": The mask which
// specifies fields that need to be returned in the SfdcInstance's
// response.
func (c *ProjectsLocationsProductsSfdcInstancesListCall) ReadMask(readMask string) *ProjectsLocationsProductsSfdcInstancesListCall {
	c.urlParams_.Set("readMask", readMask)
	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 *ProjectsLocationsProductsSfdcInstancesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsSfdcInstancesListCall {
	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 *ProjectsLocationsProductsSfdcInstancesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsSfdcInstancesListCall {
	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 *ProjectsLocationsProductsSfdcInstancesListCall) Context(ctx context.Context) *ProjectsLocationsProductsSfdcInstancesListCall {
	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 *ProjectsLocationsProductsSfdcInstancesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsSfdcInstancesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/sfdcInstances")
	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 "integrations.projects.locations.products.sfdcInstances.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse.ServerRespons
// e.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 *ProjectsLocationsProductsSfdcInstancesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse{
		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 all sfdc instances that match the filter. Restrict to sfdc instances belonging to the current client only.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.sfdcInstances.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filtering as supported in https://developers.google.com/authorized-buyers/apis/guides/list-filters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The size of entries in the response. If unspecified, defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The client, which owns this collection of SfdcInstances.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "The mask which specifies fields that need to be returned in the SfdcInstance's response.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/sfdcInstances",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse"
	//   },
	//   "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 *ProjectsLocationsProductsSfdcInstancesListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse) 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 "integrations.projects.locations.products.sfdcInstances.patch":

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

// Patch: Updates an sfdc instance. Updates the sfdc instance in
// spanner. Returns the sfdc instance.
//
//   - name: Resource name of the SFDC instance
//     projects/{project}/locations/{location}/sfdcInstances/{sfdcInstance}
//     .
func (r *ProjectsLocationsProductsSfdcInstancesService) Patch(name string, googlecloudintegrationsv1alphasfdcinstance *GoogleCloudIntegrationsV1alphaSfdcInstance) *ProjectsLocationsProductsSfdcInstancesPatchCall {
	c := &ProjectsLocationsProductsSfdcInstancesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphasfdcinstance = googlecloudintegrationsv1alphasfdcinstance
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above SfdcInstance that have been
// modified and need to be updated.
func (c *ProjectsLocationsProductsSfdcInstancesPatchCall) UpdateMask(updateMask string) *ProjectsLocationsProductsSfdcInstancesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.products.sfdcInstances.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcInstance or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcInstance.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 *ProjectsLocationsProductsSfdcInstancesPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcInstance, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcInstance{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an sfdc instance. Updates the sfdc instance in spanner. Returns the sfdc instance.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances/{sfdcInstancesId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.products.sfdcInstances.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Resource name of the SFDC instance projects/{project}/locations/{location}/sfdcInstances/{sfdcInstance}.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above SfdcInstance that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.sfdcInstances.sfdcChannels.create":

type ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall struct {
	s                                         *Service
	parent                                    string
	googlecloudintegrationsv1alphasfdcchannel *GoogleCloudIntegrationsV1alphaSfdcChannel
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// Create: Creates an sfdc channel record. Store the sfdc channel in
// Spanner. Returns the sfdc channel.
//
// - parent: "projects/{project}/locations/{location}" format.
func (r *ProjectsLocationsProductsSfdcInstancesSfdcChannelsService) Create(parent string, googlecloudintegrationsv1alphasfdcchannel *GoogleCloudIntegrationsV1alphaSfdcChannel) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall {
	c := &ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphasfdcchannel = googlecloudintegrationsv1alphasfdcchannel
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall) Context(ctx context.Context) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphasfdcchannel)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/sfdcChannels")
	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 "integrations.projects.locations.products.sfdcInstances.sfdcChannels.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcChannel or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcChannel.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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcChannel, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcChannel{
		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 an sfdc channel record. Store the sfdc channel in Spanner. Returns the sfdc channel.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.products.sfdcInstances.sfdcChannels.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. \"projects/{project}/locations/{location}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/sfdcChannels",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.sfdcInstances.sfdcChannels.delete":

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

// Delete: Deletes an sfdc channel.
//
// - name: The name that is associated with the SfdcChannel.
func (r *ProjectsLocationsProductsSfdcInstancesSfdcChannelsService) Delete(name string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsDeleteCall {
	c := &ProjectsLocationsProductsSfdcInstancesSfdcChannelsDeleteCall{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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsDeleteCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsDeleteCall) Context(ctx context.Context) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsDeleteCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.sfdcInstances.sfdcChannels.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an sfdc channel.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels/{sfdcChannelsId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.products.sfdcInstances.sfdcChannels.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the SfdcChannel.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/sfdcInstances/[^/]+/sfdcChannels/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.sfdcInstances.sfdcChannels.get":

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

// Get: Gets an sfdc channel. If the channel doesn't exist,
// Code.NOT_FOUND exception will be thrown.
//
// - name: The name that is associated with the SfdcChannel.
func (r *ProjectsLocationsProductsSfdcInstancesSfdcChannelsService) Get(name string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall {
	c := &ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall{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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall) Context(ctx context.Context) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.products.sfdcInstances.sfdcChannels.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcChannel or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcChannel.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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcChannel, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcChannel{
		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 an sfdc channel. If the channel doesn't exist, Code.NOT_FOUND exception will be thrown.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels/{sfdcChannelsId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.sfdcInstances.sfdcChannels.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the SfdcChannel.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/sfdcInstances/[^/]+/sfdcChannels/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.products.sfdcInstances.sfdcChannels.list":

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

// List: Lists all sfdc channels that match the filter. Restrict to sfdc
// channels belonging to the current client only.
//
// - parent: The client, which owns this collection of SfdcChannels.
func (r *ProjectsLocationsProductsSfdcInstancesSfdcChannelsService) List(parent string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall {
	c := &ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filtering as supported
// in
// https://developers.google.com/authorized-buyers/apis/guides/list-filters.
func (c *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) Filter(filter string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response. If unspecified, defaults to 100.
func (c *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) PageSize(pageSize int64) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) PageToken(pageToken string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": The mask which
// specifies fields that need to be returned in the SfdcChannel's
// response.
func (c *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) ReadMask(readMask string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall {
	c.urlParams_.Set("readMask", readMask)
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) Context(ctx context.Context) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall {
	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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/sfdcChannels")
	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 "integrations.projects.locations.products.sfdcInstances.sfdcChannels.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse.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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse{
		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 all sfdc channels that match the filter. Restrict to sfdc channels belonging to the current client only.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.products.sfdcInstances.sfdcChannels.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filtering as supported in https://developers.google.com/authorized-buyers/apis/guides/list-filters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The size of entries in the response. If unspecified, defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The client, which owns this collection of SfdcChannels.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "The mask which specifies fields that need to be returned in the SfdcChannel's response.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/sfdcChannels",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse"
	//   },
	//   "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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse) 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 "integrations.projects.locations.products.sfdcInstances.sfdcChannels.patch":

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

// Patch: Updates an sfdc channel. Updates the sfdc channel in spanner.
// Returns the sfdc channel.
//
//   - name: Resource name of the SFDC channel
//     projects/{project}/locations/{location}/sfdcInstances/{sfdc_instance
//     }/sfdcChannels/{sfdc_channel}.
func (r *ProjectsLocationsProductsSfdcInstancesSfdcChannelsService) Patch(name string, googlecloudintegrationsv1alphasfdcchannel *GoogleCloudIntegrationsV1alphaSfdcChannel) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsPatchCall {
	c := &ProjectsLocationsProductsSfdcInstancesSfdcChannelsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphasfdcchannel = googlecloudintegrationsv1alphasfdcchannel
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above SfdcChannel that have been
// modified and need to be updated.
func (c *ProjectsLocationsProductsSfdcInstancesSfdcChannelsPatchCall) UpdateMask(updateMask string) *ProjectsLocationsProductsSfdcInstancesSfdcChannelsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.products.sfdcInstances.sfdcChannels.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcChannel or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcChannel.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 *ProjectsLocationsProductsSfdcInstancesSfdcChannelsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcChannel, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcChannel{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an sfdc channel. Updates the sfdc channel in spanner. Returns the sfdc channel.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/products/{productsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels/{sfdcChannelsId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.products.sfdcInstances.sfdcChannels.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Resource name of the SFDC channel projects/{project}/locations/{location}/sfdcInstances/{sfdc_instance}/sfdcChannels/{sfdc_channel}.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/products/[^/]+/sfdcInstances/[^/]+/sfdcChannels/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above SfdcChannel that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.sfdcInstances.create":

type ProjectsLocationsSfdcInstancesCreateCall struct {
	s                                          *Service
	parent                                     string
	googlecloudintegrationsv1alphasfdcinstance *GoogleCloudIntegrationsV1alphaSfdcInstance
	urlParams_                                 gensupport.URLParams
	ctx_                                       context.Context
	header_                                    http.Header
}

// Create: Creates an sfdc instance record. Store the sfdc instance in
// Spanner. Returns the sfdc instance.
//
// - parent: "projects/{project}/locations/{location}" format.
func (r *ProjectsLocationsSfdcInstancesService) Create(parent string, googlecloudintegrationsv1alphasfdcinstance *GoogleCloudIntegrationsV1alphaSfdcInstance) *ProjectsLocationsSfdcInstancesCreateCall {
	c := &ProjectsLocationsSfdcInstancesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphasfdcinstance = googlecloudintegrationsv1alphasfdcinstance
	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 *ProjectsLocationsSfdcInstancesCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsSfdcInstancesCreateCall {
	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 *ProjectsLocationsSfdcInstancesCreateCall) Context(ctx context.Context) *ProjectsLocationsSfdcInstancesCreateCall {
	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 *ProjectsLocationsSfdcInstancesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsSfdcInstancesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphasfdcinstance)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/sfdcInstances")
	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 "integrations.projects.locations.sfdcInstances.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcInstance or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcInstance.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 *ProjectsLocationsSfdcInstancesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcInstance, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcInstance{
		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 an sfdc instance record. Store the sfdc instance in Spanner. Returns the sfdc instance.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.sfdcInstances.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. \"projects/{project}/locations/{location}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/sfdcInstances",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.sfdcInstances.delete":

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

// Delete: Deletes an sfdc instance.
//
// - name: The name that is associated with the SfdcInstance.
func (r *ProjectsLocationsSfdcInstancesService) Delete(name string) *ProjectsLocationsSfdcInstancesDeleteCall {
	c := &ProjectsLocationsSfdcInstancesDeleteCall{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 *ProjectsLocationsSfdcInstancesDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsSfdcInstancesDeleteCall {
	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 *ProjectsLocationsSfdcInstancesDeleteCall) Context(ctx context.Context) *ProjectsLocationsSfdcInstancesDeleteCall {
	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 *ProjectsLocationsSfdcInstancesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.sfdcInstances.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsSfdcInstancesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an sfdc instance.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances/{sfdcInstancesId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.sfdcInstances.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the SfdcInstance.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.sfdcInstances.get":

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

// Get: Gets an sfdc instance. If the instance doesn't exist,
// Code.NOT_FOUND exception will be thrown.
//
// - name: The name that is associated with the SfdcInstance.
func (r *ProjectsLocationsSfdcInstancesService) Get(name string) *ProjectsLocationsSfdcInstancesGetCall {
	c := &ProjectsLocationsSfdcInstancesGetCall{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 *ProjectsLocationsSfdcInstancesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsSfdcInstancesGetCall {
	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 *ProjectsLocationsSfdcInstancesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsSfdcInstancesGetCall {
	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 *ProjectsLocationsSfdcInstancesGetCall) Context(ctx context.Context) *ProjectsLocationsSfdcInstancesGetCall {
	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 *ProjectsLocationsSfdcInstancesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.sfdcInstances.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcInstance or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcInstance.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 *ProjectsLocationsSfdcInstancesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcInstance, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcInstance{
		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 an sfdc instance. If the instance doesn't exist, Code.NOT_FOUND exception will be thrown.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances/{sfdcInstancesId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.sfdcInstances.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the SfdcInstance.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.sfdcInstances.list":

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

// List: Lists all sfdc instances that match the filter. Restrict to
// sfdc instances belonging to the current client only.
//
// - parent: The client, which owns this collection of SfdcInstances.
func (r *ProjectsLocationsSfdcInstancesService) List(parent string) *ProjectsLocationsSfdcInstancesListCall {
	c := &ProjectsLocationsSfdcInstancesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filtering as supported
// in
// https://developers.google.com/authorized-buyers/apis/guides/list-filters.
func (c *ProjectsLocationsSfdcInstancesListCall) Filter(filter string) *ProjectsLocationsSfdcInstancesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response. If unspecified, defaults to 100.
func (c *ProjectsLocationsSfdcInstancesListCall) PageSize(pageSize int64) *ProjectsLocationsSfdcInstancesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsSfdcInstancesListCall) PageToken(pageToken string) *ProjectsLocationsSfdcInstancesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": The mask which
// specifies fields that need to be returned in the SfdcInstance's
// response.
func (c *ProjectsLocationsSfdcInstancesListCall) ReadMask(readMask string) *ProjectsLocationsSfdcInstancesListCall {
	c.urlParams_.Set("readMask", readMask)
	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 *ProjectsLocationsSfdcInstancesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsSfdcInstancesListCall {
	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 *ProjectsLocationsSfdcInstancesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsSfdcInstancesListCall {
	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 *ProjectsLocationsSfdcInstancesListCall) Context(ctx context.Context) *ProjectsLocationsSfdcInstancesListCall {
	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 *ProjectsLocationsSfdcInstancesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsSfdcInstancesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/sfdcInstances")
	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 "integrations.projects.locations.sfdcInstances.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse.ServerRespons
// e.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 *ProjectsLocationsSfdcInstancesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse{
		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 all sfdc instances that match the filter. Restrict to sfdc instances belonging to the current client only.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.sfdcInstances.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filtering as supported in https://developers.google.com/authorized-buyers/apis/guides/list-filters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The size of entries in the response. If unspecified, defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The client, which owns this collection of SfdcInstances.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "The mask which specifies fields that need to be returned in the SfdcInstance's response.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/sfdcInstances",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse"
	//   },
	//   "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 *ProjectsLocationsSfdcInstancesListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListSfdcInstancesResponse) 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 "integrations.projects.locations.sfdcInstances.patch":

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

// Patch: Updates an sfdc instance. Updates the sfdc instance in
// spanner. Returns the sfdc instance.
//
//   - name: Resource name of the SFDC instance
//     projects/{project}/locations/{location}/sfdcInstances/{sfdcInstance}
//     .
func (r *ProjectsLocationsSfdcInstancesService) Patch(name string, googlecloudintegrationsv1alphasfdcinstance *GoogleCloudIntegrationsV1alphaSfdcInstance) *ProjectsLocationsSfdcInstancesPatchCall {
	c := &ProjectsLocationsSfdcInstancesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphasfdcinstance = googlecloudintegrationsv1alphasfdcinstance
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above SfdcInstance that have been
// modified and need to be updated.
func (c *ProjectsLocationsSfdcInstancesPatchCall) UpdateMask(updateMask string) *ProjectsLocationsSfdcInstancesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.sfdcInstances.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcInstance or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcInstance.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 *ProjectsLocationsSfdcInstancesPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcInstance, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcInstance{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an sfdc instance. Updates the sfdc instance in spanner. Returns the sfdc instance.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances/{sfdcInstancesId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.sfdcInstances.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Resource name of the SFDC instance projects/{project}/locations/{location}/sfdcInstances/{sfdcInstance}.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above SfdcInstance that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcInstance"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.sfdcInstances.sfdcChannels.create":

type ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall struct {
	s                                         *Service
	parent                                    string
	googlecloudintegrationsv1alphasfdcchannel *GoogleCloudIntegrationsV1alphaSfdcChannel
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// Create: Creates an sfdc channel record. Store the sfdc channel in
// Spanner. Returns the sfdc channel.
//
// - parent: "projects/{project}/locations/{location}" format.
func (r *ProjectsLocationsSfdcInstancesSfdcChannelsService) Create(parent string, googlecloudintegrationsv1alphasfdcchannel *GoogleCloudIntegrationsV1alphaSfdcChannel) *ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall {
	c := &ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudintegrationsv1alphasfdcchannel = googlecloudintegrationsv1alphasfdcchannel
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall) Context(ctx context.Context) *ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.googlecloudintegrationsv1alphasfdcchannel)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/sfdcChannels")
	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 "integrations.projects.locations.sfdcInstances.sfdcChannels.create" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcChannel or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcChannel.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 *ProjectsLocationsSfdcInstancesSfdcChannelsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcChannel, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcChannel{
		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 an sfdc channel record. Store the sfdc channel in Spanner. Returns the sfdc channel.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels",
	//   "httpMethod": "POST",
	//   "id": "integrations.projects.locations.sfdcInstances.sfdcChannels.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. \"projects/{project}/locations/{location}\" format.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/sfdcChannels",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.sfdcInstances.sfdcChannels.delete":

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

// Delete: Deletes an sfdc channel.
//
// - name: The name that is associated with the SfdcChannel.
func (r *ProjectsLocationsSfdcInstancesSfdcChannelsService) Delete(name string) *ProjectsLocationsSfdcInstancesSfdcChannelsDeleteCall {
	c := &ProjectsLocationsSfdcInstancesSfdcChannelsDeleteCall{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 *ProjectsLocationsSfdcInstancesSfdcChannelsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsSfdcInstancesSfdcChannelsDeleteCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsDeleteCall) Context(ctx context.Context) *ProjectsLocationsSfdcInstancesSfdcChannelsDeleteCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.sfdcInstances.sfdcChannels.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsSfdcInstancesSfdcChannelsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an sfdc channel.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels/{sfdcChannelsId}",
	//   "httpMethod": "DELETE",
	//   "id": "integrations.projects.locations.sfdcInstances.sfdcChannels.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the SfdcChannel.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/sfdcInstances/[^/]+/sfdcChannels/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.sfdcInstances.sfdcChannels.get":

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

// Get: Gets an sfdc channel. If the channel doesn't exist,
// Code.NOT_FOUND exception will be thrown.
//
// - name: The name that is associated with the SfdcChannel.
func (r *ProjectsLocationsSfdcInstancesSfdcChannelsService) Get(name string) *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall {
	c := &ProjectsLocationsSfdcInstancesSfdcChannelsGetCall{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 *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall) Context(ctx context.Context) *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "integrations.projects.locations.sfdcInstances.sfdcChannels.get" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcChannel or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcChannel.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 *ProjectsLocationsSfdcInstancesSfdcChannelsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcChannel, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcChannel{
		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 an sfdc channel. If the channel doesn't exist, Code.NOT_FOUND exception will be thrown.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels/{sfdcChannelsId}",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.sfdcInstances.sfdcChannels.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name that is associated with the SfdcChannel.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/sfdcInstances/[^/]+/sfdcChannels/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "integrations.projects.locations.sfdcInstances.sfdcChannels.list":

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

// List: Lists all sfdc channels that match the filter. Restrict to sfdc
// channels belonging to the current client only.
//
// - parent: The client, which owns this collection of SfdcChannels.
func (r *ProjectsLocationsSfdcInstancesSfdcChannelsService) List(parent string) *ProjectsLocationsSfdcInstancesSfdcChannelsListCall {
	c := &ProjectsLocationsSfdcInstancesSfdcChannelsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filtering as supported
// in
// https://developers.google.com/authorized-buyers/apis/guides/list-filters.
func (c *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) Filter(filter string) *ProjectsLocationsSfdcInstancesSfdcChannelsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The size of entries
// in the response. If unspecified, defaults to 100.
func (c *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) PageSize(pageSize int64) *ProjectsLocationsSfdcInstancesSfdcChannelsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The token returned
// in the previous response.
func (c *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) PageToken(pageToken string) *ProjectsLocationsSfdcInstancesSfdcChannelsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": The mask which
// specifies fields that need to be returned in the SfdcChannel's
// response.
func (c *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) ReadMask(readMask string) *ProjectsLocationsSfdcInstancesSfdcChannelsListCall {
	c.urlParams_.Set("readMask", readMask)
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsSfdcInstancesSfdcChannelsListCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsSfdcInstancesSfdcChannelsListCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) Context(ctx context.Context) *ProjectsLocationsSfdcInstancesSfdcChannelsListCall {
	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 *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1alpha/{+parent}/sfdcChannels")
	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 "integrations.projects.locations.sfdcInstances.sfdcChannels.list" call.
// Exactly one of
// *GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse.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 *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse{
		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 all sfdc channels that match the filter. Restrict to sfdc channels belonging to the current client only.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels",
	//   "httpMethod": "GET",
	//   "id": "integrations.projects.locations.sfdcInstances.sfdcChannels.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Filtering as supported in https://developers.google.com/authorized-buyers/apis/guides/list-filters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The size of entries in the response. If unspecified, defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The token returned in the previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The client, which owns this collection of SfdcChannels.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/sfdcInstances/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "The mask which specifies fields that need to be returned in the SfdcChannel's response.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+parent}/sfdcChannels",
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse"
	//   },
	//   "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 *ProjectsLocationsSfdcInstancesSfdcChannelsListCall) Pages(ctx context.Context, f func(*GoogleCloudIntegrationsV1alphaListSfdcChannelsResponse) 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 "integrations.projects.locations.sfdcInstances.sfdcChannels.patch":

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

// Patch: Updates an sfdc channel. Updates the sfdc channel in spanner.
// Returns the sfdc channel.
//
//   - name: Resource name of the SFDC channel
//     projects/{project}/locations/{location}/sfdcInstances/{sfdc_instance
//     }/sfdcChannels/{sfdc_channel}.
func (r *ProjectsLocationsSfdcInstancesSfdcChannelsService) Patch(name string, googlecloudintegrationsv1alphasfdcchannel *GoogleCloudIntegrationsV1alphaSfdcChannel) *ProjectsLocationsSfdcInstancesSfdcChannelsPatchCall {
	c := &ProjectsLocationsSfdcInstancesSfdcChannelsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudintegrationsv1alphasfdcchannel = googlecloudintegrationsv1alphasfdcchannel
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask
// specifying the fields in the above SfdcChannel that have been
// modified and need to be updated.
func (c *ProjectsLocationsSfdcInstancesSfdcChannelsPatchCall) UpdateMask(updateMask string) *ProjectsLocationsSfdcInstancesSfdcChannelsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

// Do executes the "integrations.projects.locations.sfdcInstances.sfdcChannels.patch" call.
// Exactly one of *GoogleCloudIntegrationsV1alphaSfdcChannel or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudIntegrationsV1alphaSfdcChannel.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 *ProjectsLocationsSfdcInstancesSfdcChannelsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudIntegrationsV1alphaSfdcChannel, 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, gensupport.WrapError(&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, gensupport.WrapError(err)
	}
	ret := &GoogleCloudIntegrationsV1alphaSfdcChannel{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an sfdc channel. Updates the sfdc channel in spanner. Returns the sfdc channel.",
	//   "flatPath": "v1alpha/projects/{projectsId}/locations/{locationsId}/sfdcInstances/{sfdcInstancesId}/sfdcChannels/{sfdcChannelsId}",
	//   "httpMethod": "PATCH",
	//   "id": "integrations.projects.locations.sfdcInstances.sfdcChannels.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Resource name of the SFDC channel projects/{project}/locations/{location}/sfdcInstances/{sfdc_instance}/sfdcChannels/{sfdc_channel}.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/sfdcInstances/[^/]+/sfdcChannels/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask specifying the fields in the above SfdcChannel that have been modified and need to be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudIntegrationsV1alphaSfdcChannel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
