// Copyright 2026 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 datamigration provides access to the Database Migration API.
//
// For product documentation, see: https://cloud.google.com/database-migration/
//
// # Library status
//
// These client libraries are officially supported by Google. However, this
// library is considered complete and is in maintenance mode. This means
// that we will address critical bugs and security issues but will not add
// any new features.
//
// When possible, we recommend using our newer
// [Cloud Client Libraries for Go](https://pkg.go.dev/cloud.google.com/go)
// that are still actively being worked and iterated on.
//
// # Creating a client
//
// Usage example:
//
//	import "google.golang.org/api/datamigration/v1"
//	...
//	ctx := context.Background()
//	datamigrationService, err := datamigration.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 [google.golang.org/api/option.WithAPIKey]:
//
//	datamigrationService, err := datamigration.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth
// flow, use [google.golang.org/api/option.WithTokenSource]:
//
//	config := &oauth2.Config{...}
//	// ...
//	token, err := config.Exchange(ctx, ...)
//	datamigrationService, err := datamigration.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See [google.golang.org/api/option.ClientOption] for details on options.
package datamigration // import "google.golang.org/api/datamigration/v1"

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

	"github.com/googleapis/gax-go/v2/internallog"
	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
var _ = internallog.New

const apiId = "datamigration:v1"
const apiName = "datamigration"
const apiVersion = "v1"
const basePath = "https://datamigration.googleapis.com/"
const basePathTemplate = "https://datamigration.UNIVERSE_DOMAIN/"
const mtlsBasePath = "https://datamigration.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.WithDefaultEndpointTemplate(basePathTemplate))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	opts = append(opts, internaloption.EnableNewAuthLibrary())
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s := &Service{client: client, BasePath: basePath, logger: internaloption.GetLogger(opts)}
	s.Projects = NewProjectsService(s)
	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")
	}
	return NewService(context.TODO(), option.WithHTTPClient(client))
}

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

	Projects *ProjectsService
}

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

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.ConnectionProfiles = NewProjectsLocationsConnectionProfilesService(s)
	rs.ConversionWorkspaces = NewProjectsLocationsConversionWorkspacesService(s)
	rs.MigrationJobs = NewProjectsLocationsMigrationJobsService(s)
	rs.Operations = NewProjectsLocationsOperationsService(s)
	rs.PrivateConnections = NewProjectsLocationsPrivateConnectionsService(s)
	return rs
}

type ProjectsLocationsService struct {
	s *Service

	ConnectionProfiles *ProjectsLocationsConnectionProfilesService

	ConversionWorkspaces *ProjectsLocationsConversionWorkspacesService

	MigrationJobs *ProjectsLocationsMigrationJobsService

	Operations *ProjectsLocationsOperationsService

	PrivateConnections *ProjectsLocationsPrivateConnectionsService
}

func NewProjectsLocationsConnectionProfilesService(s *Service) *ProjectsLocationsConnectionProfilesService {
	rs := &ProjectsLocationsConnectionProfilesService{s: s}
	return rs
}

type ProjectsLocationsConnectionProfilesService struct {
	s *Service
}

func NewProjectsLocationsConversionWorkspacesService(s *Service) *ProjectsLocationsConversionWorkspacesService {
	rs := &ProjectsLocationsConversionWorkspacesService{s: s}
	rs.MappingRules = NewProjectsLocationsConversionWorkspacesMappingRulesService(s)
	return rs
}

type ProjectsLocationsConversionWorkspacesService struct {
	s *Service

	MappingRules *ProjectsLocationsConversionWorkspacesMappingRulesService
}

func NewProjectsLocationsConversionWorkspacesMappingRulesService(s *Service) *ProjectsLocationsConversionWorkspacesMappingRulesService {
	rs := &ProjectsLocationsConversionWorkspacesMappingRulesService{s: s}
	return rs
}

type ProjectsLocationsConversionWorkspacesMappingRulesService struct {
	s *Service
}

func NewProjectsLocationsMigrationJobsService(s *Service) *ProjectsLocationsMigrationJobsService {
	rs := &ProjectsLocationsMigrationJobsService{s: s}
	rs.Objects = NewProjectsLocationsMigrationJobsObjectsService(s)
	return rs
}

type ProjectsLocationsMigrationJobsService struct {
	s *Service

	Objects *ProjectsLocationsMigrationJobsObjectsService
}

func NewProjectsLocationsMigrationJobsObjectsService(s *Service) *ProjectsLocationsMigrationJobsObjectsService {
	rs := &ProjectsLocationsMigrationJobsObjectsService{s: s}
	return rs
}

type ProjectsLocationsMigrationJobsObjectsService struct {
	s *Service
}

func NewProjectsLocationsOperationsService(s *Service) *ProjectsLocationsOperationsService {
	rs := &ProjectsLocationsOperationsService{s: s}
	return rs
}

type ProjectsLocationsOperationsService struct {
	s *Service
}

func NewProjectsLocationsPrivateConnectionsService(s *Service) *ProjectsLocationsPrivateConnectionsService {
	rs := &ProjectsLocationsPrivateConnectionsService{s: s}
	return rs
}

type ProjectsLocationsPrivateConnectionsService struct {
	s *Service
}

// AlloyDbConnectionProfile: Specifies required connection parameters, and the
// parameters required to create an AlloyDB destination cluster.
type AlloyDbConnectionProfile struct {
	// ClusterId: Required. The AlloyDB cluster ID that this connection profile is
	// associated with.
	ClusterId string `json:"clusterId,omitempty"`
	// Settings: Immutable. Metadata used to create the destination AlloyDB
	// cluster.
	Settings *AlloyDbSettings `json:"settings,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ClusterId") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ClusterId") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s AlloyDbConnectionProfile) MarshalJSON() ([]byte, error) {
	type NoMethod AlloyDbConnectionProfile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// AlloyDbSettings: Settings for creating an AlloyDB cluster.
type AlloyDbSettings struct {
	// DatabaseVersion: Optional. The database engine major version. This is an
	// optional field. If a database version is not supplied at cluster creation
	// time, then a default database version will be used.
	//
	// Possible values:
	//   "DATABASE_VERSION_UNSPECIFIED" - This is an unknown database version.
	//   "POSTGRES_14" - The database version is Postgres 14.
	//   "POSTGRES_15" - The database version is Postgres 15.
	//   "POSTGRES_16" - The database version is Postgres 16.
	//   "POSTGRES_17" - The database version is Postgres 17.
	//   "POSTGRES_18" - The database version is Postgres 18.
	DatabaseVersion string `json:"databaseVersion,omitempty"`
	// EncryptionConfig: Optional. The encryption config can be specified to
	// encrypt the data disks and other persistent data resources of a cluster with
	// a customer-managed encryption key (CMEK). When this field is not specified,
	// the cluster will then use default encryption scheme to protect the user
	// data.
	EncryptionConfig *EncryptionConfig `json:"encryptionConfig,omitempty"`
	// InitialUser: Required. Input only. Initial user to setup during cluster
	// creation. Required.
	InitialUser *UserPassword `json:"initialUser,omitempty"`
	// Labels: Labels for the AlloyDB cluster created by DMS. An object containing
	// a list of 'key', 'value' pairs.
	Labels map[string]string `json:"labels,omitempty"`
	// PrimaryInstanceSettings: Settings for the cluster's primary instance
	PrimaryInstanceSettings *PrimaryInstanceSettings `json:"primaryInstanceSettings,omitempty"`
	// VpcNetwork: Required. The resource link for the VPC network in which cluster
	// resources are created and from which they are accessible via Private IP. The
	// network must belong to the same project as the cluster. It is specified in
	// the form: "projects/{project_number}/global/networks/{network_id}". This is
	// required to create a cluster.
	VpcNetwork string `json:"vpcNetwork,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DatabaseVersion") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DatabaseVersion") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s AlloyDbSettings) MarshalJSON() ([]byte, error) {
	type NoMethod AlloyDbSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ApplyConversionWorkspaceRequest: Request message for
// 'ApplyConversionWorkspace' request.
type ApplyConversionWorkspaceRequest struct {
	// AutoCommit: Optional. Specifies whether the conversion workspace is to be
	// committed automatically after the apply.
	AutoCommit bool `json:"autoCommit,omitempty"`
	// ConnectionProfile: Optional. Fully qualified (Uri) name of the destination
	// connection profile.
	ConnectionProfile string `json:"connectionProfile,omitempty"`
	// DryRun: Optional. Only validates the apply process, but doesn't change the
	// destination database. Only works for PostgreSQL destination connection
	// profile.
	DryRun bool `json:"dryRun,omitempty"`
	// Filter: Optional. Filter which entities to apply. Leaving this field empty
	// will apply all of the entities. Supports Google AIP 160 based filtering.
	Filter string `json:"filter,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AutoCommit") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AutoCommit") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ApplyConversionWorkspaceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ApplyConversionWorkspaceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ApplyHash: Apply a hash function on the value.
type ApplyHash struct {
	// UuidFromBytes: Optional. Generate UUID from the data's byte array
	UuidFromBytes *Empty `json:"uuidFromBytes,omitempty"`
	// ForceSendFields is a list of field names (e.g. "UuidFromBytes") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "UuidFromBytes") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ApplyHash) MarshalJSON() ([]byte, error) {
	type NoMethod ApplyHash
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ApplyJobDetails: Details regarding an Apply background job.
type ApplyJobDetails struct {
	// ConnectionProfile: Output only. The connection profile which was used for
	// the apply job.
	ConnectionProfile string `json:"connectionProfile,omitempty"`
	// Filter: Output only. AIP-160 based filter used to specify the entities to
	// apply
	Filter string `json:"filter,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ConnectionProfile") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ConnectionProfile") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ApplyJobDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ApplyJobDetails
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// AssignSpecificValue: Set to a specific value (value is converted to fit the
// target data type)
type AssignSpecificValue struct {
	// Value: Required. Specific value to be assigned
	Value string `json:"value,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Value") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Value") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s AssignSpecificValue) MarshalJSON() ([]byte, error) {
	type NoMethod AssignSpecificValue
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// AuditConfig: Specifies the audit configuration for a service. The
// configuration determines which permission types are logged, and what
// identities, if any, are exempted from logging. An AuditConfig must have one
// or more AuditLogConfigs. If there are AuditConfigs for both `allServices`
// and a specific service, the union of the two AuditConfigs is used for that
// service: the log_types specified in each AuditConfig are enabled, and the
// exempted_members in each AuditLogConfig are exempted. Example Policy with
// multiple AuditConfigs: { "audit_configs": [ { "service": "allServices",
// "audit_log_configs": [ { "log_type": "DATA_READ", "exempted_members": [
// "user:jose@example.com" ] }, { "log_type": "DATA_WRITE" }, { "log_type":
// "ADMIN_READ" } ] }, { "service": "sampleservice.googleapis.com",
// "audit_log_configs": [ { "log_type": "DATA_READ" }, { "log_type":
// "DATA_WRITE", "exempted_members": [ "user:aliya@example.com" ] } ] } ] } For
// sampleservice, this policy enables DATA_READ, DATA_WRITE and ADMIN_READ
// logging. It also exempts `jose@example.com` from DATA_READ logging, and
// `aliya@example.com` from DATA_WRITE logging.
type AuditConfig struct {
	// AuditLogConfigs: The configuration for logging of each type of permission.
	AuditLogConfigs []*AuditLogConfig `json:"auditLogConfigs,omitempty"`
	// Service: Specifies a service that will be enabled for audit logging. For
	// example, `storage.googleapis.com`, `cloudsql.googleapis.com`. `allServices`
	// is a special value that covers all services.
	Service string `json:"service,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AuditLogConfigs") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AuditLogConfigs") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

// AuditLogConfig: Provides the configuration for logging a type of
// permissions. Example: { "audit_log_configs": [ { "log_type": "DATA_READ",
// "exempted_members": [ "user:jose@example.com" ] }, { "log_type":
// "DATA_WRITE" } ] } This enables 'DATA_READ' and 'DATA_WRITE' logging, while
// exempting jose@example.com from DATA_READ logging.
type AuditLogConfig struct {
	// ExemptedMembers: Specifies the identities that do not cause logging for this
	// type of permission. Follows the same format of Binding.members.
	ExemptedMembers []string `json:"exemptedMembers,omitempty"`
	// LogType: The log type that this config enables.
	//
	// Possible values:
	//   "LOG_TYPE_UNSPECIFIED" - Default case. Should never be this.
	//   "ADMIN_READ" - Admin reads. Example: CloudIAM getIamPolicy
	//   "DATA_WRITE" - Data writes. Example: CloudSQL Users create
	//   "DATA_READ" - Data reads. Example: CloudSQL Users list
	LogType string `json:"logType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ExemptedMembers") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ExemptedMembers") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

// AuthorizedNetwork: AuthorizedNetwork contains metadata for an authorized
// network.
type AuthorizedNetwork struct {
	// CidrRange: Optional. CIDR range for one authorzied network of the instance.
	CidrRange string `json:"cidrRange,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CidrRange") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CidrRange") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s AuthorizedNetwork) MarshalJSON() ([]byte, error) {
	type NoMethod AuthorizedNetwork
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BackgroundJobLogEntry: Execution log of a background job.
type BackgroundJobLogEntry struct {
	// ApplyJobDetails: Output only. Apply job details.
	ApplyJobDetails *ApplyJobDetails `json:"applyJobDetails,omitempty"`
	// CompletionComment: Output only. Job completion comment, such as how many
	// entities were seeded, how many warnings were found during conversion, and
	// similar information.
	CompletionComment string `json:"completionComment,omitempty"`
	// CompletionState: Output only. Job completion state, i.e. the final state
	// after the job completed.
	//
	// Possible values:
	//   "JOB_COMPLETION_STATE_UNSPECIFIED" - The status is not specified. This
	// state is used when job is not yet finished.
	//   "SUCCEEDED" - Success.
	//   "FAILED" - Error.
	CompletionState string `json:"completionState,omitempty"`
	// ConvertJobDetails: Output only. Convert job details.
	ConvertJobDetails *ConvertJobDetails `json:"convertJobDetails,omitempty"`
	// FinishTime: The timestamp when the background job was finished.
	FinishTime string `json:"finishTime,omitempty"`
	// Id: The background job log entry ID.
	Id string `json:"id,omitempty"`
	// ImportRulesJobDetails: Output only. Import rules job details.
	ImportRulesJobDetails *ImportRulesJobDetails `json:"importRulesJobDetails,omitempty"`
	// JobType: The type of job that was executed.
	//
	// Possible values:
	//   "BACKGROUND_JOB_TYPE_UNSPECIFIED" - Unspecified background job type.
	//   "BACKGROUND_JOB_TYPE_SOURCE_SEED" - Job to seed from the source database.
	//   "BACKGROUND_JOB_TYPE_CONVERT" - Job to convert the source database into a
	// draft of the destination database.
	//   "BACKGROUND_JOB_TYPE_APPLY_DESTINATION" - Job to apply the draft tree onto
	// the destination.
	//   "BACKGROUND_JOB_TYPE_IMPORT_RULES_FILE" - Job to import and convert
	// mapping rules from an external source such as an ora2pg config file.
	JobType string `json:"jobType,omitempty"`
	// RequestAutocommit: Output only. Whether the client requested the conversion
	// workspace to be committed after a successful completion of the job.
	RequestAutocommit bool `json:"requestAutocommit,omitempty"`
	// SeedJobDetails: Output only. Seed job details.
	SeedJobDetails *SeedJobDetails `json:"seedJobDetails,omitempty"`
	// StartTime: The timestamp when the background job was started.
	StartTime string `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ApplyJobDetails") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ApplyJobDetails") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BackgroundJobLogEntry) MarshalJSON() ([]byte, error) {
	type NoMethod BackgroundJobLogEntry
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BadRequest: Describes violations in a client request. This error type
// focuses on the syntactic aspects of the request.
type BadRequest struct {
	// FieldViolations: Describes all violations in a client request.
	FieldViolations []*FieldViolation `json:"fieldViolations,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FieldViolations") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "FieldViolations") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BadRequest) MarshalJSON() ([]byte, error) {
	type NoMethod BadRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BinaryLogParser: Configuration to use Binary Log Parser CDC technique.
type BinaryLogParser struct {
	// LogFileDirectories: Use Oracle directories.
	LogFileDirectories *LogFileDirectories `json:"logFileDirectories,omitempty"`
	// OracleAsmLogFileAccess: Use Oracle ASM.
	OracleAsmLogFileAccess *OracleAsmLogFileAccess `json:"oracleAsmLogFileAccess,omitempty"`
	// ForceSendFields is a list of field names (e.g. "LogFileDirectories") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "LogFileDirectories") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BinaryLogParser) MarshalJSON() ([]byte, error) {
	type NoMethod BinaryLogParser
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Binding: Associates `members`, or principals, with a `role`.
type Binding struct {
	// Condition: The condition that is associated with this binding. If the
	// condition evaluates to `true`, then this binding applies to the current
	// request. If the condition evaluates to `false`, then this binding does not
	// apply to the current request. However, a different role binding might grant
	// the same role to one or more of the principals in this binding. To learn
	// which resources support conditions in their IAM policies, see the IAM
	// documentation
	// (https://cloud.google.com/iam/help/conditions/resource-policies).
	Condition *Expr `json:"condition,omitempty"`
	// Members: Specifies the principals requesting access for a Google Cloud
	// resource. `members` can have the following values: * `allUsers`: A special
	// identifier that represents anyone who is on the internet; with or without a
	// Google account. * `allAuthenticatedUsers`: A special identifier that
	// represents anyone who is authenticated with a Google account or a service
	// account. Does not include identities that come from external identity
	// providers (IdPs) through identity federation. * `user:{emailid}`: An email
	// address that represents a specific Google account. For example,
	// `alice@example.com` . * `serviceAccount:{emailid}`: An email address that
	// represents a Google service account. For example,
	// `my-other-app@appspot.gserviceaccount.com`. *
	// `serviceAccount:{projectid}.svc.id.goog[{namespace}/{kubernetes-sa}]`: An
	// identifier for a Kubernetes service account
	// (https://cloud.google.com/kubernetes-engine/docs/how-to/kubernetes-service-accounts).
	// For example, `my-project.svc.id.goog[my-namespace/my-kubernetes-sa]`. *
	// `group:{emailid}`: An email address that represents a Google group. For
	// example, `admins@example.com`. * `domain:{domain}`: The G Suite domain
	// (primary) that represents all the users of that domain. For example,
	// `google.com` or `example.com`. *
	// `principal://iam.googleapis.com/locations/global/workforcePools/{pool_id}/sub
	// ject/{subject_attribute_value}`: A single identity in a workforce identity
	// pool. *
	// `principalSet://iam.googleapis.com/locations/global/workforcePools/{pool_id}/
	// group/{group_id}`: All workforce identities in a group. *
	// `principalSet://iam.googleapis.com/locations/global/workforcePools/{pool_id}/
	// attribute.{attribute_name}/{attribute_value}`: All workforce identities with
	// a specific attribute value. *
	// `principalSet://iam.googleapis.com/locations/global/workforcePools/{pool_id}/
	// *`: All identities in a workforce identity pool. *
	// `principal://iam.googleapis.com/projects/{project_number}/locations/global/wo
	// rkloadIdentityPools/{pool_id}/subject/{subject_attribute_value}`: A single
	// identity in a workload identity pool. *
	// `principalSet://iam.googleapis.com/projects/{project_number}/locations/global
	// /workloadIdentityPools/{pool_id}/group/{group_id}`: A workload identity pool
	// group. *
	// `principalSet://iam.googleapis.com/projects/{project_number}/locations/global
	// /workloadIdentityPools/{pool_id}/attribute.{attribute_name}/{attribute_value}
	// `: All identities in a workload identity pool with a certain attribute. *
	// `principalSet://iam.googleapis.com/projects/{project_number}/locations/global
	// /workloadIdentityPools/{pool_id}/*`: All identities in a workload identity
	// pool. * `deleted:user:{emailid}?uid={uniqueid}`: An email address (plus
	// unique identifier) representing a user that has been recently deleted. For
	// example, `alice@example.com?uid=123456789012345678901`. If the user is
	// recovered, this value reverts to `user:{emailid}` and the recovered user
	// retains the role in the binding. *
	// `deleted:serviceAccount:{emailid}?uid={uniqueid}`: An email address (plus
	// unique identifier) representing a service account that has been recently
	// deleted. For example,
	// `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. If the
	// service account is undeleted, this value reverts to
	// `serviceAccount:{emailid}` and the undeleted service account retains the
	// role in the binding. * `deleted:group:{emailid}?uid={uniqueid}`: An email
	// address (plus unique identifier) representing a Google group that has been
	// recently deleted. For example,
	// `admins@example.com?uid=123456789012345678901`. If the group is recovered,
	// this value reverts to `group:{emailid}` and the recovered group retains the
	// role in the binding. *
	// `deleted:principal://iam.googleapis.com/locations/global/workforcePools/{pool
	// _id}/subject/{subject_attribute_value}`: Deleted single identity in a
	// workforce identity pool. For example,
	// `deleted:principal://iam.googleapis.com/locations/global/workforcePools/my-po
	// ol-id/subject/my-subject-attribute-value`.
	Members []string `json:"members,omitempty"`
	// Role: Role that is assigned to the list of `members`, or principals. For
	// example, `roles/viewer`, `roles/editor`, or `roles/owner`. For an overview
	// of the IAM roles and permissions, see the IAM documentation
	// (https://cloud.google.com/iam/docs/roles-overview). For a list of the
	// available pre-defined roles, see here
	// (https://cloud.google.com/iam/docs/understanding-roles).
	Role string `json:"role,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Condition") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

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

// CloudSqlConnectionProfile: Specifies required connection parameters, and,
// optionally, the parameters required to create a Cloud SQL destination
// database instance.
type CloudSqlConnectionProfile struct {
	// AdditionalPublicIp: Output only. The Cloud SQL database instance's
	// additional (outgoing) public IP. Used when the Cloud SQL database
	// availability type is REGIONAL (i.e. multiple zones / highly available).
	AdditionalPublicIp string `json:"additionalPublicIp,omitempty"`
	// CloudSqlId: Output only. The Cloud SQL instance ID that this connection
	// profile is associated with.
	CloudSqlId string `json:"cloudSqlId,omitempty"`
	// PrivateIp: Output only. The Cloud SQL database instance's private IP.
	PrivateIp string `json:"privateIp,omitempty"`
	// PublicIp: Output only. The Cloud SQL database instance's public IP.
	PublicIp string `json:"publicIp,omitempty"`
	// Settings: Immutable. Metadata used to create the destination Cloud SQL
	// database.
	Settings *CloudSqlSettings `json:"settings,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AdditionalPublicIp") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AdditionalPublicIp") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s CloudSqlConnectionProfile) MarshalJSON() ([]byte, error) {
	type NoMethod CloudSqlConnectionProfile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// CloudSqlSettings: Settings for creating a Cloud SQL database instance.
type CloudSqlSettings struct {
	// ActivationPolicy: The activation policy specifies when the instance is
	// activated; it is applicable only when the instance state is 'RUNNABLE'.
	// Valid values: 'ALWAYS': The instance is on, and remains so even in the
	// absence of connection requests. `NEVER`: The instance is off; it is not
	// activated, even if a connection request arrives.
	//
	// Possible values:
	//   "SQL_ACTIVATION_POLICY_UNSPECIFIED" - unspecified policy.
	//   "ALWAYS" - The instance is always up and running.
	//   "NEVER" - The instance should never spin up.
	ActivationPolicy string `json:"activationPolicy,omitempty"`
	// AutoStorageIncrease: [default: ON] If you enable this setting, Cloud SQL
	// checks your available storage every 30 seconds. If the available storage
	// falls below a threshold size, Cloud SQL automatically adds additional
	// storage capacity. If the available storage repeatedly falls below the
	// threshold size, Cloud SQL continues to add storage until it reaches the
	// maximum of 30 TB.
	AutoStorageIncrease bool `json:"autoStorageIncrease,omitempty"`
	// AvailabilityType: Optional. Availability type. Potential values: * `ZONAL`:
	// The instance serves data from only one zone. Outages in that zone affect
	// data availability. * `REGIONAL`: The instance can serve data from more than
	// one zone in a region (it is highly available).
	//
	// Possible values:
	//   "SQL_AVAILABILITY_TYPE_UNSPECIFIED" - This is an unknown Availability
	// type.
	//   "ZONAL" - Zonal availablility instance.
	//   "REGIONAL" - Regional availability instance.
	AvailabilityType string `json:"availabilityType,omitempty"`
	// CmekKeyName: The KMS key name used for the csql instance.
	CmekKeyName string `json:"cmekKeyName,omitempty"`
	// Collation: The Cloud SQL default instance level collation.
	Collation string `json:"collation,omitempty"`
	// DataCacheConfig: Optional. Data cache is an optional feature available for
	// Cloud SQL for MySQL Enterprise Plus edition only. For more information on
	// data cache, see Data cache overview
	// (https://cloud.google.com/sql/help/mysql-data-cache) in Cloud SQL
	// documentation.
	DataCacheConfig *DataCacheConfig `json:"dataCacheConfig,omitempty"`
	// DataDiskProvisionedIops: Optional. Provisioned number of I/O operations per
	// second for the data disk. This field is only used for hyperdisk-balanced
	// disk types.
	DataDiskProvisionedIops int64 `json:"dataDiskProvisionedIops,omitempty,string"`
	// DataDiskProvisionedThroughput: Optional. Provisioned throughput measured in
	// MiB per second for the data disk. This field is only used for
	// hyperdisk-balanced disk types.
	DataDiskProvisionedThroughput int64 `json:"dataDiskProvisionedThroughput,omitempty,string"`
	// DataDiskSizeGb: The storage capacity available to the database, in GB. The
	// minimum (and default) size is 10GB.
	DataDiskSizeGb int64 `json:"dataDiskSizeGb,omitempty,string"`
	// DataDiskType: The type of storage: `PD_SSD` (default) or `PD_HDD` or
	// `HYPERDISK_BALANCED`.
	//
	// Possible values:
	//   "SQL_DATA_DISK_TYPE_UNSPECIFIED" - Unspecified.
	//   "PD_SSD" - SSD disk.
	//   "PD_HDD" - HDD disk.
	//   "HYPERDISK_BALANCED" - A Hyperdisk Balanced data disk.
	DataDiskType string `json:"dataDiskType,omitempty"`
	// DatabaseFlags: The database flags passed to the Cloud SQL instance at
	// startup. An object containing a list of "key": value pairs. Example: {
	// "name": "wrench", "mass": "1.3kg", "count": "3" }.
	DatabaseFlags map[string]string `json:"databaseFlags,omitempty"`
	// DatabaseVersion: The database engine type and version. Deprecated. Use
	// database_version_name instead.
	//
	// Possible values:
	//   "SQL_DATABASE_VERSION_UNSPECIFIED" - Unspecified version.
	//   "MYSQL_5_6" - MySQL 5.6.
	//   "MYSQL_5_7" - MySQL 5.7.
	//   "MYSQL_8_0" - MySQL 8.0.
	//   "MYSQL_8_0_18" - The database major version is MySQL 8.0 and the minor
	// version is 18.
	//   "MYSQL_8_0_26" - The database major version is MySQL 8.0 and the minor
	// version is 26.
	//   "MYSQL_8_0_27" - The database major version is MySQL 8.0 and the minor
	// version is 27.
	//   "MYSQL_8_0_28" - The database major version is MySQL 8.0 and the minor
	// version is 28.
	//   "MYSQL_8_0_30" - The database major version is MySQL 8.0 and the minor
	// version is 30.
	//   "MYSQL_8_0_31" - The database major version is MySQL 8.0 and the minor
	// version is 31.
	//   "MYSQL_8_0_32" - The database major version is MySQL 8.0 and the minor
	// version is 32.
	//   "MYSQL_8_0_33" - The database major version is MySQL 8.0 and the minor
	// version is 33.
	//   "MYSQL_8_0_34" - The database major version is MySQL 8.0 and the minor
	// version is 34.
	//   "MYSQL_8_0_35" - The database major version is MySQL 8.0 and the minor
	// version is 35.
	//   "MYSQL_8_0_36" - The database major version is MySQL 8.0 and the minor
	// version is 36.
	//   "MYSQL_8_0_37" - The database major version is MySQL 8.0 and the minor
	// version is 37.
	//   "MYSQL_8_4" - MySQL 8.4.
	//   "POSTGRES_9_6" - PostgreSQL 9.6.
	//   "POSTGRES_11" - PostgreSQL 11.
	//   "POSTGRES_10" - PostgreSQL 10.
	//   "POSTGRES_12" - PostgreSQL 12.
	//   "POSTGRES_13" - PostgreSQL 13.
	//   "POSTGRES_14" - PostgreSQL 14.
	//   "POSTGRES_15" - PostgreSQL 15.
	//   "POSTGRES_16" - PostgreSQL 16.
	DatabaseVersion string `json:"databaseVersion,omitempty"`
	// DatabaseVersionName: Optional. The database engine type and version name.
	DatabaseVersionName string `json:"databaseVersionName,omitempty"`
	// Edition: Optional. The edition of the given Cloud SQL instance.
	//
	// Possible values:
	//   "EDITION_UNSPECIFIED" - The instance did not specify the edition.
	//   "ENTERPRISE" - The instance is an enterprise edition.
	//   "ENTERPRISE_PLUS" - The instance is an enterprise plus edition.
	Edition string `json:"edition,omitempty"`
	// IpConfig: The settings for IP Management. This allows to enable or disable
	// the instance IP and manage which external networks can connect to the
	// instance. The IPv4 address cannot be disabled.
	IpConfig *SqlIpConfig `json:"ipConfig,omitempty"`
	// RootPassword: Input only. Initial root password.
	RootPassword string `json:"rootPassword,omitempty"`
	// RootPasswordSet: Output only. Indicates If this connection profile root
	// password is stored.
	RootPasswordSet bool `json:"rootPasswordSet,omitempty"`
	// SecondaryZone: Optional. The Google Cloud Platform zone where the failover
	// Cloud SQL database instance is located. Used when the Cloud SQL database
	// availability type is REGIONAL (i.e. multiple zones / highly available).
	SecondaryZone string `json:"secondaryZone,omitempty"`
	// SourceId: The Database Migration Service source connection profile ID, in
	// the format:
	// `projects/my_project_name/locations/us-central1/connectionProfiles/connection
	// _profile_ID`
	SourceId string `json:"sourceId,omitempty"`
	// StorageAutoResizeLimit: The maximum size to which storage capacity can be
	// automatically increased. The default value is 0, which specifies that there
	// is no limit.
	StorageAutoResizeLimit int64 `json:"storageAutoResizeLimit,omitempty,string"`
	// Tier: The tier (or machine type) for this instance, for example:
	// `db-n1-standard-1` (MySQL instances) or `db-custom-1-3840` (PostgreSQL
	// instances). For more information, see Cloud SQL Instance Settings
	// (https://cloud.google.com/sql/docs/mysql/instance-settings).
	Tier string `json:"tier,omitempty"`
	// UserLabels: The resource labels for a Cloud SQL instance to use to annotate
	// any related underlying resources such as Compute Engine VMs. An object
	// containing a list of "key": "value" pairs. Example: `{ "name": "wrench",
	// "mass": "18kg", "count": "3" }`.
	UserLabels map[string]string `json:"userLabels,omitempty"`
	// Zone: The Google Cloud Platform zone where your Cloud SQL database instance
	// is located.
	Zone string `json:"zone,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ActivationPolicy") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ActivationPolicy") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s CloudSqlSettings) MarshalJSON() ([]byte, error) {
	type NoMethod CloudSqlSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ColumnEntity: Column is not used as an independent entity, it is retrieved
// as part of a Table entity.
type ColumnEntity struct {
	// Array: Is the column of array type.
	Array bool `json:"array,omitempty"`
	// ArrayLength: If the column is array, of which length.
	ArrayLength int64 `json:"arrayLength,omitempty"`
	// AutoGenerated: Is the column auto-generated/identity.
	AutoGenerated bool `json:"autoGenerated,omitempty"`
	// Charset: Charset override - instead of table level charset.
	Charset string `json:"charset,omitempty"`
	// Collation: Collation override - instead of table level collation.
	Collation string `json:"collation,omitempty"`
	// Comment: Comment associated with the column.
	Comment string `json:"comment,omitempty"`
	// Computed: Is the column a computed column.
	Computed bool `json:"computed,omitempty"`
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// DataType: Column data type.
	DataType string `json:"dataType,omitempty"`
	// DefaultValue: Default value of the column.
	DefaultValue string `json:"defaultValue,omitempty"`
	// FractionalSecondsPrecision: Column fractional second precision - used for
	// timestamp based datatypes.
	FractionalSecondsPrecision int64 `json:"fractionalSecondsPrecision,omitempty"`
	// Length: Column length - e.g. varchar (50).
	Length int64 `json:"length,omitempty,string"`
	// Name: Column name.
	Name string `json:"name,omitempty"`
	// Nullable: Is the column nullable.
	Nullable bool `json:"nullable,omitempty"`
	// OrdinalPosition: Column order in the table.
	OrdinalPosition int64 `json:"ordinalPosition,omitempty"`
	// Precision: Column precision - when relevant.
	Precision int64 `json:"precision,omitempty"`
	// Scale: Column scale - when relevant.
	Scale int64 `json:"scale,omitempty"`
	// SetValues: Specifies the list of values allowed in the column. Only used for
	// set data type.
	SetValues []string `json:"setValues,omitempty"`
	// Udt: Is the column a UDT.
	Udt bool `json:"udt,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Array") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Array") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ColumnEntity) MarshalJSON() ([]byte, error) {
	type NoMethod ColumnEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// CommitConversionWorkspaceRequest: Request message for
// 'CommitConversionWorkspace' request.
type CommitConversionWorkspaceRequest struct {
	// CommitName: Optional. Optional name of the commit.
	CommitName string `json:"commitName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CommitName") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CommitName") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s CommitConversionWorkspaceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CommitConversionWorkspaceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConditionalColumnSetValue: Options to configure rule type
// ConditionalColumnSetValue. The rule is used to transform the data which is
// being replicated/migrated. The rule filter field can refer to one or more
// entities. The rule scope can be one of: Column.
type ConditionalColumnSetValue struct {
	// CustomFeatures: Optional. Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// SourceNumericFilter: Optional. Optional filter on source column precision
	// and scale. Used for fixed point numbers such as NUMERIC/NUMBER data types.
	SourceNumericFilter *SourceNumericFilter `json:"sourceNumericFilter,omitempty"`
	// SourceTextFilter: Optional. Optional filter on source column length. Used
	// for text based data types like varchar.
	SourceTextFilter *SourceTextFilter `json:"sourceTextFilter,omitempty"`
	// ValueTransformation: Required. Description of data transformation during
	// migration.
	ValueTransformation *ValueTransformation `json:"valueTransformation,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConditionalColumnSetValue) MarshalJSON() ([]byte, error) {
	type NoMethod ConditionalColumnSetValue
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConnectionProfile: A connection profile definition.
type ConnectionProfile struct {
	// Alloydb: An AlloyDB cluster connection profile.
	Alloydb *AlloyDbConnectionProfile `json:"alloydb,omitempty"`
	// Cloudsql: A CloudSQL database connection profile.
	Cloudsql *CloudSqlConnectionProfile `json:"cloudsql,omitempty"`
	// CreateTime: Output only. The timestamp when the resource was created. A
	// timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example:
	// "2014-10-02T15:01:23.045123456Z".
	CreateTime string `json:"createTime,omitempty"`
	// DisplayName: The connection profile display name.
	DisplayName string `json:"displayName,omitempty"`
	// Error: Output only. The error details in case of state FAILED.
	Error *Status `json:"error,omitempty"`
	// Labels: The resource labels for connection profile to use to annotate any
	// related underlying resources such as Compute Engine VMs. An object
	// containing a list of "key": "value" pairs. Example: `{ "name": "wrench",
	// "mass": "1.3kg", "count": "3" }`.
	Labels map[string]string `json:"labels,omitempty"`
	// Mysql: A MySQL database connection profile.
	Mysql *MySqlConnectionProfile `json:"mysql,omitempty"`
	// Name: The name of this connection profile resource in the form of
	// projects/{project}/locations/{location}/connectionProfiles/{connectionProfile
	// }.
	Name string `json:"name,omitempty"`
	// Oracle: An Oracle database connection profile.
	Oracle *OracleConnectionProfile `json:"oracle,omitempty"`
	// Postgresql: A PostgreSQL database connection profile.
	Postgresql *PostgreSqlConnectionProfile `json:"postgresql,omitempty"`
	// Provider: The database provider.
	//
	// Possible values:
	//   "DATABASE_PROVIDER_UNSPECIFIED" - Use this value for on-premise source
	// database instances and ORACLE.
	//   "CLOUDSQL" - Cloud SQL is the source instance provider.
	//   "RDS" - Amazon RDS is the source instance provider.
	//   "AURORA" - Amazon Aurora is the source instance provider.
	//   "ALLOYDB" - AlloyDB for PostgreSQL is the source instance provider.
	//   "AZURE_DATABASE" - Microsoft Azure Database for MySQL/PostgreSQL.
	Provider string `json:"provider,omitempty"`
	// Role: Optional. The connection profile role.
	//
	// Possible values:
	//   "ROLE_UNSPECIFIED" - The role is unspecified.
	//   "SOURCE" - The role is source.
	//   "DESTINATION" - The role is destination.
	Role string `json:"role,omitempty"`
	// SatisfiesPzi: Output only. Reserved for future use.
	SatisfiesPzi bool `json:"satisfiesPzi,omitempty"`
	// SatisfiesPzs: Output only. Reserved for future use.
	SatisfiesPzs bool `json:"satisfiesPzs,omitempty"`
	// Sqlserver: Connection profile for a SQL Server data source.
	Sqlserver *SqlServerConnectionProfile `json:"sqlserver,omitempty"`
	// State: The current connection profile state (e.g. DRAFT, READY, or FAILED).
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - The state of the connection profile is unknown.
	//   "DRAFT" - The connection profile is in draft mode and fully editable.
	//   "CREATING" - The connection profile is being created.
	//   "READY" - The connection profile is ready.
	//   "UPDATING" - The connection profile is being updated.
	//   "DELETING" - The connection profile is being deleted.
	//   "DELETED" - The connection profile has been deleted.
	//   "FAILED" - The last action on the connection profile failed.
	State string `json:"state,omitempty"`
	// UpdateTime: Output only. The timestamp when the resource was last updated. A
	// timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. Example:
	// "2014-10-02T15:01:23.045123456Z".
	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. "Alloydb") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Alloydb") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConnectionProfile) MarshalJSON() ([]byte, error) {
	type NoMethod ConnectionProfile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConstraintEntity: Constraint is not used as an independent entity, it is
// retrieved as part of another entity such as Table or View.
type ConstraintEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// Name: The name of the table constraint.
	Name string `json:"name,omitempty"`
	// ReferenceColumns: Reference columns which may be associated with the
	// constraint. For example, if the constraint is a FOREIGN_KEY, this represents
	// the list of full names of referenced columns by the foreign key.
	ReferenceColumns []string `json:"referenceColumns,omitempty"`
	// ReferenceTable: Reference table which may be associated with the constraint.
	// For example, if the constraint is a FOREIGN_KEY, this represents the list of
	// full name of the referenced table by the foreign key.
	ReferenceTable string `json:"referenceTable,omitempty"`
	// TableColumns: Table columns used as part of the Constraint, for example
	// primary key constraint should list the columns which constitutes the key.
	TableColumns []string `json:"tableColumns,omitempty"`
	// TableName: Table which is associated with the constraint. In case the
	// constraint is defined on a table, this field is left empty as this
	// information is stored in parent_name. However, if constraint is defined on a
	// view, this field stores the table name on which the view is defined.
	TableName string `json:"tableName,omitempty"`
	// Type: Type of constraint, for example unique, primary key, foreign key
	// (currently only primary key is supported).
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConstraintEntity) MarshalJSON() ([]byte, error) {
	type NoMethod ConstraintEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConversionWorkspace: The main conversion workspace resource entity.
type ConversionWorkspace struct {
	// CreateTime: Output only. The timestamp when the workspace resource was
	// created.
	CreateTime string `json:"createTime,omitempty"`
	// Destination: Required. The destination engine details.
	Destination *DatabaseEngineInfo `json:"destination,omitempty"`
	// DestinationProvider: Optional. The provider for the destination database.
	//
	// Possible values:
	//   "DATABASE_PROVIDER_UNSPECIFIED" - Use this value for on-premise source
	// database instances and ORACLE.
	//   "CLOUDSQL" - Cloud SQL is the source instance provider.
	//   "RDS" - Amazon RDS is the source instance provider.
	//   "AURORA" - Amazon Aurora is the source instance provider.
	//   "ALLOYDB" - AlloyDB for PostgreSQL is the source instance provider.
	//   "AZURE_DATABASE" - Microsoft Azure Database for MySQL/PostgreSQL.
	DestinationProvider string `json:"destinationProvider,omitempty"`
	// DisplayName: Optional. The display name for the workspace.
	DisplayName string `json:"displayName,omitempty"`
	// GlobalSettings: Optional. A generic list of settings for the workspace. The
	// settings are database pair dependant and can indicate default behavior for
	// the mapping rules engine or turn on or off specific features. Such examples
	// can be: convert_foreign_key_to_interleave=true, skip_triggers=false,
	// ignore_non_table_synonyms=true
	GlobalSettings map[string]string `json:"globalSettings,omitempty"`
	// HasUncommittedChanges: Output only. Whether the workspace has uncommitted
	// changes (changes which were made after the workspace was committed).
	HasUncommittedChanges bool `json:"hasUncommittedChanges,omitempty"`
	// LatestApplyTime: Optional. Output only. The timestamp when the workspace was
	// last applied.
	LatestApplyTime string `json:"latestApplyTime,omitempty"`
	// LatestCommitId: Output only. The latest commit ID.
	LatestCommitId string `json:"latestCommitId,omitempty"`
	// LatestCommitTime: Output only. The timestamp when the workspace was
	// committed.
	LatestCommitTime string `json:"latestCommitTime,omitempty"`
	// LatestConvertTime: Optional. Output only. The timestamp when the workspace
	// was last converted.
	LatestConvertTime string `json:"latestConvertTime,omitempty"`
	// Name: Full name of the workspace resource, in the form of:
	// projects/{project}/locations/{location}/conversionWorkspaces/{conversion_work
	// space}.
	Name string `json:"name,omitempty"`
	// Source: Required. The source engine details.
	Source *DatabaseEngineInfo `json:"source,omitempty"`
	// SourceProvider: Optional. The provider for the source database.
	//
	// Possible values:
	//   "DATABASE_PROVIDER_UNSPECIFIED" - Use this value for on-premise source
	// database instances and ORACLE.
	//   "CLOUDSQL" - Cloud SQL is the source instance provider.
	//   "RDS" - Amazon RDS is the source instance provider.
	//   "AURORA" - Amazon Aurora is the source instance provider.
	//   "ALLOYDB" - AlloyDB for PostgreSQL is the source instance provider.
	//   "AZURE_DATABASE" - Microsoft Azure Database for MySQL/PostgreSQL.
	SourceProvider string `json:"sourceProvider,omitempty"`
	// UpdateTime: Output only. The timestamp when the workspace resource 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. "CreateTime") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConversionWorkspace) MarshalJSON() ([]byte, error) {
	type NoMethod ConversionWorkspace
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConversionWorkspaceInfo: A conversion workspace's version.
type ConversionWorkspaceInfo struct {
	// CommitId: The commit ID of the conversion workspace.
	CommitId string `json:"commitId,omitempty"`
	// Name: The resource name (URI) of the conversion workspace.
	Name string `json:"name,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CommitId") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CommitId") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConversionWorkspaceInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ConversionWorkspaceInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConvertConversionWorkspaceRequest: Request message for
// 'ConvertConversionWorkspace' request.
type ConvertConversionWorkspaceRequest struct {
	// AutoCommit: Optional. Specifies whether the conversion workspace is to be
	// committed automatically after the conversion.
	AutoCommit bool `json:"autoCommit,omitempty"`
	// ConvertFullPath: Optional. Automatically convert the full entity path for
	// each entity specified by the filter. For example, if the filter specifies a
	// table, that table schema (and database if there is one) will also be
	// converted.
	ConvertFullPath bool `json:"convertFullPath,omitempty"`
	// Filter: Optional. Filter the entities to convert. Leaving this field empty
	// will convert all of the entities. Supports Google AIP-160 style filtering.
	Filter string `json:"filter,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AutoCommit") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AutoCommit") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConvertConversionWorkspaceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ConvertConversionWorkspaceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConvertJobDetails: Details regarding a Convert background job.
type ConvertJobDetails struct {
	// Filter: Output only. AIP-160 based filter used to specify the entities to
	// convert
	Filter string `json:"filter,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Filter") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Filter") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConvertJobDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ConvertJobDetails
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConvertRowIdToColumn: Options to configure rule type ConvertROWIDToColumn.
// The rule is used to add column rowid to destination tables based on an
// Oracle rowid function/property. The rule filter field can refer to one or
// more entities. The rule scope can be one of: Table. This rule requires
// additional filter to be specified beyond the basic rule filter field, which
// is whether or not to work on tables which already have a primary key
// defined.
type ConvertRowIdToColumn struct {
	// OnlyIfNoPrimaryKey: Required. Only work on tables without primary key
	// defined
	OnlyIfNoPrimaryKey bool `json:"onlyIfNoPrimaryKey,omitempty"`
	// ForceSendFields is a list of field names (e.g. "OnlyIfNoPrimaryKey") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "OnlyIfNoPrimaryKey") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConvertRowIdToColumn) MarshalJSON() ([]byte, error) {
	type NoMethod ConvertRowIdToColumn
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DataCacheConfig: Data cache is an optional feature available for Cloud SQL
// for MySQL Enterprise Plus edition only. For more information on data cache,
// see Data cache overview (https://cloud.google.com/sql/help/mysql-data-cache)
// in Cloud SQL documentation.
type DataCacheConfig struct {
	// DataCacheEnabled: Optional. Whether data cache is enabled for the instance.
	DataCacheEnabled bool `json:"dataCacheEnabled,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DataCacheEnabled") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DataCacheEnabled") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DataCacheConfig) MarshalJSON() ([]byte, error) {
	type NoMethod DataCacheConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseEngineInfo: The type and version of a source or destination
// database.
type DatabaseEngineInfo struct {
	// Engine: Required. Engine type.
	//
	// Possible values:
	//   "DATABASE_ENGINE_UNSPECIFIED" - The source database engine of the
	// migration job is unknown.
	//   "MYSQL" - The source engine is MySQL.
	//   "POSTGRESQL" - The source engine is PostgreSQL.
	//   "SQLSERVER" - The source engine is SQL Server.
	//   "ORACLE" - The source engine is Oracle.
	Engine string `json:"engine,omitempty"`
	// Version: Required. Engine version, for example "12.c.1".
	Version string `json:"version,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Engine") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Engine") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseEngineInfo) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseEngineInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseEntity: The base entity type for all the database related entities.
// The message contains the entity name, the name of its parent, the entity
// type, and the specific details per entity type.
type DatabaseEntity struct {
	// Database: Database.
	Database *DatabaseInstanceEntity `json:"database,omitempty"`
	// DatabaseFunction: Function.
	DatabaseFunction *FunctionEntity `json:"databaseFunction,omitempty"`
	// DatabasePackage: Package.
	DatabasePackage *PackageEntity `json:"databasePackage,omitempty"`
	// EntityDdl: Details about the entity DDL script. Multiple DDL scripts are
	// provided for child entities such as a table entity will have one DDL for the
	// table with additional DDLs for each index, constraint and such.
	EntityDdl []*EntityDdl `json:"entityDdl,omitempty"`
	// EntityType: The type of the database entity (table, view, index, ...).
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	EntityType string `json:"entityType,omitempty"`
	// Issues: Details about the various issues found for the entity.
	Issues []*EntityIssue `json:"issues,omitempty"`
	// Mappings: Details about entity mappings. For source tree entities, this
	// holds the draft entities which were generated by the mapping rules. For
	// draft tree entities, this holds the source entities which were converted to
	// form the draft entity. Destination entities will have no mapping details.
	Mappings []*EntityMapping `json:"mappings,omitempty"`
	// MaterializedView: Materialized view.
	MaterializedView *MaterializedViewEntity `json:"materializedView,omitempty"`
	// ParentEntity: The full name of the parent entity (e.g. schema name).
	ParentEntity string `json:"parentEntity,omitempty"`
	// Schema: Schema.
	Schema *SchemaEntity `json:"schema,omitempty"`
	// Sequence: Sequence.
	Sequence *SequenceEntity `json:"sequence,omitempty"`
	// ShortName: The short name (e.g. table name) of the entity.
	ShortName string `json:"shortName,omitempty"`
	// StoredProcedure: Stored procedure.
	StoredProcedure *StoredProcedureEntity `json:"storedProcedure,omitempty"`
	// Synonym: Synonym.
	Synonym *SynonymEntity `json:"synonym,omitempty"`
	// Table: Table.
	Table *TableEntity `json:"table,omitempty"`
	// Tree: The type of tree the entity belongs to.
	//
	// Possible values:
	//   "TREE_TYPE_UNSPECIFIED" - Tree type unspecified.
	//   "SOURCE" - Tree of entities loaded from a source database.
	//   "DRAFT" - Tree of entities converted from the source tree using the
	// mapping rules.
	//   "DESTINATION" - Tree of entities observed on the destination database.
	Tree string `json:"tree,omitempty"`
	// Udt: UDT.
	Udt *UDTEntity `json:"udt,omitempty"`
	// View: View.
	View *ViewEntity `json:"view,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Database") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Database") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseEntity) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseInstanceEntity: DatabaseInstance acts as a parent entity to other
// database entities.
type DatabaseInstanceEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseInstanceEntity) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseInstanceEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseType: A message defining the database engine and provider.
type DatabaseType struct {
	// Engine: The database engine.
	//
	// Possible values:
	//   "DATABASE_ENGINE_UNSPECIFIED" - The source database engine of the
	// migration job is unknown.
	//   "MYSQL" - The source engine is MySQL.
	//   "POSTGRESQL" - The source engine is PostgreSQL.
	//   "SQLSERVER" - The source engine is SQL Server.
	//   "ORACLE" - The source engine is Oracle.
	Engine string `json:"engine,omitempty"`
	// Provider: The database provider.
	//
	// Possible values:
	//   "DATABASE_PROVIDER_UNSPECIFIED" - Use this value for on-premise source
	// database instances and ORACLE.
	//   "CLOUDSQL" - Cloud SQL is the source instance provider.
	//   "RDS" - Amazon RDS is the source instance provider.
	//   "AURORA" - Amazon Aurora is the source instance provider.
	//   "ALLOYDB" - AlloyDB for PostgreSQL is the source instance provider.
	//   "AZURE_DATABASE" - Microsoft Azure Database for MySQL/PostgreSQL.
	Provider string `json:"provider,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Engine") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Engine") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseType) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseType
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DebugInfo: Describes additional debugging info.
type DebugInfo struct {
	// Detail: Additional debugging information provided by the server.
	Detail string `json:"detail,omitempty"`
	// StackEntries: The stack trace entries indicating where the error occurred.
	StackEntries []string `json:"stackEntries,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Detail") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Detail") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DebugInfo) MarshalJSON() ([]byte, error) {
	type NoMethod DebugInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DemoteDestinationRequest: Request message for 'DemoteDestination' request.
type DemoteDestinationRequest struct {
}

// DescribeConversionWorkspaceRevisionsResponse: Response message for
// 'DescribeConversionWorkspaceRevisions' request.
type DescribeConversionWorkspaceRevisionsResponse struct {
	// Revisions: The list of conversion workspace revisions.
	Revisions []*ConversionWorkspace `json:"revisions,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Revisions") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Revisions") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DescribeConversionWorkspaceRevisionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod DescribeConversionWorkspaceRevisionsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DescribeDatabaseEntitiesResponse: Response message for
// 'DescribeDatabaseEntities' request.
type DescribeDatabaseEntitiesResponse struct {
	// DatabaseEntities: The list of database entities for the conversion
	// workspace.
	DatabaseEntities []*DatabaseEntity `json:"databaseEntities,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. "DatabaseEntities") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DatabaseEntities") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DescribeDatabaseEntitiesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod DescribeDatabaseEntitiesResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DoubleComparisonFilter: Filter based on relation between source value and
// compare value of type double in ConditionalColumnSetValue
type DoubleComparisonFilter struct {
	// Value: Required. Double compare value to be used
	Value float64 `json:"value,omitempty"`
	// ValueComparison: Required. Relation between source value and compare value
	//
	// Possible values:
	//   "VALUE_COMPARISON_UNSPECIFIED" - Value comparison unspecified.
	//   "VALUE_COMPARISON_IF_VALUE_SMALLER_THAN" - Value is smaller than the
	// Compare value.
	//   "VALUE_COMPARISON_IF_VALUE_SMALLER_EQUAL_THAN" - Value is smaller or equal
	// than the Compare value.
	//   "VALUE_COMPARISON_IF_VALUE_LARGER_THAN" - Value is larger than the Compare
	// value.
	//   "VALUE_COMPARISON_IF_VALUE_LARGER_EQUAL_THAN" - Value is larger or equal
	// than the Compare value.
	ValueComparison string `json:"valueComparison,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Value") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Value") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DoubleComparisonFilter) MarshalJSON() ([]byte, error) {
	type NoMethod DoubleComparisonFilter
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

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

// DumpFlag: Dump flag definition.
type DumpFlag struct {
	// Name: The name of the flag
	Name string `json:"name,omitempty"`
	// Value: The value of the flag.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DumpFlag) MarshalJSON() ([]byte, error) {
	type NoMethod DumpFlag
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DumpFlags: Dump flags definition.
type DumpFlags struct {
	// DumpFlags: The flags for the initial dump.
	DumpFlags []*DumpFlag `json:"dumpFlags,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DumpFlags") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DumpFlags") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DumpFlags) MarshalJSON() ([]byte, error) {
	type NoMethod DumpFlags
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

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

// EncryptionConfig: EncryptionConfig describes the encryption config of a
// cluster that is encrypted with a CMEK (customer-managed encryption key).
type EncryptionConfig struct {
	// KmsKeyName: The fully-qualified resource name of the KMS key. Each Cloud KMS
	// key is regionalized and has the following format:
	// projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]
	KmsKeyName string `json:"kmsKeyName,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EncryptionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod EncryptionConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// EntityDdl: A single DDL statement for a specific entity
type EntityDdl struct {
	// Ddl: The actual ddl code.
	Ddl string `json:"ddl,omitempty"`
	// DdlKind: The DDL Kind selected for apply, or UNSPECIFIED if the entity
	// wasn't converted yet.
	//
	// Possible values:
	//   "DDL_KIND_UNSPECIFIED" - The kind of the DDL is unknown.
	//   "SOURCE" - DDL of the source entity
	//   "DETERMINISTIC" - Deterministic converted DDL
	//   "AI" - Gemini AI converted DDL
	//   "USER_EDIT" - User edited DDL
	DdlKind string `json:"ddlKind,omitempty"`
	// DdlType: Type of DDL (Create, Alter).
	DdlType string `json:"ddlType,omitempty"`
	// EditedDdlKind: If ddl_kind is USER_EDIT, this holds the DDL kind of the
	// original content - DETERMINISTIC or AI. Otherwise, this is
	// DDL_KIND_UNSPECIFIED.
	//
	// Possible values:
	//   "DDL_KIND_UNSPECIFIED" - The kind of the DDL is unknown.
	//   "SOURCE" - DDL of the source entity
	//   "DETERMINISTIC" - Deterministic converted DDL
	//   "AI" - Gemini AI converted DDL
	//   "USER_EDIT" - User edited DDL
	EditedDdlKind string `json:"editedDdlKind,omitempty"`
	// Entity: The name of the database entity the ddl refers to.
	Entity string `json:"entity,omitempty"`
	// EntityType: The entity type (if the DDL is for a sub entity).
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	EntityType string `json:"entityType,omitempty"`
	// IssueId: EntityIssues found for this ddl.
	IssueId []string `json:"issueId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Ddl") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Ddl") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EntityDdl) MarshalJSON() ([]byte, error) {
	type NoMethod EntityDdl
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// EntityId: An entity identifier.
type EntityId struct {
	// ParentName: The parent entity full name.
	ParentName string `json:"parentName,omitempty"`
	// ParentType: The type of the database entity (schema, table, view, ...).
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	ParentType string `json:"parentType,omitempty"`
	// ShortName: The short name (e.g. table name) of the entity.
	ShortName string `json:"shortName,omitempty"`
	// Type: The type of the database entity (schema, table, view, index, ...).
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ParentName") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ParentName") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EntityId) MarshalJSON() ([]byte, error) {
	type NoMethod EntityId
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// EntityIssue: Issue related to the entity.
type EntityIssue struct {
	// Code: Error/Warning code
	Code string `json:"code,omitempty"`
	// Ddl: The ddl which caused the issue, if relevant.
	Ddl string `json:"ddl,omitempty"`
	// EntityType: The entity type (if the DDL is for a sub entity).
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	EntityType string `json:"entityType,omitempty"`
	// Id: Unique Issue ID.
	Id string `json:"id,omitempty"`
	// Message: Issue detailed message
	Message string `json:"message,omitempty"`
	// Position: The position of the issue found, if relevant.
	Position *Position `json:"position,omitempty"`
	// Severity: Severity of the issue
	//
	// Possible values:
	//   "ISSUE_SEVERITY_UNSPECIFIED" - Unspecified issue severity
	//   "ISSUE_SEVERITY_INFO" - Info
	//   "ISSUE_SEVERITY_WARNING" - Warning
	//   "ISSUE_SEVERITY_ERROR" - Error
	Severity string `json:"severity,omitempty"`
	// Type: The type of the issue.
	//
	// Possible values:
	//   "ISSUE_TYPE_UNSPECIFIED" - Unspecified issue type.
	//   "ISSUE_TYPE_DDL" - Issue originated from the DDL
	//   "ISSUE_TYPE_APPLY" - Issue originated during the apply process
	//   "ISSUE_TYPE_CONVERT" - Issue originated during the convert process
	//   "ISSUE_TYPE_PULL_SCHEMA" - Issue originated during the pull schema process
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Code") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Code") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EntityIssue) MarshalJSON() ([]byte, error) {
	type NoMethod EntityIssue
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// EntityMapping: Details of the mappings of a database entity.
type EntityMapping struct {
	// DraftEntity: Target entity full name. The draft entity can also include a
	// column, index or constraint using the same naming notation
	// schema.table.column.
	DraftEntity string `json:"draftEntity,omitempty"`
	// DraftType: Type of draft entity.
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	DraftType string `json:"draftType,omitempty"`
	// MappingLog: Entity mapping log entries. Multiple rules can be effective and
	// contribute changes to a converted entity, such as a rule can handle the
	// entity name, another rule can handle an entity type. In addition, rules
	// which did not change the entity are also logged along with the reason
	// preventing them to do so.
	MappingLog []*EntityMappingLogEntry `json:"mappingLog,omitempty"`
	// SourceEntity: Source entity full name. The source entity can also be a
	// column, index or constraint using the same naming notation
	// schema.table.column.
	SourceEntity string `json:"sourceEntity,omitempty"`
	// SourceType: Type of source entity.
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	SourceType string `json:"sourceType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DraftEntity") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DraftEntity") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EntityMapping) MarshalJSON() ([]byte, error) {
	type NoMethod EntityMapping
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// EntityMappingLogEntry: A single record of a rule which was used for a
// mapping.
type EntityMappingLogEntry struct {
	// MappingComment: Comment.
	MappingComment string `json:"mappingComment,omitempty"`
	// RuleId: Which rule caused this log entry.
	RuleId string `json:"ruleId,omitempty"`
	// RuleRevisionId: Rule revision ID.
	RuleRevisionId string `json:"ruleRevisionId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "MappingComment") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "MappingComment") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EntityMappingLogEntry) MarshalJSON() ([]byte, error) {
	type NoMethod EntityMappingLogEntry
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// EntityMove: Options to configure rule type EntityMove. The rule is used to
// move an entity to a new schema. The rule filter field can refer to one or
// more entities. The rule scope can be one of: Table, Column, Constraint,
// Index, View, Function, Stored Procedure, Materialized View, Sequence, UDT
type EntityMove struct {
	// NewSchema: Required. The new schema
	NewSchema string `json:"newSchema,omitempty"`
	// ForceSendFields is a list of field names (e.g. "NewSchema") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "NewSchema") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EntityMove) MarshalJSON() ([]byte, error) {
	type NoMethod EntityMove
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// EntityStatusView: A single entity for the UI view.
type EntityStatusView struct {
	// Dependencies: Optional. The set of entities that this entity directly
	// depends on, i.e., it does not include transitive dependencies. Provided only
	// for FULL_WITH_DEPENDENCIES view. Dependencies are provided according to the
	// request tree type.
	Dependencies []*EntityId `json:"dependencies,omitempty"`
	// DraftDdlKind: The DDL Kind selected for apply. If UNSPECIFIED, the entity
	// wasn't converted yet. For SUMMARY view, this rolls up from descendants with
	// the logic of UNSPECIFIED < DETERMINISTIC < AI. USER_EDIT is not propagated.
	//
	// Possible values:
	//   "DDL_KIND_UNSPECIFIED" - The kind of the DDL is unknown.
	//   "SOURCE" - DDL of the source entity
	//   "DETERMINISTIC" - Deterministic converted DDL
	//   "AI" - Gemini AI converted DDL
	//   "USER_EDIT" - User edited DDL
	DraftDdlKind string `json:"draftDdlKind,omitempty"`
	// DraftEntity: The entity short name and type from the DRAFT tree.
	DraftEntity *EntityId `json:"draftEntity,omitempty"`
	// EditedDdlKind: If ddl_kind is USER_EDIT, this holds the DDL kind of the
	// original content - DETERMINISTIC or AI. Otherwise, this is
	// DDL_KIND_UNSPECIFIED. Relevant only for FULL view.
	//
	// Possible values:
	//   "DDL_KIND_UNSPECIFIED" - The kind of the DDL is unknown.
	//   "SOURCE" - DDL of the source entity
	//   "DETERMINISTIC" - Deterministic converted DDL
	//   "AI" - Gemini AI converted DDL
	//   "USER_EDIT" - User edited DDL
	EditedDdlKind string `json:"editedDdlKind,omitempty"`
	// Issues: Unresolved issues information according to the current Draft
	// DdlKind.
	Issues *IssueAggregateData `json:"issues,omitempty"`
	// ResolvedIssues: Resolved issues information according to the current Draft
	// DdlKind.
	ResolvedIssues *IssueAggregateData `json:"resolvedIssues,omitempty"`
	// SourceEntity: The entity short name and type from the SOURCE tree.
	SourceEntity *EntityId `json:"sourceEntity,omitempty"`
	// TestedEntity: Optional. Whether the entity has successfully generated and
	// executed validation tests.
	TestedEntity bool `json:"testedEntity,omitempty"`
	// WasApplied: Was the entity applied on the destination. Relevant only for
	// FULL view.
	WasApplied bool `json:"wasApplied,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Dependencies") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Dependencies") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EntityStatusView) MarshalJSON() ([]byte, error) {
	type NoMethod EntityStatusView
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ErrorInfo: Describes the cause of the error with structured details. Example
// of an error when contacting the "pubsub.googleapis.com" API when it is not
// enabled: { "reason": "API_DISABLED" "domain": "googleapis.com" "metadata": {
// "resource": "projects/123", "service": "pubsub.googleapis.com" } } This
// response indicates that the pubsub.googleapis.com API is not enabled.
// Example of an error that is returned when attempting to create a Spanner
// instance in a region that is out of stock: { "reason": "STOCKOUT" "domain":
// "spanner.googleapis.com", "metadata": { "availableRegions":
// "us-central1,us-east2" } }
type ErrorInfo struct {
	// Domain: The logical grouping to which the "reason" belongs. The error domain
	// is typically the registered service name of the tool or product that
	// generates the error. Example: "pubsub.googleapis.com". If the error is
	// generated by some common infrastructure, the error domain must be a globally
	// unique value that identifies the infrastructure. For Google API
	// infrastructure, the error domain is "googleapis.com".
	Domain string `json:"domain,omitempty"`
	// Metadata: Additional structured details about this error. Keys must match a
	// regular expression of `a-z+` but should ideally be lowerCamelCase. Also,
	// they must be limited to 64 characters in length. When identifying the
	// current value of an exceeded limit, the units should be contained in the
	// key, not the value. For example, rather than `{"instanceLimit":
	// "100/request"}`, should be returned as, `{"instanceLimitPerRequest":
	// "100"}`, if the client exceeds the number of instances that can be created
	// in a single (batch) request.
	Metadata map[string]string `json:"metadata,omitempty"`
	// Reason: The reason for the error. This is a constant value that identifies
	// the proximate cause of the error. Error reasons are unique within a
	// particular domain of errors. This should be at most 63 characters and match
	// a regular expression of `A-Z+[A-Z0-9]`, which represents UPPER_SNAKE_CASE.
	Reason string `json:"reason,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Domain") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Domain") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ErrorInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ErrorInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Expr: Represents a textual expression in the Common Expression Language
// (CEL) syntax. CEL is a C-like expression language. The syntax and semantics
// of CEL are documented at https://github.com/google/cel-spec. Example
// (Comparison): title: "Summary size limit" description: "Determines if a
// summary is less than 100 chars" expression: "document.summary.size() < 100"
// Example (Equality): title: "Requestor is owner" description: "Determines if
// requestor is the document owner" expression: "document.owner ==
// request.auth.claims.email" Example (Logic): title: "Public documents"
// description: "Determine whether the document should be publicly visible"
// expression: "document.type != 'private' && document.type != 'internal'"
// Example (Data Manipulation): title: "Notification string" description:
// "Create a notification string with a timestamp." expression: "'New message
// received at ' + string(document.create_time)" The exact variables and
// functions that may be referenced within an expression are determined by the
// service that evaluates it. See the service documentation for additional
// information.
type Expr struct {
	// Description: Optional. Description of the expression. This is a longer text
	// which describes the expression, e.g. when hovered over it in a UI.
	Description string `json:"description,omitempty"`
	// Expression: Textual representation of an expression in Common Expression
	// Language syntax.
	Expression string `json:"expression,omitempty"`
	// Location: Optional. String indicating the location of the expression for
	// error reporting, e.g. a file name and a position in the file.
	Location string `json:"location,omitempty"`
	// Title: Optional. Title for the expression, i.e. a short string describing
	// its purpose. This can be used e.g. in UIs which allow to enter the
	// expression.
	Title string `json:"title,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Expr) MarshalJSON() ([]byte, error) {
	type NoMethod Expr
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FetchEntitiesStatusViewResponse: Response message for
// DataMigrationService.FetchEntitiesStatusView.
type FetchEntitiesStatusViewResponse struct {
	// Entities: A list of the entities matching the request, sorted by their full
	// name (source name if requested the SOURCE tree, draft name if requested the
	// DRAFT tree). Sub-entities (such as indexes) always appear immediately after
	// their parent element.
	Entities []*EntityStatusView `json:"entities,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. "Entities") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Entities") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FetchEntitiesStatusViewResponse) MarshalJSON() ([]byte, error) {
	type NoMethod FetchEntitiesStatusViewResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FetchIssuesResponse: Response for fetching issues of a conversion workspace.
type FetchIssuesResponse struct {
	// Issues: The list of issues for the conversion workspace.
	Issues []*Issue `json:"issues,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. "Issues") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Issues") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FetchIssuesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod FetchIssuesResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FetchIssuesResponseIssuePosition: Issue position.
type FetchIssuesResponseIssuePosition struct {
	// Column: Issue column number.
	Column int64 `json:"column,omitempty"`
	// Length: Issue length.
	Length int64 `json:"length,omitempty"`
	// Line: Issue line number.
	Line int64 `json:"line,omitempty"`
	// Offset: Issue offset.
	Offset int64 `json:"offset,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Column") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Column") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FetchIssuesResponseIssuePosition) MarshalJSON() ([]byte, error) {
	type NoMethod FetchIssuesResponseIssuePosition
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FetchStaticIpsResponse: Response message for a 'FetchStaticIps' request.
type FetchStaticIpsResponse struct {
	// NextPageToken: A token that 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"`
	// StaticIps: List of static IPs.
	StaticIps []string `json:"staticIps,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FetchStaticIpsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod FetchStaticIpsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FieldViolation: A message type used to describe a single bad request field.
type FieldViolation struct {
	// Description: A description of why the request element is bad.
	Description string `json:"description,omitempty"`
	// Field: A path that leads to a field in the request body. The value will be a
	// sequence of dot-separated identifiers that identify a protocol buffer field.
	// Consider the following: message CreateContactRequest { message EmailAddress
	// { enum Type { TYPE_UNSPECIFIED = 0; HOME = 1; WORK = 2; } optional string
	// email = 1; repeated EmailType type = 2; } string full_name = 1; repeated
	// EmailAddress email_addresses = 2; } In this example, in proto `field` could
	// take one of the following values: * `full_name` for a violation in the
	// `full_name` value * `email_addresses[0].email` for a violation in the
	// `email` field of the first `email_addresses` message *
	// `email_addresses[2].type[1]` for a violation in the second `type` value in
	// the third `email_addresses` message. In JSON, the same values are
	// represented as: * `fullName` for a violation in the `fullName` value *
	// `emailAddresses[0].email` for a violation in the `email` field of the first
	// `emailAddresses` message * `emailAddresses[2].type[1]` for a violation in
	// the second `type` value in the third `emailAddresses` message.
	Field string `json:"field,omitempty"`
	// LocalizedMessage: Provides a localized error message for field-level errors
	// that is safe to return to the API consumer.
	LocalizedMessage *LocalizedMessage `json:"localizedMessage,omitempty"`
	// Reason: The reason for the field-level error. This is a constant value that
	// identifies the proximate cause of the field-level error. It should uniquely
	// identify the type of the FieldViolation within the scope of the
	// google.rpc.ErrorInfo.domain. This should be at most 63 characters and match
	// a regular expression of `A-Z+[A-Z0-9]`, which represents UPPER_SNAKE_CASE.
	Reason string `json:"reason,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FieldViolation) MarshalJSON() ([]byte, error) {
	type NoMethod FieldViolation
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FilterTableColumns: Options to configure rule type FilterTableColumns. The
// rule is used to filter the list of columns to include or exclude from a
// table. The rule filter field can refer to one entity. The rule scope can be:
// Table Only one of the two lists can be specified for the rule.
type FilterTableColumns struct {
	// ExcludeColumns: Optional. List of columns to be excluded for a particular
	// table.
	ExcludeColumns []string `json:"excludeColumns,omitempty"`
	// IncludeColumns: Optional. List of columns to be included for a particular
	// table.
	IncludeColumns []string `json:"includeColumns,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ExcludeColumns") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ExcludeColumns") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FilterTableColumns) MarshalJSON() ([]byte, error) {
	type NoMethod FilterTableColumns
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ForwardSshTunnelConnectivity: Forward SSH Tunnel connectivity.
type ForwardSshTunnelConnectivity struct {
	// Hostname: Required. Hostname for the SSH tunnel.
	Hostname string `json:"hostname,omitempty"`
	// Password: Input only. SSH password.
	Password string `json:"password,omitempty"`
	// Port: Port for the SSH tunnel, default value is 22.
	Port int64 `json:"port,omitempty"`
	// PrivateKey: Input only. SSH private key.
	PrivateKey string `json:"privateKey,omitempty"`
	// Username: Required. Username for the SSH tunnel.
	Username string `json:"username,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Hostname") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Hostname") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ForwardSshTunnelConnectivity) MarshalJSON() ([]byte, error) {
	type NoMethod ForwardSshTunnelConnectivity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FunctionEntity: Function's parent is a schema.
type FunctionEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// SqlCode: The SQL code which creates the function.
	SqlCode string `json:"sqlCode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FunctionEntity) MarshalJSON() ([]byte, error) {
	type NoMethod FunctionEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GenerateSshScriptRequest: Request message for 'GenerateSshScript' request.
type GenerateSshScriptRequest struct {
	// Vm: Required. Bastion VM Instance name to use or to create.
	Vm string `json:"vm,omitempty"`
	// VmCreationConfig: The VM creation configuration
	VmCreationConfig *VmCreationConfig `json:"vmCreationConfig,omitempty"`
	// VmPort: The port that will be open on the bastion host.
	VmPort int64 `json:"vmPort,omitempty"`
	// VmSelectionConfig: The VM selection configuration
	VmSelectionConfig *VmSelectionConfig `json:"vmSelectionConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Vm") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Vm") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GenerateSshScriptRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GenerateSshScriptRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GenerateTcpProxyScriptRequest: Request message for 'GenerateTcpProxyScript'
// request.
type GenerateTcpProxyScriptRequest struct {
	// VmMachineType: Required. The type of the Compute instance that will host the
	// proxy.
	VmMachineType string `json:"vmMachineType,omitempty"`
	// VmName: Required. The name of the Compute instance that will host the proxy.
	VmName string `json:"vmName,omitempty"`
	// VmSubnet: Required. The name of the subnet the Compute instance will use for
	// private connectivity. Must be supplied in the form of
	// projects/{project}/regions/{region}/subnetworks/{subnetwork}. Note: the
	// region for the subnet must match the Compute instance region.
	VmSubnet string `json:"vmSubnet,omitempty"`
	// VmZone: Optional. The Google Cloud Platform zone to create the VM in. The
	// fully qualified name of the zone must be specified, including the region
	// name, for example "us-central1-b". If not specified, uses the "-b" zone of
	// the destination Connection Profile's region.
	VmZone string `json:"vmZone,omitempty"`
	// ForceSendFields is a list of field names (e.g. "VmMachineType") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "VmMachineType") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GenerateTcpProxyScriptRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GenerateTcpProxyScriptRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudClouddmsV1OperationMetadata: Represents the metadata of the
// long-running operation.
type GoogleCloudClouddmsV1OperationMetadata struct {
	// ApiVersion: Output only. API version used to start the operation.
	ApiVersion string `json:"apiVersion,omitempty"`
	// CreateTime: Output only. The time the operation was created.
	CreateTime string `json:"createTime,omitempty"`
	// EndTime: Output only. The time the operation finished running.
	EndTime string `json:"endTime,omitempty"`
	// Metadata: Output only. Additional metadata that is returned by the backend
	// for the operation.
	Metadata map[string]string `json:"metadata,omitempty"`
	// RequestedCancellation: Output only. Identifies whether the user has
	// requested cancellation of the operation. Operations that have successfully
	// been cancelled have google.longrunning.Operation.error value with a
	// google.rpc.Status.code of 1, corresponding to `Code.CANCELLED`.
	RequestedCancellation bool `json:"requestedCancellation,omitempty"`
	// StatusMessage: Output only. Human-readable status of the operation, if any.
	StatusMessage string `json:"statusMessage,omitempty"`
	// Target: Output only. Server-defined resource path for the target of the
	// operation.
	Target string `json:"target,omitempty"`
	// Verb: Output only. Name of the verb executed by the operation.
	Verb string `json:"verb,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ApiVersion") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ApiVersion") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GoogleCloudClouddmsV1OperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudClouddmsV1OperationMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Help: Provides links to documentation or for performing an out of band
// action. For example, if a quota check failed with an error indicating the
// calling project hasn't enabled the accessed service, this can contain a URL
// pointing directly to the right place in the developer console to flip the
// bit.
type Help struct {
	// Links: URL(s) pointing to additional information on handling the current
	// error.
	Links []*Link `json:"links,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Links") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Links") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Help) MarshalJSON() ([]byte, error) {
	type NoMethod Help
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// HeterogeneousMetadata: Metadata for heterogeneous migration jobs objects.
type HeterogeneousMetadata struct {
	// UnsupportedEventsCount: The number of unsupported events.
	UnsupportedEventsCount int64 `json:"unsupportedEventsCount,omitempty,string"`
	// ForceSendFields is a list of field names (e.g. "UnsupportedEventsCount") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "UnsupportedEventsCount") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s HeterogeneousMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod HeterogeneousMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ImportMappingRulesRequest: Request message for 'ImportMappingRules' request.
type ImportMappingRulesRequest struct {
	// AutoCommit: Required. Should the conversion workspace be committed
	// automatically after the import operation.
	AutoCommit bool `json:"autoCommit,omitempty"`
	// RulesFiles: Required. One or more rules files.
	RulesFiles []*RulesFile `json:"rulesFiles,omitempty"`
	// RulesFormat: Required. The format of the rules content file.
	//
	// Possible values:
	//   "IMPORT_RULES_FILE_FORMAT_UNSPECIFIED" - Unspecified rules format.
	//   "IMPORT_RULES_FILE_FORMAT_HARBOUR_BRIDGE_SESSION_FILE" - HarbourBridge
	// session file.
	//   "IMPORT_RULES_FILE_FORMAT_ORATOPG_CONFIG_FILE" - Ora2Pg configuration
	// file.
	RulesFormat string `json:"rulesFormat,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AutoCommit") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AutoCommit") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ImportMappingRulesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ImportMappingRulesRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ImportRulesJobDetails: Details regarding an Import Rules background job.
type ImportRulesJobDetails struct {
	// FileFormat: Output only. The requested file format.
	//
	// Possible values:
	//   "IMPORT_RULES_FILE_FORMAT_UNSPECIFIED" - Unspecified rules format.
	//   "IMPORT_RULES_FILE_FORMAT_HARBOUR_BRIDGE_SESSION_FILE" - HarbourBridge
	// session file.
	//   "IMPORT_RULES_FILE_FORMAT_ORATOPG_CONFIG_FILE" - Ora2Pg configuration
	// file.
	FileFormat string `json:"fileFormat,omitempty"`
	// Files: Output only. File names used for the import rules job.
	Files []string `json:"files,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FileFormat") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "FileFormat") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ImportRulesJobDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ImportRulesJobDetails
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// IndexEntity: Index is not used as an independent entity, it is retrieved as
// part of a Table entity.
type IndexEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// Name: The name of the index.
	Name string `json:"name,omitempty"`
	// TableColumns: Table columns used as part of the Index, for example B-TREE
	// index should list the columns which constitutes the index.
	TableColumns []string `json:"tableColumns,omitempty"`
	// TableColumnsDescending: For each table_column, mark whether it's sorting
	// order is ascending (false) or descending (true). If no value is defined,
	// assume all columns are sorted in ascending order. Otherwise, the number of
	// items must match that of table_columns with each value specifying the
	// direction of the matched column by its index.
	TableColumnsDescending []bool `json:"tableColumnsDescending,omitempty"`
	// Type: Type of index, for example B-TREE.
	Type string `json:"type,omitempty"`
	// Unique: Boolean value indicating whether the index is unique.
	Unique bool `json:"unique,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s IndexEntity) MarshalJSON() ([]byte, error) {
	type NoMethod IndexEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// InstanceNetworkConfig: Metadata related to instance level network
// configuration.
type InstanceNetworkConfig struct {
	// AuthorizedExternalNetworks: Optional. A list of external network authorized
	// to access this instance.
	AuthorizedExternalNetworks []*AuthorizedNetwork `json:"authorizedExternalNetworks,omitempty"`
	// EnableOutboundPublicIp: Optional. Enabling an outbound public IP address to
	// support a database server sending requests out into the internet.
	EnableOutboundPublicIp bool `json:"enableOutboundPublicIp,omitempty"`
	// EnablePublicIp: Optional. Enabling public ip for the instance.
	EnablePublicIp bool `json:"enablePublicIp,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AuthorizedExternalNetworks")
	// to unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AuthorizedExternalNetworks") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s InstanceNetworkConfig) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceNetworkConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// IntComparisonFilter: Filter based on relation between source value and
// compare value of type integer in ConditionalColumnSetValue
type IntComparisonFilter struct {
	// Value: Required. Integer compare value to be used
	Value int64 `json:"value,omitempty,string"`
	// ValueComparison: Required. Relation between source value and compare value
	//
	// Possible values:
	//   "VALUE_COMPARISON_UNSPECIFIED" - Value comparison unspecified.
	//   "VALUE_COMPARISON_IF_VALUE_SMALLER_THAN" - Value is smaller than the
	// Compare value.
	//   "VALUE_COMPARISON_IF_VALUE_SMALLER_EQUAL_THAN" - Value is smaller or equal
	// than the Compare value.
	//   "VALUE_COMPARISON_IF_VALUE_LARGER_THAN" - Value is larger than the Compare
	// value.
	//   "VALUE_COMPARISON_IF_VALUE_LARGER_EQUAL_THAN" - Value is larger or equal
	// than the Compare value.
	ValueComparison string `json:"valueComparison,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Value") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Value") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s IntComparisonFilter) MarshalJSON() ([]byte, error) {
	type NoMethod IntComparisonFilter
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Issue: Issue related to the entity.
type Issue struct {
	// CategoryId: The category ID.
	//
	// Possible values:
	//   "ISSUE_CATEGORY_ID_UNSPECIFIED" - Unspecified issue category ID.
	//   "ISSUE_CATEGORY_ID_CW00" - General conversion issues.
	//   "ISSUE_CATEGORY_ID_CW01" - Input issues.
	//   "ISSUE_CATEGORY_ID_CW02" - Source functionality not supported.
	//   "ISSUE_CATEGORY_ID_CW03" - Source feature not supported.
	//   "ISSUE_CATEGORY_ID_CW04" - Unsupported syntax.
	//   "ISSUE_CATEGORY_ID_CW05" - Data types and conversion.
	//   "ISSUE_CATEGORY_ID_CW06" - Potential functional nuances.
	//   "ISSUE_CATEGORY_ID_CW07" - Functional review recommended.
	//   "ISSUE_CATEGORY_ID_CW08" - Refactoring required.
	//   "ISSUE_CATEGORY_ID_CW99" - Gemini review recommendations.
	//   "ISSUE_CATEGORY_ID_QA00" - Quality assessment findings.
	//   "ISSUE_CATEGORY_ID_AP00" - General apply issues.
	CategoryId string `json:"categoryId,omitempty"`
	// EntityFullName: Entity full name.
	EntityFullName string `json:"entityFullName,omitempty"`
	// EntityType: The entity type (if the DDL is for a sub entity).
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	EntityType string `json:"entityType,omitempty"`
	// GroupId: The group ID.
	//
	// Possible values:
	//   "ISSUE_GROUP_ID_UNSPECIFIED" - Unspecified issue group ID.
	//   "ISSUE_GROUP_ID_CW_OP0000" - General conversion issues.
	//   "ISSUE_GROUP_ID_CW_OP0001" - Metadata conversion issues.
	//   "ISSUE_GROUP_ID_CW_OP0002" - Contact your support team.
	//   "ISSUE_GROUP_ID_CW_OP0101" - Invalid source code.
	//   "ISSUE_GROUP_ID_CW_OP0102" - Missing referenced objects.
	//   "ISSUE_GROUP_ID_CW_OP0103" - Missing primary key.
	//   "ISSUE_GROUP_ID_CW_OP0200" - Source functionality not supported.
	//   "ISSUE_GROUP_ID_CW_OP0201" - SQLCODE not supported.
	//   "ISSUE_GROUP_ID_CW_OP0202" - Oracle data dictionary object not supported.
	//   "ISSUE_GROUP_ID_CW_OP0203" - Oracle SQL function not supported.
	//   "ISSUE_GROUP_ID_CW_OP0204" - Oracle PL/SQL package not supported.
	//   "ISSUE_GROUP_ID_CW_OP0205" - Data type not supported.
	//   "ISSUE_GROUP_ID_CW_OP0206" - Naming conflict.
	//   "ISSUE_GROUP_ID_CW_OP0300" - Source feature not supported.
	//   "ISSUE_GROUP_ID_CW_OP0301" - Schema objects or attributes not supported.
	//   "ISSUE_GROUP_ID_CW_OP0315" - Synonyms not supported.
	//   "ISSUE_GROUP_ID_CW_OP0303" - Bulk binding not supported.
	//   "ISSUE_GROUP_ID_CW_OP0304" - Collections not supported.
	//   "ISSUE_GROUP_ID_CW_OP0305" - Pipelined functions not supported.
	//   "ISSUE_GROUP_ID_CW_OP0306" - Dynamic SQL not supported.
	//   "ISSUE_GROUP_ID_CW_OP0307" - CONNECT BY option not supported.
	//   "ISSUE_GROUP_ID_CW_OP0308" - Locking and transactions issues.
	//   "ISSUE_GROUP_ID_CW_OP0309" - JSON not supported.
	//   "ISSUE_GROUP_ID_CW_OP0310" - XML not supported.
	//   "ISSUE_GROUP_ID_CW_OP0311" - MERGE not supported.
	//   "ISSUE_GROUP_ID_CW_OP0312" - PIVOT not supported.
	//   "ISSUE_GROUP_ID_CW_OP0313" - ALTER statement option not supported.
	//   "ISSUE_GROUP_ID_CW_OP0314" - SQL feature not supported.
	//   "ISSUE_GROUP_ID_CW_OP0302" - PL/SQL feature not supported.
	//   "ISSUE_GROUP_ID_CW_OP0400" - Unsupported syntax.
	//   "ISSUE_GROUP_ID_CW_OP0401" - Unsupported SQL syntax.
	//   "ISSUE_GROUP_ID_CW_OP0402" - Unsupported PL/SQL syntax.
	//   "ISSUE_GROUP_ID_CW_OP0403" - Unsupported date and timestamp syntax.
	//   "ISSUE_GROUP_ID_CW_OP0404" - Unsupported exceptions syntax.
	//   "ISSUE_GROUP_ID_CW_OP0500" - Data types and conversion issues.
	//   "ISSUE_GROUP_ID_CW_OP0501" - Date format model issues.
	//   "ISSUE_GROUP_ID_CW_OP0502" - Numeric format model issues.
	//   "ISSUE_GROUP_ID_CW_OP0503" - Casting issues.
	//   "ISSUE_GROUP_ID_CW_OP0504" - Comparison issues.
	//   "ISSUE_GROUP_ID_CW_OP0601" - Review date format model.
	//   "ISSUE_GROUP_ID_CW_OP0602" - Review numeric format model.
	//   "ISSUE_GROUP_ID_CW_OP0603" - Review exception code.
	//   "ISSUE_GROUP_ID_CW_OP0604" - Review exception message.
	//   "ISSUE_GROUP_ID_CW_OP0605" - Review Oracle built-in function emulation.
	//   "ISSUE_GROUP_ID_CW_OP0606" - Review foreign key column data type.
	//   "ISSUE_GROUP_ID_CW_OP0701" - Functional review recommended.
	//   "ISSUE_GROUP_ID_CW_OP0702" - Review Oracle built-in function emulation.
	//   "ISSUE_GROUP_ID_CW_OP0801" - Autonomous transactions refactoring required.
	//   "ISSUE_GROUP_ID_CW_OP0802" - Database links refactoring required.
	//   "ISSUE_GROUP_ID_CW_OP0803" - Advanced queuing refactoring required.
	//   "ISSUE_GROUP_ID_CW_OP0804" - Database email refactoring required.
	//   "ISSUE_GROUP_ID_CW_OP0805" - Jobs and scheduling refactoring required.
	//   "ISSUE_GROUP_ID_CW_OP0806" - File I/O refactoring required.
	//   "ISSUE_GROUP_ID_CW_OP0807" - Synonyms refactoring required.
	//   "ISSUE_GROUP_ID_CW_OP0808" - Global temporary tables refactoring required.
	//   "ISSUE_GROUP_ID_QA_OP0000" - Functional equivalence assessment findings.
	//   "ISSUE_GROUP_ID_CW_SP0000" - General conversion issues.
	//   "ISSUE_GROUP_ID_CW_SP0001" - Metadata conversion issues.
	//   "ISSUE_GROUP_ID_CW_SP0002" - Contact your support team.
	//   "ISSUE_GROUP_ID_CW_SP0101" - Invalid source code.
	//   "ISSUE_GROUP_ID_CW_SP0102" - Missing referenced objects.
	//   "ISSUE_GROUP_ID_CW_SP0103" - Missing primary key.
	//   "ISSUE_GROUP_ID_CW_SP0200" - Source functionality not supported.
	//   "ISSUE_GROUP_ID_CW_SP0201" - SQL Server system view not supported.
	//   "ISSUE_GROUP_ID_CW_SP0202" - SQL Server SQL function not supported.
	//   "ISSUE_GROUP_ID_CW_SP0203" - SQL Server T-SQL object not supported.
	//   "ISSUE_GROUP_ID_CW_SP0204" - Missing SQL Server system View
	//   "ISSUE_GROUP_ID_CW_SP0205" - Naming conflict.
	//   "ISSUE_GROUP_ID_CW_SP0300" - Source feature not supported.
	//   "ISSUE_GROUP_ID_CW_SP0302" - T-SQL feature not supported.
	//   "ISSUE_GROUP_ID_CW_SP0306" - Dynamic SQL not supported.
	//   "ISSUE_GROUP_ID_CW_SP0308" - JSON not supported.
	//   "ISSUE_GROUP_ID_CW_SP0309" - Locking and transactions issues.
	//   "ISSUE_GROUP_ID_CW_SP0310" - XML not supported.
	//   "ISSUE_GROUP_ID_CW_SP0311" - MERGE not supported.
	//   "ISSUE_GROUP_ID_CW_SP0312" - PIVOT not supported.
	//   "ISSUE_GROUP_ID_CW_SP0313" - ALTER statement option not supported.
	//   "ISSUE_GROUP_ID_CW_SP0314" - SQL feature not supported.
	//   "ISSUE_GROUP_ID_CW_SP0400" - Unsupported syntax.
	//   "ISSUE_GROUP_ID_CW_SP0401" - Unsupported SQL syntax.
	//   "ISSUE_GROUP_ID_CW_SP0402" - Unsupported T-SQL syntax.
	//   "ISSUE_GROUP_ID_CW_SP0403" - Unsupported date and timestamp syntax.
	//   "ISSUE_GROUP_ID_CW_SP0404" - Unsupported exceptions syntax.
	//   "ISSUE_GROUP_ID_CW_SP0500" - Data types and conversion issues.
	//   "ISSUE_GROUP_ID_CW_SP0501" - Date format model issues.
	//   "ISSUE_GROUP_ID_CW_SP0502" - Numeric format model issues.
	//   "ISSUE_GROUP_ID_CW_SP0503" - Casting issues.
	//   "ISSUE_GROUP_ID_CW_SP0504" - Comparison issues.
	//   "ISSUE_GROUP_ID_CW_SP0601" - Review date format model.
	//   "ISSUE_GROUP_ID_CW_SP0602" - Review numeric format model.
	//   "ISSUE_GROUP_ID_CW_SP0604" - Review exception message.
	//   "ISSUE_GROUP_ID_CW_SP0701" - Functional review recommended.
	//   "ISSUE_GROUP_ID_CW_SP0802" - Database links refactoring required.
	//   "ISSUE_GROUP_ID_CW_SP0807" - Synonyms refactoring required.
	//   "ISSUE_GROUP_ID_QA_SP0000" - Functional equivalence assessment findings.
	//   "ISSUE_GROUP_ID_CW_AI9900" - Review Gemini suggestions.
	//   "ISSUE_GROUP_ID_CW_AI9901" - Review AI-augmented code.
	//   "ISSUE_GROUP_ID_CW_AI9902" - Citations for AI-augmented code.
	//   "ISSUE_GROUP_ID_CW_AP0000" - General apply issues.
	GroupId string `json:"groupId,omitempty"`
	// Id: Unique Issue ID. Use this ID when referencing a specific issue in other
	// API calls, such as DataMigrationService.SetIssuesState.
	Id string `json:"id,omitempty"`
	// IssueOrigin: The source of the issue (deterministic, gemini, etc).
	//
	// Possible values:
	//   "ISSUE_ORIGIN_UNSPECIFIED" - Unspecified issue origin.
	//   "ISSUE_ORIGIN_DETERMINISTIC" - Issue originated from the deterministic
	// conversion engine.
	//   "ISSUE_ORIGIN_AI" - Issue originated from the AI conversion engine.
	//   "ISSUE_ORIGIN_AI_FROM_DETERMINISTIC" - CODE_CONVERSION/CST issues that
	// were carried over to the Gemini conversion,
	IssueOrigin string `json:"issueOrigin,omitempty"`
	// IssueState: Output only. The state of the issue (open, resolved, etc).
	//
	// Possible values:
	//   "ISSUE_STATE_UNSPECIFIED" - Unspecified issue state.
	//   "ISSUE_STATE_OPEN" - Issue is open.
	//   "ISSUE_STATE_RESOLVED" - Issue is resolved.
	IssueState string `json:"issueState,omitempty"`
	// Message: Issue detailed message.
	Message string `json:"message,omitempty"`
	// Position: The position of the issue found, if relevant.
	Position *FetchIssuesResponseIssuePosition `json:"position,omitempty"`
	// Severity: Severity of the issue.
	//
	// Possible values:
	//   "ISSUE_SEVERITY_UNSPECIFIED" - Unspecified issue severity.
	//   "ISSUE_SEVERITY_INFO" - Info.
	//   "ISSUE_SEVERITY_WARNING" - Warning.
	//   "ISSUE_SEVERITY_ERROR" - Error.
	Severity string `json:"severity,omitempty"`
	// Type: The type of the issue.
	//
	// Possible values:
	//   "ISSUE_TYPE_UNSPECIFIED" - Unspecified issue type.
	//   "ISSUE_TYPE_CONVERSION" - Issue originated from the conversion process.
	//   "ISSUE_TYPE_PULL_SCHEMA" - Issue originated from the pull schema process.
	//   "ISSUE_TYPE_APPLY" - Issue originated from the apply process.
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CategoryId") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CategoryId") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Issue) MarshalJSON() ([]byte, error) {
	type NoMethod Issue
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// IssueAggregateData: Aggregate issue information.
type IssueAggregateData struct {
	// ErrorCount: Number of error issues.
	ErrorCount int64 `json:"errorCount,omitempty"`
	// InfoCount: Number of info issues.
	InfoCount int64 `json:"infoCount,omitempty"`
	// WarningCount: Number of warning issues.
	WarningCount int64 `json:"warningCount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ErrorCount") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ErrorCount") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s IssueAggregateData) MarshalJSON() ([]byte, error) {
	type NoMethod IssueAggregateData
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Link: Describes a URL link.
type Link struct {
	// Description: Describes what the link offers.
	Description string `json:"description,omitempty"`
	// Url: The URL of the link.
	Url string `json:"url,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Link) MarshalJSON() ([]byte, error) {
	type NoMethod Link
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListConnectionProfilesResponse: Response message for
// 'ListConnectionProfiles' request.
type ListConnectionProfilesResponse struct {
	// ConnectionProfiles: The response list of connection profiles.
	ConnectionProfiles []*ConnectionProfile `json:"connectionProfiles,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"`
	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "ConnectionProfiles") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ConnectionProfiles") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListConnectionProfilesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListConnectionProfilesResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListConversionWorkspacesResponse: Response message for
// 'ListConversionWorkspaces' request.
type ListConversionWorkspacesResponse struct {
	// ConversionWorkspaces: The list of conversion workspace objects.
	ConversionWorkspaces []*ConversionWorkspace `json:"conversionWorkspaces,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"`
	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "ConversionWorkspaces") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ConversionWorkspaces") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListConversionWorkspacesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListConversionWorkspacesResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListLocationsResponse: The response message for Locations.ListLocations.
type ListLocationsResponse struct {
	// Locations: A list of locations that matches the specified filter in the
	// request.
	Locations []*Location `json:"locations,omitempty"`
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Locations") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Locations") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

// ListMappingRulesResponse: Response message for 'ListMappingRulesRequest'
// request.
type ListMappingRulesResponse struct {
	// MappingRules: The list of conversion workspace mapping rules.
	MappingRules []*MappingRule `json:"mappingRules,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. "MappingRules") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "MappingRules") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListMappingRulesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListMappingRulesResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListMigrationJobObjectsResponse: Response containing the objects for a
// migration job.
type ListMigrationJobObjectsResponse struct {
	// MigrationJobObjects: List of migration job objects.
	MigrationJobObjects []*MigrationJobObject `json:"migrationJobObjects,omitempty"`
	// NextPageToken: A token, which can be sent as `page_token` to retrieve the
	// next page.
	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. "MigrationJobObjects") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "MigrationJobObjects") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListMigrationJobObjectsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListMigrationJobObjectsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListMigrationJobsResponse: Response message for 'ListMigrationJobs' request.
type ListMigrationJobsResponse struct {
	// MigrationJobs: The list of migration jobs objects.
	MigrationJobs []*MigrationJob `json:"migrationJobs,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"`
	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "MigrationJobs") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "MigrationJobs") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListMigrationJobsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListMigrationJobsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListOperationsResponse: The response message for Operations.ListOperations.
type ListOperationsResponse struct {
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Operations: A list of operations that matches the specified filter in the
	// request.
	Operations []*Operation `json:"operations,omitempty"`
	// Unreachable: Unordered list. Unreachable resources. Populated when the
	// request sets `ListOperationsRequest.return_partial_success` and reads across
	// collections. For example, when attempting to list all resources across all
	// supported locations.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

// ListPrivateConnectionsResponse: Response message for
// 'ListPrivateConnections' request.
type ListPrivateConnectionsResponse struct {
	// 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"`
	// PrivateConnections: List of private connections.
	PrivateConnections []*PrivateConnection `json:"privateConnections,omitempty"`
	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListPrivateConnectionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListPrivateConnectionsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// LocalizedMessage: Provides a localized error message that is safe to return
// to the user which can be attached to an RPC error.
type LocalizedMessage struct {
	// Locale: The locale used following the specification defined at
	// https://www.rfc-editor.org/rfc/bcp/bcp47.txt. Examples are: "en-US",
	// "fr-CH", "es-MX"
	Locale string `json:"locale,omitempty"`
	// Message: The localized error message in the above locale.
	Message string `json:"message,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Locale") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Locale") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s LocalizedMessage) MarshalJSON() ([]byte, error) {
	type NoMethod LocalizedMessage
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Location: A resource that represents a Google Cloud location.
type Location struct {
	// DisplayName: The friendly name for this location, typically a nearby city
	// name. For example, "Tokyo".
	DisplayName string `json:"displayName,omitempty"`
	// Labels: Cross-service attributes for the location. For example
	// {"cloud.googleapis.com/region": "us-east1"}
	Labels map[string]string `json:"labels,omitempty"`
	// LocationId: The canonical id for this location. For example: "us-east1".
	LocationId string `json:"locationId,omitempty"`
	// Metadata: Service-specific metadata. For example the available capacity at
	// the given location.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`
	// Name: Resource name for the location, which may vary between
	// implementations. For example:
	// "projects/example-project/locations/us-east1"
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DisplayName") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

// LogFileDirectories: Configuration to specify the Oracle directories to
// access the log files.
type LogFileDirectories struct {
	// ArchivedLogDirectory: Required. Oracle directory for archived logs.
	ArchivedLogDirectory string `json:"archivedLogDirectory,omitempty"`
	// OnlineLogDirectory: Required. Oracle directory for online logs.
	OnlineLogDirectory string `json:"onlineLogDirectory,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ArchivedLogDirectory") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ArchivedLogDirectory") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s LogFileDirectories) MarshalJSON() ([]byte, error) {
	type NoMethod LogFileDirectories
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// LogMiner: Configuration to use LogMiner CDC method.
type LogMiner struct {
}

// LookupMigrationJobObjectRequest: Request for looking up a specific migration
// job object by its source object identifier.
type LookupMigrationJobObjectRequest struct {
	// SourceObjectIdentifier: Required. The source object identifier which maps to
	// the migration job object.
	SourceObjectIdentifier *SourceObjectIdentifier `json:"sourceObjectIdentifier,omitempty"`
	// ForceSendFields is a list of field names (e.g. "SourceObjectIdentifier") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "SourceObjectIdentifier") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s LookupMigrationJobObjectRequest) MarshalJSON() ([]byte, error) {
	type NoMethod LookupMigrationJobObjectRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MachineConfig: MachineConfig describes the configuration of a machine.
type MachineConfig struct {
	// CpuCount: The number of CPU's in the VM instance.
	CpuCount int64 `json:"cpuCount,omitempty"`
	// MachineType: Optional. Machine type of the VM instance. E.g. "n2-highmem-4",
	// "n2-highmem-8", "c4a-highmem-4-lssd". cpu_count must match the number of
	// vCPUs in the machine type.
	MachineType string `json:"machineType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CpuCount") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CpuCount") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MachineConfig) MarshalJSON() ([]byte, error) {
	type NoMethod MachineConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MappingRule: Definition of a transformation that is to be applied to a group
// of entities in the source schema. Several such transformations can be
// applied to an entity sequentially to define the corresponding entity in the
// target schema.
type MappingRule struct {
	// ConditionalColumnSetValue: Optional. Rule to specify how the data contained
	// in a column should be transformed (such as trimmed, rounded, etc) provided
	// that the data meets certain criteria.
	ConditionalColumnSetValue *ConditionalColumnSetValue `json:"conditionalColumnSetValue,omitempty"`
	// ConvertRowidColumn: Optional. Rule to specify how multiple tables should be
	// converted with an additional rowid column.
	ConvertRowidColumn *ConvertRowIdToColumn `json:"convertRowidColumn,omitempty"`
	// DisplayName: Optional. A human readable name
	DisplayName string `json:"displayName,omitempty"`
	// EntityMove: Optional. Rule to specify how multiple entities should be
	// relocated into a different schema.
	EntityMove *EntityMove `json:"entityMove,omitempty"`
	// Filter: Required. The rule filter
	Filter *MappingRuleFilter `json:"filter,omitempty"`
	// FilterTableColumns: Optional. Rule to specify the list of columns to include
	// or exclude from a table.
	FilterTableColumns *FilterTableColumns `json:"filterTableColumns,omitempty"`
	// MultiColumnDataTypeChange: Optional. Rule to specify how multiple columns
	// should be converted to a different data type.
	MultiColumnDataTypeChange *MultiColumnDatatypeChange `json:"multiColumnDataTypeChange,omitempty"`
	// MultiEntityRename: Optional. Rule to specify how multiple entities should be
	// renamed.
	MultiEntityRename *MultiEntityRename `json:"multiEntityRename,omitempty"`
	// Name: Full name of the mapping rule resource, in the form of:
	// projects/{project}/locations/{location}/conversionWorkspaces/{set}/mappingRul
	// e/{rule}.
	Name string `json:"name,omitempty"`
	// RevisionCreateTime: Output only. The timestamp that the revision was
	// created.
	RevisionCreateTime string `json:"revisionCreateTime,omitempty"`
	// RevisionId: Output only. The revision ID of the mapping rule. A new revision
	// is committed whenever the mapping rule is changed in any way. The format is
	// an 8-character hexadecimal string.
	RevisionId string `json:"revisionId,omitempty"`
	// RuleOrder: Required. The order in which the rule is applied. Lower order
	// rules are applied before higher value rules so they may end up being
	// overridden.
	RuleOrder int64 `json:"ruleOrder,omitempty,string"`
	// RuleScope: Required. The rule scope
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	RuleScope string `json:"ruleScope,omitempty"`
	// SetTablePrimaryKey: Optional. Deprecated: This rule is no longer supported.
	SetTablePrimaryKey *SetTablePrimaryKey `json:"setTablePrimaryKey,omitempty"`
	// SingleColumnChange: Optional. Rule to specify how a single column is
	// converted.
	SingleColumnChange *SingleColumnChange `json:"singleColumnChange,omitempty"`
	// SingleEntityRename: Optional. Rule to specify how a single entity should be
	// renamed.
	SingleEntityRename *SingleEntityRename `json:"singleEntityRename,omitempty"`
	// SinglePackageChange: Optional. Rule to specify how a single package is
	// converted.
	SinglePackageChange *SinglePackageChange `json:"singlePackageChange,omitempty"`
	// SourceSqlChange: Optional. Rule to change the sql code for an entity, for
	// example, function, procedure.
	SourceSqlChange *SourceSqlChange `json:"sourceSqlChange,omitempty"`
	// State: Optional. The mapping rule state
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - The state of the mapping rule is unknown.
	//   "ENABLED" - The rule is enabled.
	//   "DISABLED" - The rule is disabled.
	//   "DELETED" - The rule is logically deleted.
	State string `json:"state,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "ConditionalColumnSetValue")
	// to unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ConditionalColumnSetValue") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MappingRule) MarshalJSON() ([]byte, error) {
	type NoMethod MappingRule
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MappingRuleFilter: A filter defining the entities that a mapping rule should
// be applied to. When more than one field is specified, the rule is applied
// only to entities which match all the fields.
type MappingRuleFilter struct {
	// Entities: Optional. The rule should be applied to specific entities defined
	// by their fully qualified names.
	Entities []string `json:"entities,omitempty"`
	// EntityNameContains: Optional. The rule should be applied to entities whose
	// non-qualified name contains the given string.
	EntityNameContains string `json:"entityNameContains,omitempty"`
	// EntityNamePrefix: Optional. The rule should be applied to entities whose
	// non-qualified name starts with the given prefix.
	EntityNamePrefix string `json:"entityNamePrefix,omitempty"`
	// EntityNameSuffix: Optional. The rule should be applied to entities whose
	// non-qualified name ends with the given suffix.
	EntityNameSuffix string `json:"entityNameSuffix,omitempty"`
	// ParentEntity: Optional. The rule should be applied to entities whose parent
	// entity (fully qualified name) matches the given value. For example, if the
	// rule applies to a table entity, the expected value should be a schema
	// (schema). If the rule applies to a column or index entity, the expected
	// value can be either a schema (schema) or a table (schema.table)
	ParentEntity string `json:"parentEntity,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Entities") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Entities") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MappingRuleFilter) MarshalJSON() ([]byte, error) {
	type NoMethod MappingRuleFilter
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MaterializedViewEntity: MaterializedView's parent is a schema.
type MaterializedViewEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// Indices: View indices.
	Indices []*IndexEntity `json:"indices,omitempty"`
	// SqlCode: The SQL code which creates the view.
	SqlCode string `json:"sqlCode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MaterializedViewEntity) MarshalJSON() ([]byte, error) {
	type NoMethod MaterializedViewEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MigrationJob: Represents a Database Migration Service migration job object.
type MigrationJob struct {
	// CmekKeyName: The CMEK (customer-managed encryption key) fully qualified key
	// name used for the migration job. This field supports all migration jobs
	// types except for: * Mysql to Mysql (use the cmek field in the cloudsql
	// connection profile instead). * PostrgeSQL to PostgreSQL (use the cmek field
	// in the cloudsql connection profile instead). * PostgreSQL to AlloyDB (use
	// the kms_key_name field in the alloydb connection profile instead). Each
	// Cloud CMEK key has the following format:
	// projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME]
	CmekKeyName string `json:"cmekKeyName,omitempty"`
	// ConversionWorkspace: The conversion workspace used by the migration.
	ConversionWorkspace *ConversionWorkspaceInfo `json:"conversionWorkspace,omitempty"`
	// CreateTime: Output only. The timestamp when the migration job resource was
	// created. A timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds.
	// Example: "2014-10-02T15:01:23.045123456Z".
	CreateTime string `json:"createTime,omitempty"`
	// Destination: Required. The resource name (URI) of the destination connection
	// profile.
	Destination string `json:"destination,omitempty"`
	// DestinationDatabase: The database engine type and provider of the
	// destination.
	DestinationDatabase *DatabaseType `json:"destinationDatabase,omitempty"`
	// DisplayName: The migration job display name.
	DisplayName string `json:"displayName,omitempty"`
	// DumpFlags: The initial dump flags. This field and the "dump_path" field are
	// mutually exclusive.
	DumpFlags *DumpFlags `json:"dumpFlags,omitempty"`
	// DumpPath: The path to the dump file in Google Cloud Storage, in the format:
	// (gs://[BUCKET_NAME]/[OBJECT_NAME]). This field and the "dump_flags" field
	// are mutually exclusive.
	DumpPath string `json:"dumpPath,omitempty"`
	// DumpType: Optional. The type of the data dump. Supported for MySQL to
	// CloudSQL for MySQL migrations only.
	//
	// Possible values:
	//   "DUMP_TYPE_UNSPECIFIED" - If not specified, defaults to LOGICAL
	//   "LOGICAL" - Logical dump.
	//   "PHYSICAL" - Physical file-based dump. Supported for MySQL to CloudSQL for
	// MySQL migrations only.
	DumpType string `json:"dumpType,omitempty"`
	// Duration: Output only. The duration of the migration job (in seconds). A
	// duration in seconds with up to nine fractional digits, terminated by 's'.
	// Example: "3.5s".
	Duration string `json:"duration,omitempty"`
	// EndTime: Output only. If the migration job is completed, the time when it
	// was completed.
	EndTime string `json:"endTime,omitempty"`
	// Error: Output only. The error details in case of state FAILED.
	Error *Status `json:"error,omitempty"`
	// Filter: This field can be used to select the entities to migrate as part of
	// the migration job. It uses AIP-160 notation to select a subset of the
	// entities configured on the associated conversion-workspace. This field
	// should not be set on migration-jobs that are not associated with a
	// conversion workspace.
	Filter string `json:"filter,omitempty"`
	// Labels: The resource labels for migration job to use to annotate any related
	// underlying resources such as Compute Engine VMs. An object containing a list
	// of "key": "value" pairs. Example: `{ "name": "wrench", "mass": "1.3kg",
	// "count": "3" }`.
	Labels map[string]string `json:"labels,omitempty"`
	// MysqlHomogeneousConfig: Optional. Configuration for MySQL homogeneous
	// migration.
	MysqlHomogeneousConfig *MySqlHomogeneousConfig `json:"mysqlHomogeneousConfig,omitempty"`
	// Name: The name (URI) of this migration job resource, in the form of:
	// projects/{project}/locations/{location}/migrationJobs/{migrationJob}.
	Name string `json:"name,omitempty"`
	// ObjectsConfig: Optional. The objects that need to be migrated.
	ObjectsConfig *MigrationJobObjectsConfig `json:"objectsConfig,omitempty"`
	// OracleToPostgresConfig: Configuration for heterogeneous **Oracle to Cloud
	// SQL for PostgreSQL** and **Oracle to AlloyDB for PostgreSQL** migrations.
	OracleToPostgresConfig *OracleToPostgresConfig `json:"oracleToPostgresConfig,omitempty"`
	// OriginalMigrationName: Optional. A failback replication pointer to the
	// resource name (URI) of the original migration job.
	OriginalMigrationName string `json:"originalMigrationName,omitempty"`
	// PerformanceConfig: Optional. Data dump and load parallelism settings used by
	// the migration.
	PerformanceConfig *PerformanceConfig `json:"performanceConfig,omitempty"`
	// Phase: Output only. The current migration job phase.
	//
	// Possible values:
	//   "PHASE_UNSPECIFIED" - The phase of the migration job is unknown.
	//   "FULL_DUMP" - The migration job is in the full dump phase.
	//   "CDC" - The migration job is CDC phase.
	//   "PROMOTE_IN_PROGRESS" - The migration job is running the promote phase.
	//   "WAITING_FOR_SOURCE_WRITES_TO_STOP" - Only RDS flow - waiting for source
	// writes to stop
	//   "PREPARING_THE_DUMP" - Only RDS flow - the sources writes stopped, waiting
	// for dump to begin
	//   "READY_FOR_PROMOTE" - The migration job is ready to be promoted.
	//   "PHASE_FAILBACK" - The migration job is in the failback phase. This phase
	// is currently used only for SQL Server Distributed Availability Group (DAG)
	// migrations.
	Phase string `json:"phase,omitempty"`
	// PostgresHomogeneousConfig: Optional. Configuration for PostgreSQL
	// homogeneous migration.
	PostgresHomogeneousConfig *PostgresHomogeneousConfig `json:"postgresHomogeneousConfig,omitempty"`
	// PostgresToSqlserverConfig: Configuration for heterogeneous failback
	// migrations from **PostgreSQL to SQL Server**.
	PostgresToSqlserverConfig *PostgresToSqlServerConfig `json:"postgresToSqlserverConfig,omitempty"`
	// Purpose: Output only. Migration job mode. Migration jobs can be standard
	// forward jobs or failback migration jobs.
	//
	// Possible values:
	//   "PURPOSE_UNSPECIFIED" - Unknown purpose. Will be defaulted to MIGRATE.
	//   "MIGRATE" - Standard migration job.
	//   "FAILBACK" - Failback replication job.
	Purpose string `json:"purpose,omitempty"`
	// ReverseSshConnectivity: The details needed to communicate to the source over
	// Reverse SSH tunnel connectivity.
	ReverseSshConnectivity *ReverseSshConnectivity `json:"reverseSshConnectivity,omitempty"`
	// SatisfiesPzi: Output only. Reserved for future use.
	SatisfiesPzi bool `json:"satisfiesPzi,omitempty"`
	// SatisfiesPzs: Output only. Reserved for future use.
	SatisfiesPzs bool `json:"satisfiesPzs,omitempty"`
	// Source: Required. The resource name (URI) of the source connection profile.
	Source string `json:"source,omitempty"`
	// SourceDatabase: The database engine type and provider of the source.
	SourceDatabase *DatabaseType `json:"sourceDatabase,omitempty"`
	// SqlserverHomogeneousMigrationJobConfig: Optional. Configuration for SQL
	// Server homogeneous migration.
	SqlserverHomogeneousMigrationJobConfig *SqlServerHomogeneousMigrationJobConfig `json:"sqlserverHomogeneousMigrationJobConfig,omitempty"`
	// SqlserverToPostgresConfig: Configuration for heterogeneous **SQL Server to
	// Cloud SQL for PostgreSQL** migrations.
	SqlserverToPostgresConfig *SqlServerToPostgresConfig `json:"sqlserverToPostgresConfig,omitempty"`
	// State: The current migration job state.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - The state of the migration job is unknown.
	//   "MAINTENANCE" - The migration job is down for maintenance.
	//   "DRAFT" - The migration job is in draft mode and no resources are created.
	//   "CREATING" - The migration job is being created.
	//   "NOT_STARTED" - The migration job is created and not started.
	//   "RUNNING" - The migration job is running.
	//   "FAILED" - The migration job failed.
	//   "COMPLETED" - The migration job has been completed.
	//   "DELETING" - The migration job is being deleted.
	//   "STOPPING" - The migration job is being stopped.
	//   "STOPPED" - The migration job is currently stopped.
	//   "DELETED" - The migration job has been deleted.
	//   "UPDATING" - The migration job is being updated.
	//   "STARTING" - The migration job is starting.
	//   "RESTARTING" - The migration job is restarting.
	//   "RESUMING" - The migration job is resuming.
	State string `json:"state,omitempty"`
	// StaticIpConnectivity: static ip connectivity data (default, no additional
	// details needed).
	StaticIpConnectivity *StaticIpConnectivity `json:"staticIpConnectivity,omitempty"`
	// Type: Required. The migration job type.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The type of the migration job is unknown.
	//   "ONE_TIME" - The migration job is a one time migration.
	//   "CONTINUOUS" - The migration job is a continuous migration.
	Type string `json:"type,omitempty"`
	// UpdateTime: Output only. The timestamp when the migration job resource was
	// last updated. A timestamp in RFC3339 UTC "Zulu" format, accurate to
	// nanoseconds. Example: "2014-10-02T15:01:23.045123456Z".
	UpdateTime string `json:"updateTime,omitempty"`
	// VpcPeeringConnectivity: The details of the VPC network that the source
	// database is located in.
	VpcPeeringConnectivity *VpcPeeringConnectivity `json:"vpcPeeringConnectivity,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "CmekKeyName") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CmekKeyName") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MigrationJob) MarshalJSON() ([]byte, error) {
	type NoMethod MigrationJob
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MigrationJobObject: A specific Migration Job Object (e.g. a specifc DB
// Table)
type MigrationJobObject struct {
	// CreateTime: Output only. The creation time of the migration job object.
	CreateTime string `json:"createTime,omitempty"`
	// Error: Output only. The error details in case of failure.
	Error *Status `json:"error,omitempty"`
	// HeterogeneousMetadata: Output only. Metadata for heterogeneous migration
	// jobs objects.
	HeterogeneousMetadata *HeterogeneousMetadata `json:"heterogeneousMetadata,omitempty"`
	// Name: The object's name.
	Name string `json:"name,omitempty"`
	// Phase: Output only. The phase of the migration job object.
	//
	// Possible values:
	//   "PHASE_UNSPECIFIED" - The phase of the migration job is unknown.
	//   "FULL_DUMP" - The migration job object is in the full dump phase.
	//   "CDC" - The migration job object is in CDC phase.
	//   "READY_FOR_PROMOTE" - The migration job object is ready to be promoted.
	//   "PROMOTE_IN_PROGRESS" - The migration job object is in running the promote
	// phase.
	//   "PROMOTED" - The migration job is promoted.
	//   "DIFF_BACKUP" - The migration job object is in the differential backup
	// phase.
	//   "CREATING_BACKUP" - The migration job object is creating a fully managed
	// backup of the source.
	//   "RESTORING_BACKUP" - The migration job object is restoring a fully managed
	// backup to the destination.
	Phase string `json:"phase,omitempty"`
	// SourceObject: The object identifier in the data source.
	SourceObject *SourceObjectIdentifier `json:"sourceObject,omitempty"`
	// State: The state of the migration job object.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - The state of the migration job object is unknown.
	//   "NOT_STARTED" - The migration job object is not started.
	//   "RUNNING" - The migration job object is running.
	//   "STOPPING" - The migration job object is being stopped.
	//   "STOPPED" - The migration job object is currently stopped.
	//   "RESTARTING" - The migration job object is restarting.
	//   "FAILED" - The migration job object failed.
	//   "REMOVING" - The migration job object is deleting.
	//   "NOT_SELECTED" - The migration job object is not selected for migration.
	//   "COMPLETED" - The migration job object is completed.
	State string `json:"state,omitempty"`
	// UpdateTime: Output only. The last update time of the migration job object.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MigrationJobObject) MarshalJSON() ([]byte, error) {
	type NoMethod MigrationJobObject
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MigrationJobObjectsConfig: Configuration for the objects to be migrated.
type MigrationJobObjectsConfig struct {
	// SourceObjectsConfig: The list of the migration job objects.
	SourceObjectsConfig *SourceObjectsConfig `json:"sourceObjectsConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "SourceObjectsConfig") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "SourceObjectsConfig") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MigrationJobObjectsConfig) MarshalJSON() ([]byte, error) {
	type NoMethod MigrationJobObjectsConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MigrationJobVerificationError: Error message of a verification Migration
// job.
type MigrationJobVerificationError struct {
	// ErrorCode: Output only. An instance of ErrorCode specifying the error that
	// occurred.
	//
	// Possible values:
	//   "ERROR_CODE_UNSPECIFIED" - An unknown error occurred
	//   "CONNECTION_FAILURE" - We failed to connect to one of the connection
	// profile.
	//   "AUTHENTICATION_FAILURE" - We failed to authenticate to one of the
	// connection profile.
	//   "INVALID_CONNECTION_PROFILE_CONFIG" - One of the involved connection
	// profiles has an invalid configuration.
	//   "VERSION_INCOMPATIBILITY" - The versions of the source and the destination
	// are incompatible.
	//   "CONNECTION_PROFILE_TYPES_INCOMPATIBILITY" - The types of the source and
	// the destination are incompatible.
	//   "NO_PGLOGICAL_INSTALLED" - No pglogical extension installed on databases,
	// applicable for postgres.
	//   "PGLOGICAL_NODE_ALREADY_EXISTS" - pglogical node already exists on
	// databases, applicable for postgres.
	//   "INVALID_WAL_LEVEL" - The value of parameter wal_level is not set to
	// logical.
	//   "INVALID_SHARED_PRELOAD_LIBRARY" - The value of parameter
	// shared_preload_libraries does not include pglogical.
	//   "INSUFFICIENT_MAX_REPLICATION_SLOTS" - The value of parameter
	// max_replication_slots is not sufficient.
	//   "INSUFFICIENT_MAX_WAL_SENDERS" - The value of parameter max_wal_senders is
	// not sufficient.
	//   "INSUFFICIENT_MAX_WORKER_PROCESSES" - The value of parameter
	// max_worker_processes is not sufficient.
	//   "UNSUPPORTED_EXTENSIONS" - Extensions installed are either not supported
	// or having unsupported versions.
	//   "UNSUPPORTED_MIGRATION_TYPE" - Unsupported migration type.
	//   "INVALID_RDS_LOGICAL_REPLICATION" - Invalid RDS logical replication.
	//   "UNSUPPORTED_GTID_MODE" - The gtid_mode is not supported, applicable for
	// MySQL.
	//   "UNSUPPORTED_TABLE_DEFINITION" - The table definition is not support due
	// to missing primary key or replica identity.
	//   "UNSUPPORTED_DEFINER" - The definer is not supported.
	//   "CANT_RESTART_RUNNING_MIGRATION" - Migration is already running at the
	// time of restart request.
	//   "SOURCE_ALREADY_SETUP" - The source already has a replication setup.
	//   "TABLES_WITH_LIMITED_SUPPORT" - The source has tables with limited
	// support. E.g. PostgreSQL tables without primary keys.
	//   "UNSUPPORTED_DATABASE_LOCALE" - The source uses an unsupported locale.
	//   "UNSUPPORTED_DATABASE_FDW_CONFIG" - The source uses an unsupported Foreign
	// Data Wrapper configuration.
	//   "ERROR_RDBMS" - There was an underlying RDBMS error.
	//   "SOURCE_SIZE_EXCEEDS_THRESHOLD" - The source DB size in Bytes exceeds a
	// certain threshold. The migration might require an increase of quota, or
	// might not be supported.
	//   "EXISTING_CONFLICTING_DATABASES" - The destination DB contains existing
	// databases that are conflicting with those in the source DB.
	//   "PARALLEL_IMPORT_INSUFFICIENT_PRIVILEGE" - Insufficient privilege to
	// enable the parallelism configuration.
	//   "EXISTING_DATA" - The destination instance contains existing data or user
	// defined entities (for example databases, tables, or functions). You can only
	// migrate to empty instances. Clear your destination instance and retry the
	// migration job.
	//   "SOURCE_MAX_SUBSCRIPTIONS" - The migration job is configured to use max
	// number of subscriptions to migrate data from the source to the destination.
	ErrorCode string `json:"errorCode,omitempty"`
	// ErrorDetailMessage: Output only. A specific detailed error message, if
	// supplied by the engine.
	ErrorDetailMessage string `json:"errorDetailMessage,omitempty"`
	// ErrorMessage: Output only. A formatted message with further details about
	// the error and a CTA.
	ErrorMessage string `json:"errorMessage,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MigrationJobVerificationError) MarshalJSON() ([]byte, error) {
	type NoMethod MigrationJobVerificationError
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MultiColumnDatatypeChange: Options to configure rule type
// MultiColumnDatatypeChange. The rule is used to change the data type and
// associated properties of multiple columns at once. The rule filter field can
// refer to one or more entities. The rule scope can be one of:Column. This
// rule requires additional filters to be specified beyond the basic rule
// filter field, which is the source data type, but the rule supports
// additional filtering capabilities such as the minimum and maximum field
// length. All additional filters which are specified are required to be met in
// order for the rule to be applied (logical AND between the fields).
type MultiColumnDatatypeChange struct {
	// CustomFeatures: Optional. Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// NewDataType: Required. New data type.
	NewDataType string `json:"newDataType,omitempty"`
	// OverrideFractionalSecondsPrecision: Optional. Column fractional seconds
	// precision - used only for timestamp based datatypes - if not specified and
	// relevant uses the source column fractional seconds precision.
	OverrideFractionalSecondsPrecision int64 `json:"overrideFractionalSecondsPrecision,omitempty"`
	// OverrideLength: Optional. Column length - e.g. varchar (50) - if not
	// specified and relevant uses the source column length.
	OverrideLength int64 `json:"overrideLength,omitempty,string"`
	// OverridePrecision: Optional. Column precision - when relevant - if not
	// specified and relevant uses the source column precision.
	OverridePrecision int64 `json:"overridePrecision,omitempty"`
	// OverrideScale: Optional. Column scale - when relevant - if not specified and
	// relevant uses the source column scale.
	OverrideScale int64 `json:"overrideScale,omitempty"`
	// SourceDataTypeFilter: Required. Filter on source data type.
	SourceDataTypeFilter string `json:"sourceDataTypeFilter,omitempty"`
	// SourceNumericFilter: Optional. Filter for fixed point number data types such
	// as NUMERIC/NUMBER.
	SourceNumericFilter *SourceNumericFilter `json:"sourceNumericFilter,omitempty"`
	// SourceTextFilter: Optional. Filter for text-based data types like varchar.
	SourceTextFilter *SourceTextFilter `json:"sourceTextFilter,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MultiColumnDatatypeChange) MarshalJSON() ([]byte, error) {
	type NoMethod MultiColumnDatatypeChange
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MultiEntityRename: Options to configure rule type MultiEntityRename. The
// rule is used to rename multiple entities. The rule filter field can refer to
// one or more entities. The rule scope can be one of: Database, Schema, Table,
// Column, Constraint, Index, View, Function, Stored Procedure, Materialized
// View, Sequence, UDT
type MultiEntityRename struct {
	// NewNamePattern: Optional. The pattern used to generate the new entity's
	// name. This pattern must include the characters '{name}', which will be
	// replaced with the name of the original entity. For example, the pattern
	// 't_{name}' for an entity name jobs would be converted to 't_jobs'. If
	// unspecified, the default value for this field is '{name}'
	NewNamePattern string `json:"newNamePattern,omitempty"`
	// SourceNameTransformation: Optional. Additional transformation that can be
	// done on the source entity name before it is being used by the
	// new_name_pattern, for example lower case. If no transformation is desired,
	// use NO_TRANSFORMATION
	//
	// Possible values:
	//   "ENTITY_NAME_TRANSFORMATION_UNSPECIFIED" - Entity name transformation
	// unspecified.
	//   "ENTITY_NAME_TRANSFORMATION_NO_TRANSFORMATION" - No transformation.
	//   "ENTITY_NAME_TRANSFORMATION_LOWER_CASE" - Transform to lower case.
	//   "ENTITY_NAME_TRANSFORMATION_UPPER_CASE" - Transform to upper case.
	//   "ENTITY_NAME_TRANSFORMATION_CAPITALIZED_CASE" - Transform to capitalized
	// case.
	SourceNameTransformation string `json:"sourceNameTransformation,omitempty"`
	// ForceSendFields is a list of field names (e.g. "NewNamePattern") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "NewNamePattern") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MultiEntityRename) MarshalJSON() ([]byte, error) {
	type NoMethod MultiEntityRename
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MySqlConnectionProfile: Specifies connection parameters required
// specifically for MySQL databases.
type MySqlConnectionProfile struct {
	// CloudSqlId: If the source is a Cloud SQL database, use this field to provide
	// the Cloud SQL instance ID of the source.
	CloudSqlId string `json:"cloudSqlId,omitempty"`
	// Host: Required. The IP or hostname of the source MySQL database.
	Host string `json:"host,omitempty"`
	// Password: Required. Input only. The password for the user that Database
	// Migration Service will be using to connect to the database. This field is
	// not returned on request, and the value is encrypted when stored in Database
	// Migration Service.
	Password string `json:"password,omitempty"`
	// PasswordSet: Output only. Indicates If this connection profile password is
	// stored.
	PasswordSet bool `json:"passwordSet,omitempty"`
	// Port: Required. The network port of the source MySQL database.
	Port int64 `json:"port,omitempty"`
	// PrivateConnectivity: Private connectivity.
	PrivateConnectivity *PrivateConnectivity `json:"privateConnectivity,omitempty"`
	// PrivateServiceConnectConnectivity: Private Service Connect connectivity.
	PrivateServiceConnectConnectivity *PrivateServiceConnectConnectivity `json:"privateServiceConnectConnectivity,omitempty"`
	// Ssl: SSL configuration for the destination to connect to the source
	// database.
	Ssl *SslConfig `json:"ssl,omitempty"`
	// StaticServiceIpConnectivity: Static Service IP connectivity.
	StaticServiceIpConnectivity *StaticServiceIpConnectivity `json:"staticServiceIpConnectivity,omitempty"`
	// Username: Required. The username that Database Migration Service will use to
	// connect to the database. The value is encrypted when stored in Database
	// Migration Service.
	Username string `json:"username,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CloudSqlId") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CloudSqlId") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MySqlConnectionProfile) MarshalJSON() ([]byte, error) {
	type NoMethod MySqlConnectionProfile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MySqlHomogeneousConfig: Configuration for MySQL to MySQL migrations.
type MySqlHomogeneousConfig struct {
	// IsPrimaryDestination: Optional. Whether the destination for the migration
	// job is a primary instance.
	IsPrimaryDestination bool `json:"isPrimaryDestination,omitempty"`
	// ForceSendFields is a list of field names (e.g. "IsPrimaryDestination") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "IsPrimaryDestination") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MySqlHomogeneousConfig) MarshalJSON() ([]byte, error) {
	type NoMethod MySqlHomogeneousConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Operation: This resource represents a long-running operation that is the
// result of a network API call.
type Operation struct {
	// Done: If the value is `false`, it means the operation is still in progress.
	// If `true`, the operation is completed, and either `error` or `response` is
	// available.
	Done bool `json:"done,omitempty"`
	// Error: The error result of the operation in case of failure or cancellation.
	Error *Status `json:"error,omitempty"`
	// Metadata: Service-specific metadata associated with the operation. It
	// typically contains progress information and common metadata such as create
	// time. Some services might not provide such metadata. Any method that returns
	// a long-running operation should document the metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`
	// Name: The server-assigned name, which is only unique within the same service
	// that originally returns it. If you use the default HTTP mapping, the `name`
	// should be a resource name ending with `operations/{unique_id}`.
	Name string `json:"name,omitempty"`
	// Response: The normal, successful response of the operation. If the original
	// method returns no data on success, such as `Delete`, the response is
	// `google.protobuf.Empty`. If the original method is standard
	// `Get`/`Create`/`Update`, the response should be the resource. For other
	// methods, the response should have the type `XxxResponse`, where `Xxx` is the
	// original method name. For example, if the original method name is
	// `TakeSnapshot()`, the inferred response type is `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Done") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Done") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// OracleAsmConfig: Configuration for Oracle Automatic Storage Management (ASM)
// connection.
type OracleAsmConfig struct {
	// AsmService: Required. ASM service name for the Oracle ASM connection.
	AsmService string `json:"asmService,omitempty"`
	// Hostname: Required. Hostname for the Oracle ASM connection.
	Hostname string `json:"hostname,omitempty"`
	// Password: Required. Input only. Password for the Oracle ASM connection.
	Password string `json:"password,omitempty"`
	// PasswordSet: Output only. Indicates whether a new password is included in
	// the request.
	PasswordSet bool `json:"passwordSet,omitempty"`
	// Port: Required. Port for the Oracle ASM connection.
	Port int64 `json:"port,omitempty"`
	// Ssl: Optional. SSL configuration for the Oracle connection.
	Ssl *SslConfig `json:"ssl,omitempty"`
	// Username: Required. Username for the Oracle ASM connection.
	Username string `json:"username,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AsmService") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AsmService") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s OracleAsmConfig) MarshalJSON() ([]byte, error) {
	type NoMethod OracleAsmConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// OracleAsmLogFileAccess: Configuration to use Oracle ASM to access the log
// files.
type OracleAsmLogFileAccess struct {
}

// OracleConnectionProfile: Specifies connection parameters required
// specifically for Oracle databases.
type OracleConnectionProfile struct {
	// DatabaseService: Required. Database service for the Oracle connection.
	DatabaseService string `json:"databaseService,omitempty"`
	// ForwardSshConnectivity: Forward SSH tunnel connectivity.
	ForwardSshConnectivity *ForwardSshTunnelConnectivity `json:"forwardSshConnectivity,omitempty"`
	// Host: Required. The IP or hostname of the source Oracle database.
	Host string `json:"host,omitempty"`
	// OracleAsmConfig: Optional. Configuration for Oracle ASM connection.
	OracleAsmConfig *OracleAsmConfig `json:"oracleAsmConfig,omitempty"`
	// Password: Required. Input only. The password for the user that Database
	// Migration Service will be using to connect to the database. This field is
	// not returned on request, and the value is encrypted when stored in Database
	// Migration Service.
	Password string `json:"password,omitempty"`
	// PasswordSet: Output only. Indicates whether a new password is included in
	// the request.
	PasswordSet bool `json:"passwordSet,omitempty"`
	// Port: Required. The network port of the source Oracle database.
	Port int64 `json:"port,omitempty"`
	// PrivateConnectivity: Private connectivity.
	PrivateConnectivity *PrivateConnectivity `json:"privateConnectivity,omitempty"`
	// Ssl: SSL configuration for the connection to the source Oracle database. *
	// Only `SERVER_ONLY` configuration is supported for Oracle SSL. * SSL is
	// supported for Oracle versions 12 and above.
	Ssl *SslConfig `json:"ssl,omitempty"`
	// StaticServiceIpConnectivity: Static Service IP connectivity.
	StaticServiceIpConnectivity *StaticServiceIpConnectivity `json:"staticServiceIpConnectivity,omitempty"`
	// Username: Required. The username that Database Migration Service will use to
	// connect to the database. The value is encrypted when stored in Database
	// Migration Service.
	Username string `json:"username,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DatabaseService") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DatabaseService") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s OracleConnectionProfile) MarshalJSON() ([]byte, error) {
	type NoMethod OracleConnectionProfile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// OracleSourceConfig: Configuration for Oracle as a source in a migration.
type OracleSourceConfig struct {
	// BinaryLogParser: Use Binary Log Parser.
	BinaryLogParser *BinaryLogParser `json:"binaryLogParser,omitempty"`
	// CdcStartPosition: Optional. The schema change number (SCN) to start CDC data
	// migration from.
	CdcStartPosition int64 `json:"cdcStartPosition,omitempty,string"`
	// LogMiner: Use LogMiner.
	LogMiner *LogMiner `json:"logMiner,omitempty"`
	// MaxConcurrentCdcConnections: Optional. Maximum number of connections
	// Database Migration Service will open to the source for CDC phase.
	MaxConcurrentCdcConnections int64 `json:"maxConcurrentCdcConnections,omitempty"`
	// MaxConcurrentFullDumpConnections: Optional. Maximum number of connections
	// Database Migration Service will open to the source for full dump phase.
	MaxConcurrentFullDumpConnections int64 `json:"maxConcurrentFullDumpConnections,omitempty"`
	// SkipFullDump: Optional. Whether to skip full dump or not.
	SkipFullDump bool `json:"skipFullDump,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BinaryLogParser") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BinaryLogParser") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s OracleSourceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod OracleSourceConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// OracleToPostgresConfig: Configuration for heterogeneous **Oracle to Cloud
// SQL for PostgreSQL** and **Oracle to AlloyDB for PostgreSQL** migrations.
type OracleToPostgresConfig struct {
	// OracleSourceConfig: Optional. Configuration for Oracle source.
	OracleSourceConfig *OracleSourceConfig `json:"oracleSourceConfig,omitempty"`
	// PostgresDestinationConfig: Optional. Configuration for Postgres destination.
	PostgresDestinationConfig *PostgresDestinationConfig `json:"postgresDestinationConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "OracleSourceConfig") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "OracleSourceConfig") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s OracleToPostgresConfig) MarshalJSON() ([]byte, error) {
	type NoMethod OracleToPostgresConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PackageEntity: Package's parent is a schema.
type PackageEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// PackageBody: The SQL code which creates the package body. If the package
	// specification has cursors or subprograms, then the package body is
	// mandatory.
	PackageBody string `json:"packageBody,omitempty"`
	// PackageSqlCode: The SQL code which creates the package.
	PackageSqlCode string `json:"packageSqlCode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PackageEntity) MarshalJSON() ([]byte, error) {
	type NoMethod PackageEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PerformanceConfig: Performance configuration definition.
type PerformanceConfig struct {
	// DumpParallelLevel: Initial dump parallelism level.
	//
	// Possible values:
	//   "DUMP_PARALLEL_LEVEL_UNSPECIFIED" - Unknown dump parallel level. Will be
	// defaulted to OPTIMAL.
	//   "MIN" - Minimal parallel level.
	//   "OPTIMAL" - Optimal parallel level.
	//   "MAX" - Maximum parallel level.
	DumpParallelLevel string `json:"dumpParallelLevel,omitempty"`
	// LoadParallelLevel: Optional. Initial load parallelism level.
	//
	// Possible values:
	//   "LOAD_PARALLEL_LEVEL_UNSPECIFIED" - Unknown load parallel level.
	//   "LOAD_MIN" - Minimal parallel level.
	//   "LOAD_OPTIMAL" - Optimal parallel level.
	//   "LOAD_MAX" - Maximum parallel level.
	LoadParallelLevel string `json:"loadParallelLevel,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DumpParallelLevel") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DumpParallelLevel") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PerformanceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod PerformanceConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Policy: An Identity and Access Management (IAM) policy, which specifies
// access controls for Google Cloud resources. A `Policy` is a collection of
// `bindings`. A `binding` binds one or more `members`, or principals, to a
// single `role`. Principals can be user accounts, service accounts, Google
// groups, and domains (such as G Suite). A `role` is a named list of
// permissions; each `role` can be an IAM predefined role or a user-created
// custom role. For some types of Google Cloud resources, a `binding` can also
// specify a `condition`, which is a logical expression that allows access to a
// resource only if the expression evaluates to `true`. A condition can add
// constraints based on attributes of the request, the resource, or both. To
// learn which resources support conditions in their IAM policies, see the IAM
// documentation
// (https://cloud.google.com/iam/help/conditions/resource-policies). **JSON
// example:** ``` { "bindings": [ { "role":
// "roles/resourcemanager.organizationAdmin", "members": [
// "user:mike@example.com", "group:admins@example.com", "domain:google.com",
// "serviceAccount:my-project-id@appspot.gserviceaccount.com" ] }, { "role":
// "roles/resourcemanager.organizationViewer", "members": [
// "user:eve@example.com" ], "condition": { "title": "expirable access",
// "description": "Does not grant access after Sep 2020", "expression":
// "request.time < timestamp('2020-10-01T00:00:00.000Z')", } } ], "etag":
// "BwWWja0YfJA=", "version": 3 } ``` **YAML example:** ``` bindings: -
// members: - user:mike@example.com - group:admins@example.com -
// domain:google.com - serviceAccount:my-project-id@appspot.gserviceaccount.com
// role: roles/resourcemanager.organizationAdmin - members: -
// user:eve@example.com role: roles/resourcemanager.organizationViewer
// condition: title: expirable access description: Does not grant access after
// Sep 2020 expression: request.time < timestamp('2020-10-01T00:00:00.000Z')
// etag: BwWWja0YfJA= version: 3 ``` For a description of IAM and its features,
// see the IAM documentation (https://cloud.google.com/iam/docs/).
type Policy struct {
	// AuditConfigs: Specifies cloud audit logging configuration for this policy.
	AuditConfigs []*AuditConfig `json:"auditConfigs,omitempty"`
	// Bindings: Associates a list of `members`, or principals, with a `role`.
	// Optionally, may specify a `condition` that determines how and when the
	// `bindings` are applied. Each of the `bindings` must contain at least one
	// principal. The `bindings` in a `Policy` can refer to up to 1,500 principals;
	// up to 250 of these principals can be Google groups. Each occurrence of a
	// principal counts towards these limits. For example, if the `bindings` grant
	// 50 different roles to `user:alice@example.com`, and not to any other
	// principal, then you can add another 1,450 principals to the `bindings` in
	// the `Policy`.
	Bindings []*Binding `json:"bindings,omitempty"`
	// Etag: `etag` is used for optimistic concurrency control as a way to help
	// prevent simultaneous updates of a policy from overwriting each other. It is
	// strongly suggested that systems make use of the `etag` in the
	// read-modify-write cycle to perform policy updates in order to avoid race
	// conditions: An `etag` is returned in the response to `getIamPolicy`, and
	// systems are expected to put that etag in the request to `setIamPolicy` to
	// ensure that their change will be applied to the same version of the policy.
	// **Important:** If you use IAM Conditions, you must include the `etag` field
	// whenever you call `setIamPolicy`. If you omit this field, then IAM allows
	// you to overwrite a version `3` policy with a version `1` policy, and all of
	// the conditions in the version `3` policy are lost.
	Etag string `json:"etag,omitempty"`
	// Version: Specifies the format of the policy. Valid values are `0`, `1`, and
	// `3`. Requests that specify an invalid value are rejected. Any operation that
	// affects conditional role bindings must specify version `3`. This requirement
	// applies to the following operations: * Getting a policy that includes a
	// conditional role binding * Adding a conditional role binding to a policy *
	// Changing a conditional role binding in a policy * Removing any role binding,
	// with or without a condition, from a policy that includes conditions
	// **Important:** If you use IAM Conditions, you must include the `etag` field
	// whenever you call `setIamPolicy`. If you omit this field, then IAM allows
	// you to overwrite a version `3` policy with a version `1` policy, and all of
	// the conditions in the version `3` policy are lost. If a policy does not
	// include any conditions, operations on that policy may specify any valid
	// version or leave the field unset. To learn which resources support
	// conditions in their IAM policies, see the IAM documentation
	// (https://cloud.google.com/iam/help/conditions/resource-policies).
	Version int64 `json:"version,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "AuditConfigs") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AuditConfigs") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

// Position: Issue position.
type Position struct {
	// Column: Issue column number
	Column int64 `json:"column,omitempty"`
	// Length: Issue length
	Length int64 `json:"length,omitempty"`
	// Line: Issue line number
	Line int64 `json:"line,omitempty"`
	// Offset: Issue offset
	Offset int64 `json:"offset,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Column") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Column") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Position) MarshalJSON() ([]byte, error) {
	type NoMethod Position
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PostgreSqlConnectionProfile: Specifies connection parameters required
// specifically for PostgreSQL databases.
type PostgreSqlConnectionProfile struct {
	// AlloydbClusterId: Optional. If the destination is an AlloyDB database, use
	// this field to provide the AlloyDB cluster ID.
	AlloydbClusterId string `json:"alloydbClusterId,omitempty"`
	// CloudSqlId: If the source is a Cloud SQL database, use this field to provide
	// the Cloud SQL instance ID of the source.
	CloudSqlId string `json:"cloudSqlId,omitempty"`
	// Database: Optional. The name of the specific database within the host.
	Database string `json:"database,omitempty"`
	// EnableIamAuthentication: Optional. If true, Database Migration Service will
	// use IAM database authentication to connect to the database.
	EnableIamAuthentication bool `json:"enableIamAuthentication,omitempty"`
	// ForwardSshConnectivity: Forward SSH tunnel connectivity.
	ForwardSshConnectivity *ForwardSshTunnelConnectivity `json:"forwardSshConnectivity,omitempty"`
	// Host: Required. The IP or hostname of the source PostgreSQL database.
	Host string `json:"host,omitempty"`
	// NetworkArchitecture: Output only. If the source is a Cloud SQL database,
	// this field indicates the network architecture it's associated with.
	//
	// Possible values:
	//   "NETWORK_ARCHITECTURE_UNSPECIFIED"
	//   "NETWORK_ARCHITECTURE_OLD_CSQL_PRODUCER" - Instance is in Cloud SQL's old
	// producer network architecture.
	//   "NETWORK_ARCHITECTURE_NEW_CSQL_PRODUCER" - Instance is in Cloud SQL's new
	// producer network architecture.
	NetworkArchitecture string `json:"networkArchitecture,omitempty"`
	// Password: Required. Input only. The password for the user that Database
	// Migration Service will be using to connect to the database. This field is
	// not returned on request, and the value is encrypted when stored in Database
	// Migration Service.
	Password string `json:"password,omitempty"`
	// PasswordSet: Output only. Indicates If this connection profile password is
	// stored.
	PasswordSet bool `json:"passwordSet,omitempty"`
	// Port: Required. The network port of the source PostgreSQL database.
	Port int64 `json:"port,omitempty"`
	// PrivateConnectivity: Private connectivity.
	PrivateConnectivity *PrivateConnectivity `json:"privateConnectivity,omitempty"`
	// PrivateServiceConnectConnectivity: Private Service Connect connectivity.
	PrivateServiceConnectConnectivity *PrivateServiceConnectConnectivity `json:"privateServiceConnectConnectivity,omitempty"`
	// Ssl: SSL configuration for the destination to connect to the source
	// database.
	Ssl *SslConfig `json:"ssl,omitempty"`
	// StaticIpConnectivity: Static ip connectivity data (default, no additional
	// details needed).
	StaticIpConnectivity *StaticIpConnectivity `json:"staticIpConnectivity,omitempty"`
	// Username: Required. The username that Database Migration Service will use to
	// connect to the database. The value is encrypted when stored in Database
	// Migration Service.
	Username string `json:"username,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AlloydbClusterId") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AlloydbClusterId") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PostgreSqlConnectionProfile) MarshalJSON() ([]byte, error) {
	type NoMethod PostgreSqlConnectionProfile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PostgresDestinationConfig: Configuration for Postgres as a destination in a
// migration.
type PostgresDestinationConfig struct {
	// MaxConcurrentConnections: Optional. Maximum number of connections Database
	// Migration Service will open to the destination for data migration.
	MaxConcurrentConnections int64 `json:"maxConcurrentConnections,omitempty"`
	// TransactionTimeout: Optional. Timeout for data migration transactions.
	TransactionTimeout string `json:"transactionTimeout,omitempty"`
	// ForceSendFields is a list of field names (e.g. "MaxConcurrentConnections")
	// to unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "MaxConcurrentConnections") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PostgresDestinationConfig) MarshalJSON() ([]byte, error) {
	type NoMethod PostgresDestinationConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PostgresHomogeneousConfig: Configuration for PostgreSQL to PostgreSQL
// migrations.
type PostgresHomogeneousConfig struct {
	// IsNativeLogical: Required. Whether the migration is native logical.
	IsNativeLogical bool `json:"isNativeLogical,omitempty"`
	// MaxAdditionalSubscriptions: Optional. Maximum number of additional
	// subscriptions to use for the migration job.
	MaxAdditionalSubscriptions int64 `json:"maxAdditionalSubscriptions,omitempty"`
	// ForceSendFields is a list of field names (e.g. "IsNativeLogical") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "IsNativeLogical") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PostgresHomogeneousConfig) MarshalJSON() ([]byte, error) {
	type NoMethod PostgresHomogeneousConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PostgresSourceConfig: Configuration for Postgres as a source in a migration.
type PostgresSourceConfig struct {
	// SkipFullDump: Optional. Whether to skip full dump or not.
	SkipFullDump bool `json:"skipFullDump,omitempty"`
	// ForceSendFields is a list of field names (e.g. "SkipFullDump") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "SkipFullDump") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PostgresSourceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod PostgresSourceConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PostgresToSqlServerConfig: Configuration for heterogeneous failback
// migrations from **PostgreSQL to SQL Server**.
type PostgresToSqlServerConfig struct {
	// PostgresSourceConfig: Optional. Configuration for PostgreSQL source.
	PostgresSourceConfig *PostgresSourceConfig `json:"postgresSourceConfig,omitempty"`
	// SqlserverDestinationConfig: Optional. Configuration for SQL Server
	// destination.
	SqlserverDestinationConfig *SqlServerDestinationConfig `json:"sqlserverDestinationConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PostgresSourceConfig") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "PostgresSourceConfig") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PostgresToSqlServerConfig) MarshalJSON() ([]byte, error) {
	type NoMethod PostgresToSqlServerConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PreconditionFailure: Describes what preconditions have failed. For example,
// if an RPC failed because it required the Terms of Service to be
// acknowledged, it could list the terms of service violation in the
// PreconditionFailure message.
type PreconditionFailure struct {
	// Violations: Describes all precondition violations.
	Violations []*PreconditionFailureViolation `json:"violations,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Violations") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Violations") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PreconditionFailure) MarshalJSON() ([]byte, error) {
	type NoMethod PreconditionFailure
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PreconditionFailureViolation: A message type used to describe a single
// precondition failure.
type PreconditionFailureViolation struct {
	// Description: A description of how the precondition failed. Developers can
	// use this description to understand how to fix the failure. For example:
	// "Terms of service not accepted".
	Description string `json:"description,omitempty"`
	// Subject: The subject, relative to the type, that failed. For example,
	// "google.com/cloud" relative to the "TOS" type would indicate which terms of
	// service is being referenced.
	Subject string `json:"subject,omitempty"`
	// Type: The type of PreconditionFailure. We recommend using a service-specific
	// enum type to define the supported precondition violation subjects. For
	// example, "TOS" for "Terms of Service violation".
	Type string `json:"type,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PreconditionFailureViolation) MarshalJSON() ([]byte, error) {
	type NoMethod PreconditionFailureViolation
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PrimaryInstanceSettings: Settings for the cluster's primary instance
type PrimaryInstanceSettings struct {
	// DatabaseFlags: Database flags to pass to AlloyDB when DMS is creating the
	// AlloyDB cluster and instances. See the AlloyDB documentation for how these
	// can be used.
	DatabaseFlags map[string]string `json:"databaseFlags,omitempty"`
	// Id: Required. The ID of the AlloyDB primary instance. The ID must satisfy
	// the regex expression "[a-z0-9-]+".
	Id string `json:"id,omitempty"`
	// InstanceNetworkConfig: Optional. Metadata related to instance level network
	// configuration.
	InstanceNetworkConfig *InstanceNetworkConfig `json:"instanceNetworkConfig,omitempty"`
	// Labels: Labels for the AlloyDB primary instance created by DMS. An object
	// containing a list of 'key', 'value' pairs.
	Labels map[string]string `json:"labels,omitempty"`
	// MachineConfig: Configuration for the machines that host the underlying
	// database engine.
	MachineConfig *MachineConfig `json:"machineConfig,omitempty"`
	// OutboundPublicIpAddresses: Output only. All outbound public IP addresses
	// configured for the instance.
	OutboundPublicIpAddresses []string `json:"outboundPublicIpAddresses,omitempty"`
	// PrivateIp: Output only. The private IP address for the Instance. This is the
	// connection endpoint for an end-user application.
	PrivateIp string `json:"privateIp,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DatabaseFlags") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DatabaseFlags") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PrimaryInstanceSettings) MarshalJSON() ([]byte, error) {
	type NoMethod PrimaryInstanceSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PrivateConnection: The PrivateConnection resource is used to establish
// private connectivity with the customer's network.
type PrivateConnection struct {
	// CreateTime: Output only. The create time of the resource.
	CreateTime string `json:"createTime,omitempty"`
	// DisplayName: The private connection display name.
	DisplayName string `json:"displayName,omitempty"`
	// Error: Output only. The error details in case of state FAILED.
	Error *Status `json:"error,omitempty"`
	// Labels: The resource labels for private connections to use to annotate any
	// related underlying resources such as Compute Engine VMs. An object
	// containing a list of "key": "value" pairs. Example: `{ "name": "wrench",
	// "mass": "1.3kg", "count": "3" }`.
	Labels map[string]string `json:"labels,omitempty"`
	// Name: The name of the resource.
	Name string `json:"name,omitempty"`
	// PscInterfaceConfig: PSC Interface configuration.
	PscInterfaceConfig *PscInterfaceConfig `json:"pscInterfaceConfig,omitempty"`
	// ReservedPublicIpConfig: Reserved Public IP configuration.
	ReservedPublicIpConfig *ReservedPublicIpConfig `json:"reservedPublicIpConfig,omitempty"`
	// SatisfiesPzi: Output only. Reserved for future use.
	SatisfiesPzi bool `json:"satisfiesPzi,omitempty"`
	// SatisfiesPzs: Output only. Reserved for future use.
	SatisfiesPzs bool `json:"satisfiesPzs,omitempty"`
	// State: Output only. The state of the private connection.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED"
	//   "CREATING" - The private connection is in creation state - creating
	// resources.
	//   "CREATED" - The private connection has been created with all of its
	// resources.
	//   "FAILED" - The private connection creation has failed.
	//   "DELETING" - The private connection is being deleted.
	//   "FAILED_TO_DELETE" - Delete request has failed, resource is in invalid
	// state.
	//   "DELETED" - The private connection has been deleted.
	State string `json:"state,omitempty"`
	// UpdateTime: Output only. The last update time of the resource.
	UpdateTime string `json:"updateTime,omitempty"`
	// VpcPeeringConfig: VPC peering configuration.
	VpcPeeringConfig *VpcPeeringConfig `json:"vpcPeeringConfig,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PrivateConnection) MarshalJSON() ([]byte, error) {
	type NoMethod PrivateConnection
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PrivateConnectivity: Private Connectivity.
type PrivateConnectivity struct {
	// PrivateConnection: Required. The resource name (URI) of the private
	// connection.
	PrivateConnection string `json:"privateConnection,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PrivateConnection") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "PrivateConnection") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PrivateConnectivity) MarshalJSON() ([]byte, error) {
	type NoMethod PrivateConnectivity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PrivateServiceConnectConnectivity: Private Service Connect connectivity
// (https://cloud.google.com/vpc/docs/private-service-connect#service-attachments)
type PrivateServiceConnectConnectivity struct {
	// ServiceAttachment: Required. A service attachment that exposes a database,
	// and has the following format:
	// projects/{project}/regions/{region}/serviceAttachments/{service_attachment_na
	// me}
	ServiceAttachment string `json:"serviceAttachment,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ServiceAttachment") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ServiceAttachment") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PrivateServiceConnectConnectivity) MarshalJSON() ([]byte, error) {
	type NoMethod PrivateServiceConnectConnectivity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PromoteMigrationJobRequest: Request message for 'PromoteMigrationJob'
// request.
type PromoteMigrationJobRequest struct {
	// ObjectsFilter: Optional. The object filter to apply to the migration job.
	ObjectsFilter *MigrationJobObjectsConfig `json:"objectsFilter,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ObjectsFilter") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ObjectsFilter") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PromoteMigrationJobRequest) MarshalJSON() ([]byte, error) {
	type NoMethod PromoteMigrationJobRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PscInterfaceConfig: The PSC Interface configuration is used to create PSC
// Interface between DMS's internal VPC and the consumer's PSC.
type PscInterfaceConfig struct {
	// NetworkAttachment: Required. Fully qualified name of the Network Attachment
	// that DMS will connect to. Format:
	// `projects/{{project}}/regions/{{region}}/networkAttachments/{{name}}`
	NetworkAttachment string `json:"networkAttachment,omitempty"`
	// ForceSendFields is a list of field names (e.g. "NetworkAttachment") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "NetworkAttachment") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PscInterfaceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod PscInterfaceConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// QuotaFailure: Describes how a quota check failed. For example if a daily
// limit was exceeded for the calling project, a service could respond with a
// QuotaFailure detail containing the project id and the description of the
// quota limit that was exceeded. If the calling project hasn't enabled the
// service in the developer console, then a service could respond with the
// project id and set `service_disabled` to true. Also see RetryInfo and Help
// types for other details about handling a quota failure.
type QuotaFailure struct {
	// Violations: Describes all quota violations.
	Violations []*QuotaFailureViolation `json:"violations,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Violations") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Violations") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s QuotaFailure) MarshalJSON() ([]byte, error) {
	type NoMethod QuotaFailure
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// QuotaFailureViolation: A message type used to describe a single quota
// violation. For example, a daily quota or a custom quota that was exceeded.
type QuotaFailureViolation struct {
	// ApiService: The API Service from which the `QuotaFailure.Violation`
	// originates. In some cases, Quota issues originate from an API Service other
	// than the one that was called. In other words, a dependency of the called API
	// Service could be the cause of the `QuotaFailure`, and this field would have
	// the dependency API service name. For example, if the called API is
	// Kubernetes Engine API (container.googleapis.com), and a quota violation
	// occurs in the Kubernetes Engine API itself, this field would be
	// "container.googleapis.com". On the other hand, if the quota violation occurs
	// when the Kubernetes Engine API creates VMs in the Compute Engine API
	// (compute.googleapis.com), this field would be "compute.googleapis.com".
	ApiService string `json:"apiService,omitempty"`
	// Description: A description of how the quota check failed. Clients can use
	// this description to find more about the quota configuration in the service's
	// public documentation, or find the relevant quota limit to adjust through
	// developer console. For example: "Service disabled" or "Daily Limit for read
	// operations exceeded".
	Description string `json:"description,omitempty"`
	// FutureQuotaValue: The new quota value being rolled out at the time of the
	// violation. At the completion of the rollout, this value will be enforced in
	// place of quota_value. If no rollout is in progress at the time of the
	// violation, this field is not set. For example, if at the time of the
	// violation a rollout is in progress changing the number of CPUs quota from 10
	// to 20, 20 would be the value of this field.
	FutureQuotaValue int64 `json:"futureQuotaValue,omitempty,string"`
	// QuotaDimensions: The dimensions of the violated quota. Every non-global
	// quota is enforced on a set of dimensions. While quota metric defines what to
	// count, the dimensions specify for what aspects the counter should be
	// increased. For example, the quota "CPUs per region per VM family" enforces a
	// limit on the metric "compute.googleapis.com/cpus_per_vm_family" on
	// dimensions "region" and "vm_family". And if the violation occurred in region
	// "us-central1" and for VM family "n1", the quota_dimensions would be, {
	// "region": "us-central1", "vm_family": "n1", } When a quota is enforced
	// globally, the quota_dimensions would always be empty.
	QuotaDimensions map[string]string `json:"quotaDimensions,omitempty"`
	// QuotaId: The id of the violated quota. Also know as "limit name", this is
	// the unique identifier of a quota in the context of an API service. For
	// example, "CPUS-PER-VM-FAMILY-per-project-region".
	QuotaId string `json:"quotaId,omitempty"`
	// QuotaMetric: The metric of the violated quota. A quota metric is a named
	// counter to measure usage, such as API requests or CPUs. When an activity
	// occurs in a service, such as Virtual Machine allocation, one or more quota
	// metrics may be affected. For example,
	// "compute.googleapis.com/cpus_per_vm_family",
	// "storage.googleapis.com/internet_egress_bandwidth".
	QuotaMetric string `json:"quotaMetric,omitempty"`
	// QuotaValue: The enforced quota value at the time of the `QuotaFailure`. For
	// example, if the enforced quota value at the time of the `QuotaFailure` on
	// the number of CPUs is "10", then the value of this field would reflect this
	// quantity.
	QuotaValue int64 `json:"quotaValue,omitempty,string"`
	// Subject: The subject on which the quota check failed. For example,
	// "clientip:" or "project:".
	Subject string `json:"subject,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ApiService") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ApiService") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s QuotaFailureViolation) MarshalJSON() ([]byte, error) {
	type NoMethod QuotaFailureViolation
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RequestInfo: Contains metadata about the request that clients can attach
// when filing a bug or providing other forms of feedback.
type RequestInfo struct {
	// RequestId: An opaque string that should only be interpreted by the service
	// generating it. For example, it can be used to identify requests in the
	// service's logs.
	RequestId string `json:"requestId,omitempty"`
	// ServingData: Any data that was used to serve this request. For example, an
	// encrypted stack trace that can be sent back to the service provider for
	// debugging.
	ServingData string `json:"servingData,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RequestId") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RequestId") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RequestInfo) MarshalJSON() ([]byte, error) {
	type NoMethod RequestInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ReservedPublicIpConfig: Reserved Public IP configuration.
type ReservedPublicIpConfig struct {
	// EgressPublicIps: Output only. The reserved public IPs.
	EgressPublicIps []string `json:"egressPublicIps,omitempty"`
	// NatIpsCount: Optional. Number of static public IP addresses to reserve.
	NatIpsCount int64 `json:"natIpsCount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EgressPublicIps") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EgressPublicIps") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ReservedPublicIpConfig) MarshalJSON() ([]byte, error) {
	type NoMethod ReservedPublicIpConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ResourceInfo: Describes the resource that is being accessed.
type ResourceInfo struct {
	// Description: Describes what error is encountered when accessing this
	// resource. For example, updating a cloud project may require the `writer`
	// permission on the developer console project.
	Description string `json:"description,omitempty"`
	// Owner: The owner of the resource (optional). For example, "user:" or
	// "project:".
	Owner string `json:"owner,omitempty"`
	// ResourceName: The name of the resource being accessed. For example, a shared
	// calendar name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the
	// current error is google.rpc.Code.PERMISSION_DENIED.
	ResourceName string `json:"resourceName,omitempty"`
	// ResourceType: A name for the type of resource being accessed, e.g. "sql
	// table", "cloud storage bucket", "file", "Google calendar"; or the type URL
	// of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic".
	ResourceType string `json:"resourceType,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ResourceInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RestartMigrationJobRequest: Request message for 'RestartMigrationJob'
// request.
type RestartMigrationJobRequest struct {
	// ObjectsFilter: Optional. The object filter to apply to the migration job.
	ObjectsFilter *MigrationJobObjectsConfig `json:"objectsFilter,omitempty"`
	// RestartFailedObjects: Optional. If true, only failed objects will be
	// restarted.
	RestartFailedObjects bool `json:"restartFailedObjects,omitempty"`
	// SkipValidation: Optional. Restart the migration job without running prior
	// configuration verification. Defaults to `false`.
	SkipValidation bool `json:"skipValidation,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ObjectsFilter") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ObjectsFilter") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RestartMigrationJobRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RestartMigrationJobRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ResumeMigrationJobRequest: Request message for 'ResumeMigrationJob' request.
type ResumeMigrationJobRequest struct {
	// SkipValidation: Optional. Resume the migration job without running prior
	// configuration verification. Defaults to `false`.
	SkipValidation bool `json:"skipValidation,omitempty"`
	// ForceSendFields is a list of field names (e.g. "SkipValidation") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "SkipValidation") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ResumeMigrationJobRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ResumeMigrationJobRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RetryInfo: Describes when the clients can retry a failed request. Clients
// could ignore the recommendation here or retry when this information is
// missing from error responses. It's always recommended that clients should
// use exponential backoff when retrying. Clients should wait until
// `retry_delay` amount of time has passed since receiving the error response
// before retrying. If retrying requests also fail, clients should use an
// exponential backoff scheme to gradually increase the delay between retries
// based on `retry_delay`, until either a maximum number of retries have been
// reached or a maximum retry delay cap has been reached.
type RetryInfo struct {
	// RetryDelay: Clients should wait at least this long between retrying the same
	// request.
	RetryDelay string `json:"retryDelay,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RetryDelay") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RetryDelay") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RetryInfo) MarshalJSON() ([]byte, error) {
	type NoMethod RetryInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ReverseSshConnectivity: The details needed to configure a reverse SSH tunnel
// between the source and destination databases. These details will be used
// when calling the generateSshScript method (see
// https://cloud.google.com/database-migration/docs/reference/rest/v1/projects.locations.migrationJobs/generateSshScript)
// to produce the script that will help set up the reverse SSH tunnel, and to
// set up the VPC peering between the Cloud SQL private network and the VPC.
type ReverseSshConnectivity struct {
	// Vm: The name of the virtual machine (Compute Engine) used as the bastion
	// server for the SSH tunnel.
	Vm string `json:"vm,omitempty"`
	// VmIp: Required. The IP of the virtual machine (Compute Engine) used as the
	// bastion server for the SSH tunnel.
	VmIp string `json:"vmIp,omitempty"`
	// VmPort: Required. The forwarding port of the virtual machine (Compute
	// Engine) used as the bastion server for the SSH tunnel.
	VmPort int64 `json:"vmPort,omitempty"`
	// Vpc: The name of the VPC to peer with the Cloud SQL private network.
	Vpc string `json:"vpc,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Vm") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Vm") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ReverseSshConnectivity) MarshalJSON() ([]byte, error) {
	type NoMethod ReverseSshConnectivity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RollbackConversionWorkspaceRequest: Request message for
// 'RollbackConversionWorkspace' request.
type RollbackConversionWorkspaceRequest struct {
}

// RoundToScale: This allows the data to change scale, for example if the
// source is 2 digits after the decimal point, specify round to scale value =
// 2. If for example the value needs to be converted to an integer, use round
// to scale value = 0.
type RoundToScale struct {
	// Scale: Required. Scale value to be used
	Scale int64 `json:"scale,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Scale") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Scale") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RoundToScale) MarshalJSON() ([]byte, error) {
	type NoMethod RoundToScale
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RulesFile: Details of a single rules file.
type RulesFile struct {
	// RulesContent: Required. The text content of the rules that needs to be
	// converted.
	RulesContent string `json:"rulesContent,omitempty"`
	// RulesSourceFilename: Required. The filename of the rules that needs to be
	// converted. The filename is used mainly so that future logs of the import
	// rules job contain it, and can therefore be searched by it.
	RulesSourceFilename string `json:"rulesSourceFilename,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RulesContent") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RulesContent") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RulesFile) MarshalJSON() ([]byte, error) {
	type NoMethod RulesFile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SchemaEntity: Schema typically has no parent entity, but can have a parent
// entity DatabaseInstance (for database engines which support it). For some
// database engines, the terms schema and user can be used interchangeably when
// they refer to a namespace or a collection of other database entities. Can
// store additional information which is schema specific.
type SchemaEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SchemaEntity) MarshalJSON() ([]byte, error) {
	type NoMethod SchemaEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SearchBackgroundJobsResponse: Response message for 'SearchBackgroundJobs'
// request.
type SearchBackgroundJobsResponse struct {
	// Jobs: The list of conversion workspace mapping rules.
	Jobs []*BackgroundJobLogEntry `json:"jobs,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Jobs") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Jobs") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SearchBackgroundJobsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod SearchBackgroundJobsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SeedConversionWorkspaceRequest: Request message for
// 'SeedConversionWorkspace' request.
type SeedConversionWorkspaceRequest struct {
	// AutoCommit: Should the conversion workspace be committed automatically after
	// the seed operation.
	AutoCommit bool `json:"autoCommit,omitempty"`
	// DestinationConnectionProfile: Optional. Fully qualified (Uri) name of the
	// destination connection profile.
	DestinationConnectionProfile string `json:"destinationConnectionProfile,omitempty"`
	// SourceConnectionProfile: Optional. Fully qualified (Uri) name of the source
	// connection profile.
	SourceConnectionProfile string `json:"sourceConnectionProfile,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AutoCommit") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AutoCommit") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SeedConversionWorkspaceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SeedConversionWorkspaceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SeedJobDetails: Details regarding a Seed background job.
type SeedJobDetails struct {
	// ConnectionProfile: Output only. The connection profile which was used for
	// the seed job.
	ConnectionProfile string `json:"connectionProfile,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ConnectionProfile") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ConnectionProfile") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SeedJobDetails) MarshalJSON() ([]byte, error) {
	type NoMethod SeedJobDetails
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SequenceEntity: Sequence's parent is a schema.
type SequenceEntity struct {
	// Cache: Indicates number of entries to cache / precreate.
	Cache int64 `json:"cache,omitempty,string"`
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// Cycle: Indicates whether the sequence value should cycle through.
	Cycle bool `json:"cycle,omitempty"`
	// Increment: Increment value for the sequence.
	Increment int64 `json:"increment,omitempty,string"`
	// MaxValue: Maximum number for the sequence represented as bytes to
	// accommodate large. numbers
	MaxValue string `json:"maxValue,omitempty"`
	// MinValue: Minimum number for the sequence represented as bytes to
	// accommodate large. numbers
	MinValue string `json:"minValue,omitempty"`
	// StartValue: Start number for the sequence represented as bytes to
	// accommodate large. numbers
	StartValue string `json:"startValue,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Cache") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Cache") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SequenceEntity) MarshalJSON() ([]byte, error) {
	type NoMethod SequenceEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SetDraftEntityDdlRequest: Request message for
// DataMigrationService.SetDraftEntityDdl.
type SetDraftEntityDdlRequest struct {
	// BasedOnDdlKind: Optional. Which DDL (Deterministic/AI) the updated DDL is
	// based on. Defaults to DETERMINISTIC if not specified.
	//
	// Possible values:
	//   "DDL_KIND_UNSPECIFIED" - The kind of the DDL is unknown.
	//   "SOURCE" - DDL of the source entity
	//   "DETERMINISTIC" - Deterministic converted DDL
	//   "AI" - Gemini AI converted DDL
	//   "USER_EDIT" - User edited DDL
	BasedOnDdlKind string `json:"basedOnDdlKind,omitempty"`
	// Ddl: Required. The DDL to set.
	Ddl string `json:"ddl,omitempty"`
	// DdlKind: Optional. The updated DDL Kind. Can be either USER_EDIT (default)
	// or AI.
	//
	// Possible values:
	//   "DDL_KIND_UNSPECIFIED" - The kind of the DDL is unknown.
	//   "SOURCE" - DDL of the source entity
	//   "DETERMINISTIC" - Deterministic converted DDL
	//   "AI" - Gemini AI converted DDL
	//   "USER_EDIT" - User edited DDL
	DdlKind string `json:"ddlKind,omitempty"`
	// EntityName: Required. The draft entity full name from the tree. .
	EntityName string `json:"entityName,omitempty"`
	// EntityType: Required. The type of the database entity (table, view, index,
	// ...).
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	EntityType string `json:"entityType,omitempty"`
	// Explanation: Optional. An optional explanation of the generated DDL if
	// ddl_kind is AI.
	Explanation string `json:"explanation,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BasedOnDdlKind") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BasedOnDdlKind") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SetDraftEntityDdlRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SetDraftEntityDdlRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SetDraftEntityDdlResponse: Response message for
// DataMigrationService.SetDraftEntityDdl.
type SetDraftEntityDdlResponse struct {
	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
}

// SetIamPolicyRequest: Request message for `SetIamPolicy` method.
type SetIamPolicyRequest struct {
	// Policy: REQUIRED: The complete policy to be applied to the `resource`. The
	// size of the policy is limited to a few 10s of KB. An empty policy is a valid
	// policy but certain Google Cloud services (such as Projects) might reject
	// them.
	Policy *Policy `json:"policy,omitempty"`
	// UpdateMask: OPTIONAL: A FieldMask specifying which fields of the policy to
	// modify. Only the fields in the mask will be modified. If no mask is
	// provided, the following default mask is used: `paths: "bindings, etag"
	UpdateMask string `json:"updateMask,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Policy") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Policy") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

// SetTablePrimaryKey: Deprecated: Options to configure rule type
// SetTablePrimaryKey. The rule is used to specify the columns and name to
// configure/alter the primary key of a table. The rule filter field can refer
// to one entity. The rule scope can be one of: Table.
type SetTablePrimaryKey struct {
	// PrimaryKey: Optional. Name for the primary key
	PrimaryKey string `json:"primaryKey,omitempty"`
	// PrimaryKeyColumns: Required. List of column names for the primary key
	PrimaryKeyColumns []string `json:"primaryKeyColumns,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PrimaryKey") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "PrimaryKey") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SetTablePrimaryKey) MarshalJSON() ([]byte, error) {
	type NoMethod SetTablePrimaryKey
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SingleColumnChange: Options to configure rule type SingleColumnChange. The
// rule is used to change the properties of a column. The rule filter field can
// refer to one entity. The rule scope can be one of: Column. When using this
// rule, if a field is not specified than the destination column's
// configuration will be the same as the one in the source column..
type SingleColumnChange struct {
	// Array: Optional. Is the column of array type.
	Array bool `json:"array,omitempty"`
	// ArrayLength: Optional. The length of the array, only relevant if the column
	// type is an array.
	ArrayLength int64 `json:"arrayLength,omitempty"`
	// AutoGenerated: Optional. Is the column auto-generated/identity.
	AutoGenerated bool `json:"autoGenerated,omitempty"`
	// Charset: Optional. Charset override - instead of table level charset.
	Charset string `json:"charset,omitempty"`
	// Collation: Optional. Collation override - instead of table level collation.
	Collation string `json:"collation,omitempty"`
	// Comment: Optional. Comment associated with the column.
	Comment string `json:"comment,omitempty"`
	// CustomFeatures: Optional. Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// DataType: Optional. Column data type name.
	DataType string `json:"dataType,omitempty"`
	// FractionalSecondsPrecision: Optional. Column fractional seconds precision -
	// e.g. 2 as in timestamp (2) - when relevant.
	FractionalSecondsPrecision int64 `json:"fractionalSecondsPrecision,omitempty"`
	// Length: Optional. Column length - e.g. 50 as in varchar (50) - when
	// relevant.
	Length int64 `json:"length,omitempty,string"`
	// Nullable: Optional. Is the column nullable.
	Nullable bool `json:"nullable,omitempty"`
	// Precision: Optional. Column precision - e.g. 8 as in double (8,2) - when
	// relevant.
	Precision int64 `json:"precision,omitempty"`
	// Scale: Optional. Column scale - e.g. 2 as in double (8,2) - when relevant.
	Scale int64 `json:"scale,omitempty"`
	// SetValues: Optional. Specifies the list of values allowed in the column.
	SetValues []string `json:"setValues,omitempty"`
	// Udt: Optional. Is the column a UDT (User-defined Type).
	Udt bool `json:"udt,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Array") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Array") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SingleColumnChange) MarshalJSON() ([]byte, error) {
	type NoMethod SingleColumnChange
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SingleEntityRename: Options to configure rule type SingleEntityRename. The
// rule is used to rename an entity. The rule filter field can refer to only
// one entity. The rule scope can be one of: Database, Schema, Table, Column,
// Constraint, Index, View, Function, Stored Procedure, Materialized View,
// Sequence, UDT, Synonym
type SingleEntityRename struct {
	// NewName: Required. The new name of the destination entity
	NewName string `json:"newName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "NewName") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "NewName") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SingleEntityRename) MarshalJSON() ([]byte, error) {
	type NoMethod SingleEntityRename
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SinglePackageChange: Options to configure rule type SinglePackageChange. The
// rule is used to alter the sql code for a package entities. The rule filter
// field can refer to one entity. The rule scope can be: Package
type SinglePackageChange struct {
	// PackageBody: Optional. Sql code for package body
	PackageBody string `json:"packageBody,omitempty"`
	// PackageDescription: Optional. Sql code for package description
	PackageDescription string `json:"packageDescription,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PackageBody") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "PackageBody") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SinglePackageChange) MarshalJSON() ([]byte, error) {
	type NoMethod SinglePackageChange
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SourceNumericFilter: Filter for fixed point number data types such as
// NUMERIC/NUMBER
type SourceNumericFilter struct {
	// NumericFilterOption: Required. Enum to set the option defining the datatypes
	// numeric filter has to be applied to
	//
	// Possible values:
	//   "NUMERIC_FILTER_OPTION_UNSPECIFIED" - Numeric filter option unspecified
	//   "NUMERIC_FILTER_OPTION_ALL" - Numeric filter option that matches all
	// numeric columns.
	//   "NUMERIC_FILTER_OPTION_LIMIT" - Numeric filter option that matches columns
	// having numeric datatypes with specified precision and scale within the
	// limited range of filter.
	//   "NUMERIC_FILTER_OPTION_LIMITLESS" - Numeric filter option that matches
	// only the numeric columns with no precision and scale specified.
	NumericFilterOption string `json:"numericFilterOption,omitempty"`
	// SourceMaxPrecisionFilter: Optional. The filter will match columns with
	// precision smaller than or equal to this number.
	SourceMaxPrecisionFilter int64 `json:"sourceMaxPrecisionFilter,omitempty"`
	// SourceMaxScaleFilter: Optional. The filter will match columns with scale
	// smaller than or equal to this number.
	SourceMaxScaleFilter int64 `json:"sourceMaxScaleFilter,omitempty"`
	// SourceMinPrecisionFilter: Optional. The filter will match columns with
	// precision greater than or equal to this number.
	SourceMinPrecisionFilter int64 `json:"sourceMinPrecisionFilter,omitempty"`
	// SourceMinScaleFilter: Optional. The filter will match columns with scale
	// greater than or equal to this number.
	SourceMinScaleFilter int64 `json:"sourceMinScaleFilter,omitempty"`
	// ForceSendFields is a list of field names (e.g. "NumericFilterOption") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "NumericFilterOption") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SourceNumericFilter) MarshalJSON() ([]byte, error) {
	type NoMethod SourceNumericFilter
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SourceObjectConfig: Config for a single migration job object.
type SourceObjectConfig struct {
	// ObjectIdentifier: Optional. The object identifier.
	ObjectIdentifier *SourceObjectIdentifier `json:"objectIdentifier,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ObjectIdentifier") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ObjectIdentifier") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SourceObjectConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SourceObjectConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SourceObjectIdentifier: An identifier for the Migration Job Object.
type SourceObjectIdentifier struct {
	// Database: Optional. The database name. This will be required only if the
	// object uses a database name as part of its unique identifier.
	Database string `json:"database,omitempty"`
	// Schema: Optional. The schema name. This will be required only if the object
	// uses a schema name as part of its unique identifier.
	Schema string `json:"schema,omitempty"`
	// Table: Optional. The table name. This will be required only if the object is
	// a level below database or schema.
	Table string `json:"table,omitempty"`
	// Type: Required. The type of the migration job object.
	//
	// Possible values:
	//   "MIGRATION_JOB_OBJECT_TYPE_UNSPECIFIED" - The type of the migration job
	// object is unknown.
	//   "DATABASE" - The migration job object is a database.
	//   "SCHEMA" - The migration job object is a schema.
	//   "TABLE" - The migration job object is a table.
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Database") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Database") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SourceObjectIdentifier) MarshalJSON() ([]byte, error) {
	type NoMethod SourceObjectIdentifier
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SourceObjectsConfig: List of configurations for the source objects to be
// migrated.
type SourceObjectsConfig struct {
	// ObjectConfigs: Optional. The list of the objects to be migrated.
	ObjectConfigs []*SourceObjectConfig `json:"objectConfigs,omitempty"`
	// ObjectsSelectionType: Optional. The objects selection type of the migration
	// job.
	//
	// Possible values:
	//   "OBJECTS_SELECTION_TYPE_UNSPECIFIED" - The type of the objects selection
	// is unknown, indicating that the migration job is at instance level.
	//   "ALL_OBJECTS" - Migrate all of the objects.
	//   "SPECIFIED_OBJECTS" - Migrate specific objects.
	ObjectsSelectionType string `json:"objectsSelectionType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ObjectConfigs") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ObjectConfigs") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SourceObjectsConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SourceObjectsConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SourceSqlChange: Options to configure rule type SourceSqlChange. The rule is
// used to alter the sql code for database entities. The rule filter field can
// refer to one entity. The rule scope can be: StoredProcedure, Function,
// Trigger, View
type SourceSqlChange struct {
	// SqlCode: Required. Sql code for source (stored procedure, function, trigger
	// or view)
	SqlCode string `json:"sqlCode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "SqlCode") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "SqlCode") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SourceSqlChange) MarshalJSON() ([]byte, error) {
	type NoMethod SourceSqlChange
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SourceTextFilter: Filter for text-based data types like varchar.
type SourceTextFilter struct {
	// SourceMaxLengthFilter: Optional. The filter will match columns with length
	// smaller than or equal to this number.
	SourceMaxLengthFilter int64 `json:"sourceMaxLengthFilter,omitempty,string"`
	// SourceMinLengthFilter: Optional. The filter will match columns with length
	// greater than or equal to this number.
	SourceMinLengthFilter int64 `json:"sourceMinLengthFilter,omitempty,string"`
	// ForceSendFields is a list of field names (e.g. "SourceMaxLengthFilter") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "SourceMaxLengthFilter") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SourceTextFilter) MarshalJSON() ([]byte, error) {
	type NoMethod SourceTextFilter
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlAclEntry: An entry for an Access Control list.
type SqlAclEntry struct {
	// ExpireTime: The time when this access control entry expires in RFC 3339
	// (https://tools.ietf.org/html/rfc3339) format, for example:
	// `2012-11-15T16:19:00.094Z`.
	ExpireTime string `json:"expireTime,omitempty"`
	// Label: A label to identify this entry.
	Label string `json:"label,omitempty"`
	// Ttl: Input only. The time-to-leave of this access control entry.
	Ttl string `json:"ttl,omitempty"`
	// Value: The allowlisted value for the access control list.
	Value string `json:"value,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlAclEntry) MarshalJSON() ([]byte, error) {
	type NoMethod SqlAclEntry
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlIpConfig: IP Management configuration.
type SqlIpConfig struct {
	// AllocatedIpRange: Optional. The name of the allocated IP address range for
	// the private IP Cloud SQL instance. This name refers to an already allocated
	// IP range address. If set, the instance IP address will be created in the
	// allocated range. Note that this IP address range can't be modified after the
	// instance is created. If you change the VPC when configuring connectivity
	// settings for the migration job, this field is not relevant.
	AllocatedIpRange string `json:"allocatedIpRange,omitempty"`
	// AuthorizedNetworks: The list of external networks that are allowed to
	// connect to the instance using the IP. See
	// https://en.wikipedia.org/wiki/CIDR_notation#CIDR_notation, also known as
	// 'slash' notation (e.g. `192.168.100.0/24`).
	AuthorizedNetworks []*SqlAclEntry `json:"authorizedNetworks,omitempty"`
	// EnableIpv4: Whether the instance should be assigned an IPv4 address or not.
	EnableIpv4 bool `json:"enableIpv4,omitempty"`
	// PrivateNetwork: The resource link for the VPC network from which the Cloud
	// SQL instance is accessible for private IP. For example,
	// `projects/myProject/global/networks/default`. This setting can be updated,
	// but it cannot be removed after it is set.
	PrivateNetwork string `json:"privateNetwork,omitempty"`
	// RequireSsl: Whether SSL connections over IP should be enforced or not.
	RequireSsl bool `json:"requireSsl,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AllocatedIpRange") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AllocatedIpRange") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlIpConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SqlIpConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerBackups: Specifies the backup details in Cloud Storage for
// homogeneous migration to Cloud SQL for SQL Server.
type SqlServerBackups struct {
	// GcsBucket: Required. The Cloud Storage bucket that stores backups for all
	// replicated databases.
	GcsBucket string `json:"gcsBucket,omitempty"`
	// GcsPrefix: Optional. Cloud Storage path inside the bucket that stores
	// backups.
	GcsPrefix string `json:"gcsPrefix,omitempty"`
	// ForceSendFields is a list of field names (e.g. "GcsBucket") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "GcsBucket") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerBackups) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerBackups
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerConnectionProfile: Specifies connection parameters required
// specifically for SQL Server databases.
type SqlServerConnectionProfile struct {
	// Backups: The backup details in Cloud Storage for homogeneous migration to
	// Cloud SQL for SQL Server.
	Backups *SqlServerBackups `json:"backups,omitempty"`
	// CloudSqlId: If the source is a Cloud SQL database, use this field to provide
	// the Cloud SQL instance ID of the source.
	CloudSqlId string `json:"cloudSqlId,omitempty"`
	// CloudSqlProjectId: Optional. The project id of the Cloud SQL instance. If
	// not provided, the project id of the connection profile will be used.
	CloudSqlProjectId string `json:"cloudSqlProjectId,omitempty"`
	// Database: Required. The name of the specific database within the host.
	Database string `json:"database,omitempty"`
	// DbmPort: Optional. The Database Mirroring (DBM) port of the source SQL
	// Server instance.
	DbmPort int64 `json:"dbmPort,omitempty"`
	// ForwardSshConnectivity: Forward SSH tunnel connectivity.
	ForwardSshConnectivity *ForwardSshTunnelConnectivity `json:"forwardSshConnectivity,omitempty"`
	// Host: Required. The IP or hostname of the source SQL Server database.
	Host string `json:"host,omitempty"`
	// Password: Required. Input only. The password for the user that Database
	// Migration Service will be using to connect to the database. This field is
	// not returned on request, and the value is encrypted when stored in Database
	// Migration Service.
	Password string `json:"password,omitempty"`
	// PasswordSet: Output only. Indicates whether a new password is included in
	// the request.
	PasswordSet bool `json:"passwordSet,omitempty"`
	// Port: Required. The network port of the source SQL Server database.
	Port int64 `json:"port,omitempty"`
	// PrivateConnectivity: Private connectivity.
	PrivateConnectivity *PrivateConnectivity `json:"privateConnectivity,omitempty"`
	// PrivateServiceConnectConnectivity: Private Service Connect connectivity.
	PrivateServiceConnectConnectivity *PrivateServiceConnectConnectivity `json:"privateServiceConnectConnectivity,omitempty"`
	// Ssl: SSL configuration for the destination to connect to the source
	// database.
	Ssl *SslConfig `json:"ssl,omitempty"`
	// StaticIpConnectivity: Static IP connectivity data (default, no additional
	// details needed).
	StaticIpConnectivity *StaticIpConnectivity `json:"staticIpConnectivity,omitempty"`
	// Username: Required. The username that Database Migration Service will use to
	// connect to the database. The value is encrypted when stored in Database
	// Migration Service.
	Username string `json:"username,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Backups") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Backups") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerConnectionProfile) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerConnectionProfile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerDagConfig: Configuration for distributed availability group (DAG)
// for the SQL Server homogeneous migration.
type SqlServerDagConfig struct {
	// LinkedServer: Required. The name of the linked server that points to the
	// source SQL Server instance. Only used by DAG migrations.
	LinkedServer string `json:"linkedServer,omitempty"`
	// SourceAg: Required. The name of the source availability group. Only used by
	// DAG migrations.
	SourceAg string `json:"sourceAg,omitempty"`
	// ForceSendFields is a list of field names (e.g. "LinkedServer") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "LinkedServer") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerDagConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerDagConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerDatabaseBackup: Specifies the backup details for a single database
// in Cloud Storage for homogeneous migration to Cloud SQL for SQL Server.
type SqlServerDatabaseBackup struct {
	// Database: Required. Name of a SQL Server database for which to define backup
	// configuration.
	Database string `json:"database,omitempty"`
	// EncryptionOptions: Optional. Encryption settings for the database. Required
	// if provided database backups are encrypted. Encryption settings include path
	// to certificate, path to certificate private key, and key password.
	EncryptionOptions *SqlServerEncryptionOptions `json:"encryptionOptions,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Database") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Database") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerDatabaseBackup) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerDatabaseBackup
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerDestinationConfig: Configuration for SQL Server as a destination in
// a migration.
type SqlServerDestinationConfig struct {
	// MaxConcurrentConnections: Optional. Maximum number of connections Database
	// Migration Service will open to the destination for data migration.
	MaxConcurrentConnections int64 `json:"maxConcurrentConnections,omitempty"`
	// TransactionTimeout: Optional. Timeout for data migration transactions.
	TransactionTimeout string `json:"transactionTimeout,omitempty"`
	// ForceSendFields is a list of field names (e.g. "MaxConcurrentConnections")
	// to unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "MaxConcurrentConnections") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerDestinationConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerDestinationConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerEncryptionOptions: Encryption settings for the SQL Server database.
type SqlServerEncryptionOptions struct {
	// CertPath: Required. Path to the Certificate (.cer) in Cloud Storage, in the
	// form `gs://bucketName/fileName`. The instance must have write permissions to
	// the bucket and read access to the file.
	CertPath string `json:"certPath,omitempty"`
	// PvkPassword: Required. Input only. Password that encrypts the private key.
	PvkPassword string `json:"pvkPassword,omitempty"`
	// PvkPath: Required. Path to the Certificate Private Key (.pvk) in Cloud
	// Storage, in the form `gs://bucketName/fileName`. The instance must have
	// write permissions to the bucket and read access to the file.
	PvkPath string `json:"pvkPath,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CertPath") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CertPath") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerEncryptionOptions) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerEncryptionOptions
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerHomogeneousMigrationJobConfig: Configuration for homogeneous
// migration to Cloud SQL for SQL Server.
type SqlServerHomogeneousMigrationJobConfig struct {
	// BackupFilePattern: Required. Pattern that describes the default backup
	// naming strategy. The specified pattern should ensure lexicographical order
	// of backups. The pattern must define one of the following capture group sets:
	// Capture group set #1 yy/yyyy - year, 2 or 4 digits mm - month number, 1-12
	// dd - day of month, 1-31 hh - hour of day, 00-23 mi - minutes, 00-59 ss -
	// seconds, 00-59 Example: For backup file TestDB_20230802_155400.trn, use
	// pattern: (?.*)_backup_(?\d{4})(?\d{2})(?\d{2})_(?\d{2})(?\d{2})(?\d{2}).trn
	// Capture group set #2 timestamp - unix timestamp Example: For backup file
	// TestDB.1691448254.trn, use pattern: (?.*)\.(?\d*).trn or (?.*)\.(?\d*).trn
	BackupFilePattern string `json:"backupFilePattern,omitempty"`
	// DagConfig: Optional. Configuration for distributed availability group (DAG)
	// for the SQL Server homogeneous migration.
	DagConfig *SqlServerDagConfig `json:"dagConfig,omitempty"`
	// DatabaseBackups: Required. Backup details per database in Cloud Storage.
	DatabaseBackups []*SqlServerDatabaseBackup `json:"databaseBackups,omitempty"`
	// PromoteWhenReady: Optional. Promote databases when ready.
	PromoteWhenReady bool `json:"promoteWhenReady,omitempty"`
	// UseDiffBackup: Optional. Enable differential backups.
	UseDiffBackup bool `json:"useDiffBackup,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BackupFilePattern") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupFilePattern") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerHomogeneousMigrationJobConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerHomogeneousMigrationJobConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerSourceConfig: Configuration for SQL Server as a source in a
// migration.
type SqlServerSourceConfig struct {
	// CdcStartPosition: Optional. The log sequence number (LSN) to start CDC data
	// migration from.
	CdcStartPosition string `json:"cdcStartPosition,omitempty"`
	// MaxConcurrentCdcConnections: Optional. Maximum number of connections
	// Database Migration Service will open to the source for CDC phase.
	MaxConcurrentCdcConnections int64 `json:"maxConcurrentCdcConnections,omitempty"`
	// MaxConcurrentFullDumpConnections: Optional. Maximum number of connections
	// Database Migration Service will open to the source for full dump phase.
	MaxConcurrentFullDumpConnections int64 `json:"maxConcurrentFullDumpConnections,omitempty"`
	// SkipFullDump: Optional. Whether to skip full dump or not.
	SkipFullDump bool `json:"skipFullDump,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CdcStartPosition") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CdcStartPosition") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerSourceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerSourceConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SqlServerToPostgresConfig: Configuration for heterogeneous **SQL Server to
// Cloud SQL for PostgreSQL** migrations.
type SqlServerToPostgresConfig struct {
	// PostgresDestinationConfig: Optional. Configuration for Postgres destination.
	PostgresDestinationConfig *PostgresDestinationConfig `json:"postgresDestinationConfig,omitempty"`
	// SqlserverSourceConfig: Optional. Configuration for SQL Server source.
	SqlserverSourceConfig *SqlServerSourceConfig `json:"sqlserverSourceConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PostgresDestinationConfig")
	// to unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "PostgresDestinationConfig") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SqlServerToPostgresConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SqlServerToPostgresConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SshScript: Response message for 'GenerateSshScript' request.
type SshScript struct {
	// Script: The ssh configuration script.
	Script string `json:"script,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Script") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Script") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SshScript) MarshalJSON() ([]byte, error) {
	type NoMethod SshScript
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SslConfig: SSL configuration information.
type SslConfig struct {
	// CaCertificate: Required. Input only. The x509 PEM-encoded certificate of the
	// CA that signed the source database server's certificate. The replica will
	// use this certificate to verify it's connecting to the right host.
	CaCertificate string `json:"caCertificate,omitempty"`
	// ClientCertificate: Input only. The x509 PEM-encoded certificate that will be
	// used by the replica to authenticate against the source database server.If
	// this field is used then the 'client_key' field is mandatory.
	ClientCertificate string `json:"clientCertificate,omitempty"`
	// ClientKey: Input only. The unencrypted PKCS#1 or PKCS#8 PEM-encoded private
	// key associated with the Client Certificate. If this field is used then the
	// 'client_certificate' field is mandatory.
	ClientKey string `json:"clientKey,omitempty"`
	// SslFlags: Optional. SSL flags used for establishing SSL connection to the
	// source database. Only source specific flags are supported. An object
	// containing a list of "key": "value" pairs. Example: {
	// "server_certificate_hostname": "server.com"}.
	SslFlags map[string]string `json:"sslFlags,omitempty"`
	// Type: Optional. The ssl config type according to 'client_key',
	// 'client_certificate' and 'ca_certificate'.
	//
	// Possible values:
	//   "SSL_TYPE_UNSPECIFIED" - Unspecified.
	//   "SERVER_ONLY" - Only 'ca_certificate' specified.
	//   "SERVER_CLIENT" - Both server ('ca_certificate'), and client
	// ('client_key', 'client_certificate') specified.
	//   "REQUIRED" - Mandates SSL encryption for all connections. This does not
	// require certificate verification.
	//   "NONE" - Connection is not encrypted.
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CaCertificate") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CaCertificate") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SslConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SslConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// StartMigrationJobRequest: Request message for 'StartMigrationJob' request.
type StartMigrationJobRequest struct {
	// SkipValidation: Optional. Start the migration job without running prior
	// configuration verification. Defaults to `false`.
	SkipValidation bool `json:"skipValidation,omitempty"`
	// ForceSendFields is a list of field names (e.g. "SkipValidation") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "SkipValidation") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s StartMigrationJobRequest) MarshalJSON() ([]byte, error) {
	type NoMethod StartMigrationJobRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// StaticIpConnectivity: The source database will allow incoming connections
// from the public IP of the destination database. You can retrieve the public
// IP of the Cloud SQL instance from the Cloud SQL console or using Cloud SQL
// APIs. No additional configuration is required.
type StaticIpConnectivity struct {
}

// StaticServiceIpConnectivity: Static IP address connectivity configured on
// service project.
type StaticServiceIpConnectivity struct {
}

// Status: The `Status` type defines a logical error model that is suitable for
// different programming environments, including REST APIs and RPC APIs. It is
// used by gRPC (https://github.com/grpc). Each `Status` message contains three
// pieces of data: error code, error message, and error details. You can find
// out more about this error model and how to work with it in the API Design
// Guide (https://cloud.google.com/apis/design/errors).
type Status struct {
	// Code: The status code, which should be an enum value of google.rpc.Code.
	Code int64 `json:"code,omitempty"`
	// Details: A list of messages that carry the error details. There is a common
	// set of message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`
	// Message: A developer-facing error message, which should be in English. Any
	// user-facing error message should be localized and sent in the
	// google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Code") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Code") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Status) MarshalJSON() ([]byte, error) {
	type NoMethod Status
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// StopMigrationJobRequest: Request message for 'StopMigrationJob' request.
type StopMigrationJobRequest struct {
}

// StoredProcedureEntity: Stored procedure's parent is a schema.
type StoredProcedureEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// SqlCode: The SQL code which creates the stored procedure.
	SqlCode string `json:"sqlCode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s StoredProcedureEntity) MarshalJSON() ([]byte, error) {
	type NoMethod StoredProcedureEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SynonymEntity: Synonym's parent is a schema.
type SynonymEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// SourceEntity: The name of the entity for which the synonym is being created
	// (the source).
	SourceEntity string `json:"sourceEntity,omitempty"`
	// SourceType: The type of the entity for which the synonym is being created
	// (usually a table or a sequence).
	//
	// Possible values:
	//   "DATABASE_ENTITY_TYPE_UNSPECIFIED" - Unspecified database entity type.
	//   "DATABASE_ENTITY_TYPE_SCHEMA" - Schema.
	//   "DATABASE_ENTITY_TYPE_TABLE" - Table.
	//   "DATABASE_ENTITY_TYPE_COLUMN" - Column.
	//   "DATABASE_ENTITY_TYPE_CONSTRAINT" - Constraint.
	//   "DATABASE_ENTITY_TYPE_INDEX" - Index.
	//   "DATABASE_ENTITY_TYPE_TRIGGER" - Trigger.
	//   "DATABASE_ENTITY_TYPE_VIEW" - View.
	//   "DATABASE_ENTITY_TYPE_SEQUENCE" - Sequence.
	//   "DATABASE_ENTITY_TYPE_STORED_PROCEDURE" - Stored Procedure.
	//   "DATABASE_ENTITY_TYPE_FUNCTION" - Function.
	//   "DATABASE_ENTITY_TYPE_SYNONYM" - Synonym.
	//   "DATABASE_ENTITY_TYPE_DATABASE_PACKAGE" - Package.
	//   "DATABASE_ENTITY_TYPE_UDT" - UDT.
	//   "DATABASE_ENTITY_TYPE_MATERIALIZED_VIEW" - Materialized View.
	//   "DATABASE_ENTITY_TYPE_DATABASE" - Database.
	SourceType string `json:"sourceType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SynonymEntity) MarshalJSON() ([]byte, error) {
	type NoMethod SynonymEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// TableEntity: Table's parent is a schema.
type TableEntity struct {
	// Columns: Table columns.
	Columns []*ColumnEntity `json:"columns,omitempty"`
	// Comment: Comment associated with the table.
	Comment string `json:"comment,omitempty"`
	// Constraints: Table constraints.
	Constraints []*ConstraintEntity `json:"constraints,omitempty"`
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// Indices: Table indices.
	Indices []*IndexEntity `json:"indices,omitempty"`
	// Triggers: Table triggers.
	Triggers []*TriggerEntity `json:"triggers,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Columns") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Columns") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s TableEntity) MarshalJSON() ([]byte, error) {
	type NoMethod TableEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// TcpProxyScript: Response message for 'GenerateTcpProxyScript' request.
type TcpProxyScript struct {
	// Script: The TCP Proxy configuration script.
	Script string `json:"script,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Script") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Script") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s TcpProxyScript) MarshalJSON() ([]byte, error) {
	type NoMethod TcpProxyScript
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// TestIamPermissionsRequest: Request message for `TestIamPermissions` method.
type TestIamPermissionsRequest struct {
	// Permissions: The set of permissions to check for the `resource`. Permissions
	// with wildcards (such as `*` or `storage.*`) are not allowed. For more
	// information see IAM Overview
	// (https://cloud.google.com/iam/docs/overview#permissions).
	Permissions []string `json:"permissions,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Permissions") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Permissions") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

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

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Permissions") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Permissions") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

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

// TriggerEntity: Trigger is not used as an independent entity, it is retrieved
// as part of a Table entity.
type TriggerEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// Name: The name of the trigger.
	Name string `json:"name,omitempty"`
	// SqlCode: The SQL code which creates the trigger.
	SqlCode string `json:"sqlCode,omitempty"`
	// TriggerType: Indicates when the trigger fires, for example BEFORE STATEMENT,
	// AFTER EACH ROW.
	TriggerType string `json:"triggerType,omitempty"`
	// TriggeringEvents: The DML, DDL, or database events that fire the trigger,
	// for example INSERT, UPDATE.
	TriggeringEvents []string `json:"triggeringEvents,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s TriggerEntity) MarshalJSON() ([]byte, error) {
	type NoMethod TriggerEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// UDTEntity: UDT's parent is a schema.
type UDTEntity struct {
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// UdtBody: The SQL code which creates the udt body.
	UdtBody string `json:"udtBody,omitempty"`
	// UdtSqlCode: The SQL code which creates the udt.
	UdtSqlCode string `json:"udtSqlCode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomFeatures") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CustomFeatures") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s UDTEntity) MarshalJSON() ([]byte, error) {
	type NoMethod UDTEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// UserPassword: The username/password for a database user. Used for specifying
// initial users at cluster creation time.
type UserPassword struct {
	// Password: The initial password for the user.
	Password string `json:"password,omitempty"`
	// PasswordSet: Output only. Indicates if the initial_user.password field has
	// been set.
	PasswordSet bool `json:"passwordSet,omitempty"`
	// User: The database username.
	User string `json:"user,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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	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. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s UserPassword) MarshalJSON() ([]byte, error) {
	type NoMethod UserPassword
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ValueListFilter: A list of values to filter by in ConditionalColumnSetValue
type ValueListFilter struct {
	// IgnoreCase: Required. Whether to ignore case when filtering by values.
	// Defaults to false
	IgnoreCase bool `json:"ignoreCase,omitempty"`
	// ValuePresentList: Required. Indicates whether the filter matches rows with
	// values that are present in the list or those with values not present in it.
	//
	// Possible values:
	//   "VALUE_PRESENT_IN_LIST_UNSPECIFIED" - Value present in list unspecified
	//   "VALUE_PRESENT_IN_LIST_IF_VALUE_LIST" - If the source value is in the
	// supplied list at value_list
	//   "VALUE_PRESENT_IN_LIST_IF_VALUE_NOT_LIST" - If the source value is not in
	// the supplied list at value_list
	ValuePresentList string `json:"valuePresentList,omitempty"`
	// Values: Required. The list to be used to filter by
	Values []string `json:"values,omitempty"`
	// ForceSendFields is a list of field names (e.g. "IgnoreCase") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "IgnoreCase") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ValueListFilter) MarshalJSON() ([]byte, error) {
	type NoMethod ValueListFilter
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ValueTransformation: Description of data transformation during migration as
// part of the ConditionalColumnSetValue.
type ValueTransformation struct {
	// ApplyHash: Optional. Applies a hash function on the data
	ApplyHash *ApplyHash `json:"applyHash,omitempty"`
	// AssignMaxValue: Optional. Set to max_value - if integer or numeric, will use
	// int.maxvalue, etc
	AssignMaxValue *Empty `json:"assignMaxValue,omitempty"`
	// AssignMinValue: Optional. Set to min_value - if integer or numeric, will use
	// int.minvalue, etc
	AssignMinValue *Empty `json:"assignMinValue,omitempty"`
	// AssignNull: Optional. Set to null
	AssignNull *Empty `json:"assignNull,omitempty"`
	// AssignSpecificValue: Optional. Set to a specific value (value is converted
	// to fit the target data type)
	AssignSpecificValue *AssignSpecificValue `json:"assignSpecificValue,omitempty"`
	// DoubleComparison: Optional. Filter on relation between source value and
	// compare value of type double.
	DoubleComparison *DoubleComparisonFilter `json:"doubleComparison,omitempty"`
	// IntComparison: Optional. Filter on relation between source value and compare
	// value of type integer.
	IntComparison *IntComparisonFilter `json:"intComparison,omitempty"`
	// IsNull: Optional. Value is null
	IsNull *Empty `json:"isNull,omitempty"`
	// RoundScale: Optional. Allows the data to change scale
	RoundScale *RoundToScale `json:"roundScale,omitempty"`
	// ValueList: Optional. Value is found in the specified list.
	ValueList *ValueListFilter `json:"valueList,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ApplyHash") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ApplyHash") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ValueTransformation) MarshalJSON() ([]byte, error) {
	type NoMethod ValueTransformation
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// VerifyMigrationJobRequest: Request message for 'VerifyMigrationJob' request.
type VerifyMigrationJobRequest struct {
	// MigrationJob: Optional. The changed migration job parameters to verify. It
	// will not update the migration job.
	MigrationJob *MigrationJob `json:"migrationJob,omitempty"`
	// UpdateMask: Optional. Field mask is used to specify the changed fields to be
	// verified. It will not update the migration job.
	UpdateMask string `json:"updateMask,omitempty"`
	// ForceSendFields is a list of field names (e.g. "MigrationJob") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "MigrationJob") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s VerifyMigrationJobRequest) MarshalJSON() ([]byte, error) {
	type NoMethod VerifyMigrationJobRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ViewEntity: View's parent is a schema.
type ViewEntity struct {
	// Constraints: View constraints.
	Constraints []*ConstraintEntity `json:"constraints,omitempty"`
	// CustomFeatures: Custom engine specific features.
	CustomFeatures googleapi.RawMessage `json:"customFeatures,omitempty"`
	// SqlCode: The SQL code which creates the view.
	SqlCode string `json:"sqlCode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Constraints") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Constraints") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ViewEntity) MarshalJSON() ([]byte, error) {
	type NoMethod ViewEntity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// VmCreationConfig: VM creation configuration message
type VmCreationConfig struct {
	// Subnet: The subnet name the vm needs to be created in.
	Subnet string `json:"subnet,omitempty"`
	// VmMachineType: Required. VM instance machine type to create.
	VmMachineType string `json:"vmMachineType,omitempty"`
	// VmZone: The Google Cloud Platform zone to create the VM in.
	VmZone string `json:"vmZone,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Subnet") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Subnet") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s VmCreationConfig) MarshalJSON() ([]byte, error) {
	type NoMethod VmCreationConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// VmSelectionConfig: VM selection configuration message
type VmSelectionConfig struct {
	// VmZone: Required. The Google Cloud Platform zone the VM is located.
	VmZone string `json:"vmZone,omitempty"`
	// ForceSendFields is a list of field names (e.g. "VmZone") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "VmZone") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s VmSelectionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod VmSelectionConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// VpcPeeringConfig: The VPC peering configuration is used to create VPC
// peering with the consumer's VPC.
type VpcPeeringConfig struct {
	// Subnet: Required. A free subnet for peering. (CIDR of /29)
	Subnet string `json:"subnet,omitempty"`
	// VpcName: Required. Fully qualified name of the VPC that Database Migration
	// Service will peer to.
	VpcName string `json:"vpcName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Subnet") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Subnet") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s VpcPeeringConfig) MarshalJSON() ([]byte, error) {
	type NoMethod VpcPeeringConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// VpcPeeringConnectivity: The details of the VPC where the source database is
// located in Google Cloud. We will use this information to set up the VPC
// peering connection between Cloud SQL and this VPC.
type VpcPeeringConnectivity struct {
	// Vpc: The name of the VPC network to peer with the Cloud SQL private network.
	Vpc string `json:"vpc,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Vpc") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Vpc") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s VpcPeeringConnectivity) MarshalJSON() ([]byte, error) {
	type NoMethod VpcPeeringConnectivity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

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

// FetchStaticIps: Fetches a set of static IP addresses that need to be
// allowlisted by the customer when using the static-IP connectivity method.
//
//   - name: The resource name for the location for which static IPs should be
//     returned. Must be in the format `projects/*/locations/*`.
func (r *ProjectsLocationsService) FetchStaticIps(name string) *ProjectsLocationsFetchStaticIpsCall {
	c := &ProjectsLocationsFetchStaticIpsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// FetchReservedPublicIps sets the optional parameter "fetchReservedPublicIps":
// Indicates whether to fetch the reserved public IP addresses allocated for
// private connections in this location. If false or not set, fetches the
// shared external static IP addresses instead.
func (c *ProjectsLocationsFetchStaticIpsCall) FetchReservedPublicIps(fetchReservedPublicIps bool) *ProjectsLocationsFetchStaticIpsCall {
	c.urlParams_.Set("fetchReservedPublicIps", fmt.Sprint(fetchReservedPublicIps))
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of IPs to
// return.
func (c *ProjectsLocationsFetchStaticIpsCall) PageSize(pageSize int64) *ProjectsLocationsFetchStaticIpsCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token, received
// from a previous `FetchStaticIps` call.
func (c *ProjectsLocationsFetchStaticIpsCall) PageToken(pageToken string) *ProjectsLocationsFetchStaticIpsCall {
	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
// details.
func (c *ProjectsLocationsFetchStaticIpsCall) Fields(s ...googleapi.Field) *ProjectsLocationsFetchStaticIpsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsFetchStaticIpsCall) IfNoneMatch(entityTag string) *ProjectsLocationsFetchStaticIpsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsFetchStaticIpsCall) Context(ctx context.Context) *ProjectsLocationsFetchStaticIpsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsFetchStaticIpsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:fetchStaticIps")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.fetchStaticIps", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.fetchStaticIps" call.
// Any non-2xx status code is an error. Response headers are in either
// *FetchStaticIpsResponse.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 *ProjectsLocationsFetchStaticIpsCall) Do(opts ...googleapi.CallOption) (*FetchStaticIpsResponse, 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 := &FetchStaticIpsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.fetchStaticIps", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsFetchStaticIpsCall) Pages(ctx context.Context, f func(*FetchStaticIpsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

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

// Get: Gets information about a location.
//
// - name: Resource name for the location.
func (r *ProjectsLocationsService) Get(name string) *ProjectsLocationsGetCall {
	c := &ProjectsLocationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsGetCall) Context(ctx context.Context) *ProjectsLocationsGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *Location.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsGetCall) Do(opts ...googleapi.CallOption) (*Location, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Location{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists information about the supported locations for this service. This
// method lists locations based on the resource scope provided in the
// ListLocationsRequest.name field: * **Global locations**: If `name` is empty,
// the method lists the public locations available to all projects. *
// **Project-specific locations**: If `name` follows the format
// `projects/{project}`, the method lists locations visible to that specific
// project. This includes public, private, or other project-specific locations
// enabled for the project. For gRPC and client library implementations, the
// resource name is passed as the `name` field. For direct service calls, the
// resource name is incorporated into the request path based on the specific
// service implementation and version.
//
// - name: The resource that owns the locations collection, if applicable.
func (r *ProjectsLocationsService) List(name string) *ProjectsLocationsListCall {
	c := &ProjectsLocationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ExtraLocationTypes sets the optional parameter "extraLocationTypes": Do not
// use this field unless explicitly documented otherwise. This is primarily for
// internal usage.
func (c *ProjectsLocationsListCall) ExtraLocationTypes(extraLocationTypes ...string) *ProjectsLocationsListCall {
	c.urlParams_.SetMulti("extraLocationTypes", append([]string{}, extraLocationTypes...))
	return c
}

// Filter sets the optional parameter "filter": A filter to narrow down results
// to a preferred subset. The filtering language accepts strings like
// "displayName=tokyo", and is documented in more detail in AIP-160
// (https://google.aip.dev/160).
func (c *ProjectsLocationsListCall) Filter(filter string) *ProjectsLocationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// results to return. If not set, the service selects a default.
func (c *ProjectsLocationsListCall) PageSize(pageSize int64) *ProjectsLocationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token received
// from the `next_page_token` field in the response. Send that page token to
// receive the subsequent page.
func (c *ProjectsLocationsListCall) PageToken(pageToken string) *ProjectsLocationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsListCall) Context(ctx context.Context) *ProjectsLocationsListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/locations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListLocationsResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsListCall) Do(opts ...googleapi.CallOption) (*ListLocationsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &ListLocationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsListCall) Pages(ctx context.Context, f func(*ListLocationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

type ProjectsLocationsConnectionProfilesCreateCall struct {
	s                 *Service
	parent            string
	connectionprofile *ConnectionProfile
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Creates a new connection profile in a given project and location.
//
// - parent: The parent which owns this collection of connection profiles.
func (r *ProjectsLocationsConnectionProfilesService) Create(parent string, connectionprofile *ConnectionProfile) *ProjectsLocationsConnectionProfilesCreateCall {
	c := &ProjectsLocationsConnectionProfilesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.connectionprofile = connectionprofile
	return c
}

// ConnectionProfileId sets the optional parameter "connectionProfileId":
// Required. The connection profile identifier.
func (c *ProjectsLocationsConnectionProfilesCreateCall) ConnectionProfileId(connectionProfileId string) *ProjectsLocationsConnectionProfilesCreateCall {
	c.urlParams_.Set("connectionProfileId", connectionProfileId)
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsConnectionProfilesCreateCall) RequestId(requestId string) *ProjectsLocationsConnectionProfilesCreateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// SkipValidation sets the optional parameter "skipValidation": Create the
// connection profile without validating it. The default is false. Only
// supported for Oracle connection profiles.
func (c *ProjectsLocationsConnectionProfilesCreateCall) SkipValidation(skipValidation bool) *ProjectsLocationsConnectionProfilesCreateCall {
	c.urlParams_.Set("skipValidation", fmt.Sprint(skipValidation))
	return c
}

// ValidateOnly sets the optional parameter "validateOnly": Only validate the
// connection profile, but don't create any resources. The default is false.
// Only supported for Oracle connection profiles.
func (c *ProjectsLocationsConnectionProfilesCreateCall) ValidateOnly(validateOnly bool) *ProjectsLocationsConnectionProfilesCreateCall {
	c.urlParams_.Set("validateOnly", fmt.Sprint(validateOnly))
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConnectionProfilesCreateCall) Context(ctx context.Context) *ProjectsLocationsConnectionProfilesCreateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConnectionProfilesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.connectionprofile)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/connectionProfiles")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.connectionProfiles.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConnectionProfilesCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes a single Database Migration Service connection profile. A
// connection profile can only be deleted if it is not in use by any active
// migration jobs.
//
// - name: Name of the connection profile resource to delete.
func (r *ProjectsLocationsConnectionProfilesService) Delete(name string) *ProjectsLocationsConnectionProfilesDeleteCall {
	c := &ProjectsLocationsConnectionProfilesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Force sets the optional parameter "force": In case of force delete, the
// CloudSQL replica database is also deleted (only for CloudSQL connection
// profile).
func (c *ProjectsLocationsConnectionProfilesDeleteCall) Force(force bool) *ProjectsLocationsConnectionProfilesDeleteCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsConnectionProfilesDeleteCall) RequestId(requestId string) *ProjectsLocationsConnectionProfilesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConnectionProfilesDeleteCall) Context(ctx context.Context) *ProjectsLocationsConnectionProfilesDeleteCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConnectionProfilesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.connectionProfiles.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConnectionProfilesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Gets details of a single connection profile.
//
// - name: Name of the connection profile resource to get.
func (r *ProjectsLocationsConnectionProfilesService) Get(name string) *ProjectsLocationsConnectionProfilesGetCall {
	c := &ProjectsLocationsConnectionProfilesGetCall{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
// details.
func (c *ProjectsLocationsConnectionProfilesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsConnectionProfilesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConnectionProfilesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsConnectionProfilesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConnectionProfilesGetCall) Context(ctx context.Context) *ProjectsLocationsConnectionProfilesGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConnectionProfilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.connectionProfiles.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *ConnectionProfile.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 *ProjectsLocationsConnectionProfilesGetCall) Do(opts ...googleapi.CallOption) (*ConnectionProfile, 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 := &ConnectionProfile{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// GetIamPolicy: Gets the access control policy for a resource. Returns an
// empty policy if the resource exists and does not have a policy set.
//
//   - resource: REQUIRED: The resource for which the policy is being requested.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsConnectionProfilesService) GetIamPolicy(resource string) *ProjectsLocationsConnectionProfilesGetIamPolicyCall {
	c := &ProjectsLocationsConnectionProfilesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// OptionsRequestedPolicyVersion sets the optional parameter
// "options.requestedPolicyVersion": The maximum policy version that will be
// used to format the policy. Valid values are 0, 1, and 3. Requests specifying
// an invalid value will be rejected. Requests for policies with any
// conditional role bindings must specify version 3. Policies with no
// conditional role bindings may specify any valid value or leave the field
// unset. The policy in the response might use the policy version that you
// specified, or it might use a lower policy version. For example, if you
// specify version 3, but the policy has no conditional role bindings, the
// response uses version 1. To learn which resources support conditions in
// their IAM policies, see the IAM documentation
// (https://cloud.google.com/iam/help/conditions/resource-policies).
func (c *ProjectsLocationsConnectionProfilesGetIamPolicyCall) OptionsRequestedPolicyVersion(optionsRequestedPolicyVersion int64) *ProjectsLocationsConnectionProfilesGetIamPolicyCall {
	c.urlParams_.Set("options.requestedPolicyVersion", fmt.Sprint(optionsRequestedPolicyVersion))
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConnectionProfilesGetIamPolicyCall) IfNoneMatch(entityTag string) *ProjectsLocationsConnectionProfilesGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConnectionProfilesGetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsConnectionProfilesGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConnectionProfilesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.getIamPolicy", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.connectionProfiles.getIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConnectionProfilesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.getIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Retrieves a list of all connection profiles in a given project and
// location.
//
// - parent: The parent which owns this collection of connection profiles.
func (r *ProjectsLocationsConnectionProfilesService) List(parent string) *ProjectsLocationsConnectionProfilesListCall {
	c := &ProjectsLocationsConnectionProfilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters connection profiles listed in the response. The expression must
// specify the field name, a comparison operator, and the value that you want
// to use for filtering. The value must be a string, a number, or a boolean.
// The comparison operator must be either =, !=, >, or <. For example, list
// connection profiles created this year by specifying **createTime %gt;
// 2020-01-01T00:00:00.000000000Z**. You can also filter nested fields. For
// example, you could specify **mySql.username = %lt;my_username%gt;** to list
// all connection profiles configured to connect with a specific username.
func (c *ProjectsLocationsConnectionProfilesListCall) Filter(filter string) *ProjectsLocationsConnectionProfilesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": A comma-separated list of
// fields to order results according to.
func (c *ProjectsLocationsConnectionProfilesListCall) OrderBy(orderBy string) *ProjectsLocationsConnectionProfilesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// connection profiles to return. The service may return fewer than this value.
// If unspecified, at most 50 connection profiles will be returned. The maximum
// value is 1000; values above 1000 are coerced to 1000.
func (c *ProjectsLocationsConnectionProfilesListCall) PageSize(pageSize int64) *ProjectsLocationsConnectionProfilesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token, received
// from a previous `ListConnectionProfiles` call. Provide this to retrieve the
// subsequent page. When paginating, all other parameters provided to
// `ListConnectionProfiles` must match the call that provided the page token.
func (c *ProjectsLocationsConnectionProfilesListCall) PageToken(pageToken string) *ProjectsLocationsConnectionProfilesListCall {
	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
// details.
func (c *ProjectsLocationsConnectionProfilesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsConnectionProfilesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConnectionProfilesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsConnectionProfilesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConnectionProfilesListCall) Context(ctx context.Context) *ProjectsLocationsConnectionProfilesListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConnectionProfilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/connectionProfiles")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.connectionProfiles.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListConnectionProfilesResponse.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 *ProjectsLocationsConnectionProfilesListCall) Do(opts ...googleapi.CallOption) (*ListConnectionProfilesResponse, 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 := &ListConnectionProfilesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsConnectionProfilesListCall) Pages(ctx context.Context, f func(*ListConnectionProfilesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

type ProjectsLocationsConnectionProfilesPatchCall struct {
	s                 *Service
	name              string
	connectionprofile *ConnectionProfile
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Patch: Update the configuration of a single connection profile.
//
//   - name: The name of this connection profile resource in the form of
//     projects/{project}/locations/{location}/connectionProfiles/{connectionProfi
//     le}.
func (r *ProjectsLocationsConnectionProfilesService) Patch(name string, connectionprofile *ConnectionProfile) *ProjectsLocationsConnectionProfilesPatchCall {
	c := &ProjectsLocationsConnectionProfilesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.connectionprofile = connectionprofile
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsConnectionProfilesPatchCall) RequestId(requestId string) *ProjectsLocationsConnectionProfilesPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// SkipValidation sets the optional parameter "skipValidation": Update the
// connection profile without validating it. The default is false. Only
// supported for Oracle connection profiles.
func (c *ProjectsLocationsConnectionProfilesPatchCall) SkipValidation(skipValidation bool) *ProjectsLocationsConnectionProfilesPatchCall {
	c.urlParams_.Set("skipValidation", fmt.Sprint(skipValidation))
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. Field mask is
// used to specify the fields to be overwritten by the update in the conversion
// workspace resource.
func (c *ProjectsLocationsConnectionProfilesPatchCall) UpdateMask(updateMask string) *ProjectsLocationsConnectionProfilesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

// ValidateOnly sets the optional parameter "validateOnly": Only validate the
// connection profile, but don't update any resources. The default is false.
// Only supported for Oracle connection profiles.
func (c *ProjectsLocationsConnectionProfilesPatchCall) ValidateOnly(validateOnly bool) *ProjectsLocationsConnectionProfilesPatchCall {
	c.urlParams_.Set("validateOnly", fmt.Sprint(validateOnly))
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConnectionProfilesPatchCall) Context(ctx context.Context) *ProjectsLocationsConnectionProfilesPatchCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConnectionProfilesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.connectionprofile)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.connectionProfiles.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConnectionProfilesPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConnectionProfilesSetIamPolicyCall struct {
	s                   *Service
	resource            string
	setiampolicyrequest *SetIamPolicyRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// SetIamPolicy: Sets the access control policy on the specified resource.
// Replaces any existing policy. Can return `NOT_FOUND`, `INVALID_ARGUMENT`,
// and `PERMISSION_DENIED` errors.
//
//   - resource: REQUIRED: The resource for which the policy is being specified.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsConnectionProfilesService) SetIamPolicy(resource string, setiampolicyrequest *SetIamPolicyRequest) *ProjectsLocationsConnectionProfilesSetIamPolicyCall {
	c := &ProjectsLocationsConnectionProfilesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.setiampolicyrequest = setiampolicyrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConnectionProfilesSetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsConnectionProfilesSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConnectionProfilesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.setiampolicyrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.setIamPolicy", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.connectionProfiles.setIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConnectionProfilesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.setIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConnectionProfilesTestIamPermissionsCall struct {
	s                         *Service
	resource                  string
	testiampermissionsrequest *TestIamPermissionsRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the specified
// resource. If the resource does not exist, this will return an empty set of
// permissions, not a `NOT_FOUND` error. Note: This operation is designed to be
// used for building permission-aware UIs and command-line tools, not for
// authorization checking. This operation may "fail open" without warning.
//
//   - resource: REQUIRED: The resource for which the policy detail is being
//     requested. See Resource names
//     (https://cloud.google.com/apis/design/resource_names) for the appropriate
//     value for this field.
func (r *ProjectsLocationsConnectionProfilesService) TestIamPermissions(resource string, testiampermissionsrequest *TestIamPermissionsRequest) *ProjectsLocationsConnectionProfilesTestIamPermissionsCall {
	c := &ProjectsLocationsConnectionProfilesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.testiampermissionsrequest = testiampermissionsrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConnectionProfilesTestIamPermissionsCall) Context(ctx context.Context) *ProjectsLocationsConnectionProfilesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConnectionProfilesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.testiampermissionsrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.testIamPermissions", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.connectionProfiles.testIamPermissions" call.
// Any non-2xx status code is an error. Response headers are in either
// *TestIamPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsConnectionProfilesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &TestIamPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.connectionProfiles.testIamPermissions", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesApplyCall struct {
	s                               *Service
	name                            string
	applyconversionworkspacerequest *ApplyConversionWorkspaceRequest
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Apply: Applies draft tree onto a specific destination database.
//
//   - name: The name of the conversion workspace resource for which to apply the
//     draft tree. Must be in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) Apply(name string, applyconversionworkspacerequest *ApplyConversionWorkspaceRequest) *ProjectsLocationsConversionWorkspacesApplyCall {
	c := &ProjectsLocationsConversionWorkspacesApplyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.applyconversionworkspacerequest = applyconversionworkspacerequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesApplyCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesApplyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesApplyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.applyconversionworkspacerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:apply")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.apply", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.apply" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesApplyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.apply", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesCommitCall struct {
	s                                *Service
	name                             string
	commitconversionworkspacerequest *CommitConversionWorkspaceRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// Commit: Marks all the data in the conversion workspace as committed.
//
// - name: Name of the conversion workspace resource to commit.
func (r *ProjectsLocationsConversionWorkspacesService) Commit(name string, commitconversionworkspacerequest *CommitConversionWorkspaceRequest) *ProjectsLocationsConversionWorkspacesCommitCall {
	c := &ProjectsLocationsConversionWorkspacesCommitCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.commitconversionworkspacerequest = commitconversionworkspacerequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesCommitCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesCommitCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesCommitCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.commitconversionworkspacerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:commit")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.commit", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.commit" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesCommitCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.commit", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesConvertCall struct {
	s                                 *Service
	name                              string
	convertconversionworkspacerequest *ConvertConversionWorkspaceRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// Convert: Creates a draft tree schema for the destination database.
//
//   - name: Name of the conversion workspace resource to convert in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) Convert(name string, convertconversionworkspacerequest *ConvertConversionWorkspaceRequest) *ProjectsLocationsConversionWorkspacesConvertCall {
	c := &ProjectsLocationsConversionWorkspacesConvertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.convertconversionworkspacerequest = convertconversionworkspacerequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesConvertCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesConvertCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesConvertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.convertconversionworkspacerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:convert")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.convert", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.convert" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesConvertCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.convert", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesCreateCall struct {
	s                   *Service
	parent              string
	conversionworkspace *ConversionWorkspace
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// Create: Creates a new conversion workspace in a given project and location.
//
// - parent: The parent which owns this collection of conversion workspaces.
func (r *ProjectsLocationsConversionWorkspacesService) Create(parent string, conversionworkspace *ConversionWorkspace) *ProjectsLocationsConversionWorkspacesCreateCall {
	c := &ProjectsLocationsConversionWorkspacesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.conversionworkspace = conversionworkspace
	return c
}

// ConversionWorkspaceId sets the optional parameter "conversionWorkspaceId":
// Required. The ID of the conversion workspace to create.
func (c *ProjectsLocationsConversionWorkspacesCreateCall) ConversionWorkspaceId(conversionWorkspaceId string) *ProjectsLocationsConversionWorkspacesCreateCall {
	c.urlParams_.Set("conversionWorkspaceId", conversionWorkspaceId)
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsConversionWorkspacesCreateCall) RequestId(requestId string) *ProjectsLocationsConversionWorkspacesCreateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesCreateCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesCreateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.conversionworkspace)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/conversionWorkspaces")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes a single conversion workspace.
//
// - name: Name of the conversion workspace resource to delete.
func (r *ProjectsLocationsConversionWorkspacesService) Delete(name string) *ProjectsLocationsConversionWorkspacesDeleteCall {
	c := &ProjectsLocationsConversionWorkspacesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Force sets the optional parameter "force": Force delete the conversion
// workspace, even if there's a running migration that is using the workspace.
func (c *ProjectsLocationsConversionWorkspacesDeleteCall) Force(force bool) *ProjectsLocationsConversionWorkspacesDeleteCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsConversionWorkspacesDeleteCall) RequestId(requestId string) *ProjectsLocationsConversionWorkspacesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesDeleteCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesDeleteCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// DescribeConversionWorkspaceRevisions: Retrieves a list of committed
// revisions of a specific conversion workspace.
//
//   - conversionWorkspace: Name of the conversion workspace resource whose
//     revisions are listed. Must be in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) DescribeConversionWorkspaceRevisions(conversionWorkspace string) *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall {
	c := &ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.conversionWorkspace = conversionWorkspace
	return c
}

// CommitId sets the optional parameter "commitId": Optional filter to request
// a specific commit ID.
func (c *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall) CommitId(commitId string) *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall {
	c.urlParams_.Set("commitId", commitId)
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+conversionWorkspace}:describeConversionWorkspaceRevisions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"conversionWorkspace": c.conversionWorkspace,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.describeConversionWorkspaceRevisions", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.describeConversionWorkspaceRevisions" call.
// Any non-2xx status code is an error. Response headers are in either
// *DescribeConversionWorkspaceRevisionsResponse.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 *ProjectsLocationsConversionWorkspacesDescribeConversionWorkspaceRevisionsCall) Do(opts ...googleapi.CallOption) (*DescribeConversionWorkspaceRevisionsResponse, 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 := &DescribeConversionWorkspaceRevisionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.describeConversionWorkspaceRevisions", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// DescribeDatabaseEntities: Describes the database entities tree for a
// specific conversion workspace and a specific tree type. Database entities
// are not resources like conversion workspaces or mapping rules, and they
// can't be created, updated or deleted. Instead, they are simple data objects
// describing the structure of the client database.
//
//   - conversionWorkspace: Name of the conversion workspace resource whose
//     database entities are described. Must be in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) DescribeDatabaseEntities(conversionWorkspace string) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c := &ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.conversionWorkspace = conversionWorkspace
	return c
}

// CommitId sets the optional parameter "commitId": Request a specific commit
// ID. If not specified, the entities from the latest commit are returned.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) CommitId(commitId string) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.urlParams_.Set("commitId", commitId)
	return c
}

// Filter sets the optional parameter "filter": Filter the returned entities
// based on AIP-160 standard.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) Filter(filter string) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// entities to return. The service may return fewer entities than the value
// specifies.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) PageSize(pageSize int64) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The nextPageToken value
// received in the previous call to
// conversionWorkspace.describeDatabaseEntities, used in the subsequent request
// to retrieve the next page of results. On first call this should be left
// blank. When paginating, all other parameters provided to
// conversionWorkspace.describeDatabaseEntities must match the call that
// provided the page token.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) PageToken(pageToken string) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Tree sets the optional parameter "tree": Required. The tree to fetch.
//
// Possible values:
//
//	"DB_TREE_TYPE_UNSPECIFIED" - Unspecified tree type.
//	"SOURCE_TREE" - The source database tree.
//	"DRAFT_TREE" - The draft database tree.
//	"DESTINATION_TREE" - The destination database tree.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) Tree(tree string) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.urlParams_.Set("tree", tree)
	return c
}

// Uncommitted sets the optional parameter "uncommitted": Whether to retrieve
// the latest committed version of the entities or the latest version. This
// field is ignored if a specific commit_id is specified.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) Uncommitted(uncommitted bool) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.urlParams_.Set("uncommitted", fmt.Sprint(uncommitted))
	return c
}

// View sets the optional parameter "view": Results view based on AIP-157
//
// Possible values:
//
//	"DATABASE_ENTITY_VIEW_UNSPECIFIED" - Unspecified view. Defaults to basic
//
// view.
//
//	"DATABASE_ENTITY_VIEW_BASIC" - Default view. Does not return DDLs or
//
// Issues.
//
//	"DATABASE_ENTITY_VIEW_FULL" - Return full entity details including
//
// mappings, ddl and issues.
//
//	"DATABASE_ENTITY_VIEW_ROOT_SUMMARY" - Top-most (Database, Schema) nodes
//
// which are returned contains summary details for their descendants such as
// the number of entities per type and issues rollups. When this view is used,
// only a single page of result is returned and the page_size property of the
// request is ignored. The returned page will only include the top-most node
// types.
//
//	"DATABASE_ENTITY_VIEW_FULL_COMPACT" - Returns full entity details except
//
// for ddls and schema custom features.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) View(view string) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.urlParams_.Set("view", view)
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+conversionWorkspace}:describeDatabaseEntities")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"conversionWorkspace": c.conversionWorkspace,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.describeDatabaseEntities", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.describeDatabaseEntities" call.
// Any non-2xx status code is an error. Response headers are in either
// *DescribeDatabaseEntitiesResponse.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 *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) Do(opts ...googleapi.CallOption) (*DescribeDatabaseEntitiesResponse, 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 := &DescribeDatabaseEntitiesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.describeDatabaseEntities", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsConversionWorkspacesDescribeDatabaseEntitiesCall) Pages(ctx context.Context, f func(*DescribeDatabaseEntitiesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

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

// FetchEntitiesStatusView: An internal, RPC only method that returns a list of
// the (filtered) entities with minimal information required for the entities
// tree view.
//
//   - conversionWorkspace: Name of the conversion workspace resource whose
//     database entities are described. Must be in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) FetchEntitiesStatusView(conversionWorkspace string) *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall {
	c := &ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.conversionWorkspace = conversionWorkspace
	return c
}

// FetchView sets the optional parameter "fetchView": The view to fetch. If not
// specified, FULL is used.
//
// Possible values:
//
//	"FETCH_VIEW_UNSPECIFIED" - Unspecified view. Defaults to FULL.
//	"FULL" - Get all entities matching the filter.
//	"SUMMARY" - Each schema will have one entity per (non sub) type with a
//
// dummy name that will contain the aggregated information for all entities of
// that type. Counters like number of statements and issues will be aggregated
// accordingly.
//
//	"FULL_WITH_DEPENDENCIES" - Same as FULL plus dependency information.
func (c *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) FetchView(fetchView string) *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall {
	c.urlParams_.Set("fetchView", fetchView)
	return c
}

// Filter sets the optional parameter "filter": Filter the returned entities
// based on AIP-160 standard.
func (c *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) Filter(filter string) *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// entities to return. The service may return fewer entities than the value
// specifies. Default is 100000.
func (c *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) PageSize(pageSize int64) *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The nextPageToken value
// received in the previous call to
// conversionWorkspace.FetchEntitiesStatusView, used in the subsequent request
// to retrieve the next page of results. On first call this should be left
// blank. When paginating, all other parameters provided to
// conversionWorkspace.FetchEntitiesStatusView must match the call that
// provided the page token, except for the page_size parameter.
func (c *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) PageToken(pageToken string) *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Tree sets the optional parameter "tree": Required. The tree to fetch.
//
// Possible values:
//
//	"DB_TREE_TYPE_UNSPECIFIED" - Unspecified tree type.
//	"SOURCE_TREE" - The source database tree.
//	"DRAFT_TREE" - The draft database tree.
func (c *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) Tree(tree string) *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall {
	c.urlParams_.Set("tree", tree)
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+conversionWorkspace}:fetchEntitiesStatusView")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"conversionWorkspace": c.conversionWorkspace,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.fetchEntitiesStatusView", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.fetchEntitiesStatusView" call.
// Any non-2xx status code is an error. Response headers are in either
// *FetchEntitiesStatusViewResponse.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 *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) Do(opts ...googleapi.CallOption) (*FetchEntitiesStatusViewResponse, 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 := &FetchEntitiesStatusViewResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.fetchEntitiesStatusView", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsConversionWorkspacesFetchEntitiesStatusViewCall) Pages(ctx context.Context, f func(*FetchEntitiesStatusViewResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

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

// FetchIssues: List issues of conversion workspace operations e.g. conversion.
//
//   - conversionWorkspace: Conversion workspace with issues to fetch. Must be in
//     the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) FetchIssues(conversionWorkspace string) *ProjectsLocationsConversionWorkspacesFetchIssuesCall {
	c := &ProjectsLocationsConversionWorkspacesFetchIssuesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.conversionWorkspace = conversionWorkspace
	return c
}

// AllIssues sets the optional parameter "allIssues": If 'true', gets all
// issues matching the filter. Otherwise, for each entity only the issues
// matching the DdlKind chosen for application on the destination are returned.
func (c *ProjectsLocationsConversionWorkspacesFetchIssuesCall) AllIssues(allIssues bool) *ProjectsLocationsConversionWorkspacesFetchIssuesCall {
	c.urlParams_.Set("allIssues", fmt.Sprint(allIssues))
	return c
}

// Filter sets the optional parameter "filter": AIP-160 standard filter.
// Supporting both entity and issue fields. Supported fields: - `name` /
// `fullname`: The entity full name. - `type`: The entity type (e.g. `TABLE`,
// `VIEW`, `INDEX`, `TRIGGER`). - `ddlkind`: The kind of DDL (e.g.
// `DDL_KIND_SOURCE`, `DDL_KIND_AI`, `DDL_KIND_DETERMINISTIC`). -
// `issue.severity`: The severity of the issue (e.g. `INFO`, `WARNING`,
// `ERROR`). - `issue.state`: The state of the issue (e.g. `OPEN`, `RESOLVED`).
// - `issue.origin`: The origin of the issue (e.g. `DETERMINISTIC`, `AI`). -
// `issue.category_id`: The category ID of the issue. - `issue.group_id`: The
// group ID of the issue.
func (c *ProjectsLocationsConversionWorkspacesFetchIssuesCall) Filter(filter string) *ProjectsLocationsConversionWorkspacesFetchIssuesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// issues to return. The service may return fewer issues than the value
// specifies.
func (c *ProjectsLocationsConversionWorkspacesFetchIssuesCall) PageSize(pageSize int64) *ProjectsLocationsConversionWorkspacesFetchIssuesCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// FetchIssuesResponse.next_page_token value received in the previous call to
// FetchIssues, used in the subsequent request to retrieve the next page of
// results. On first call this should be left blank. When paginating, all other
// parameters provided to FetchIssues must match the call that provided the
// page token, except for the page_size parameter.
func (c *ProjectsLocationsConversionWorkspacesFetchIssuesCall) PageToken(pageToken string) *ProjectsLocationsConversionWorkspacesFetchIssuesCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Tree sets the optional parameter "tree": The tree to fetch issues from. If
// not specified, source tree is assumed.
//
// Possible values:
//
//	"DB_TREE_TYPE_UNSPECIFIED" - Unspecified tree type.
//	"SOURCE" - Returns seed and conversion issues
//	"DRAFT" - Returns apply issues.
func (c *ProjectsLocationsConversionWorkspacesFetchIssuesCall) Tree(tree string) *ProjectsLocationsConversionWorkspacesFetchIssuesCall {
	c.urlParams_.Set("tree", tree)
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesFetchIssuesCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesFetchIssuesCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesFetchIssuesCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesFetchIssuesCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesFetchIssuesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+conversionWorkspace}:fetchIssues")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"conversionWorkspace": c.conversionWorkspace,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.fetchIssues", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.fetchIssues" call.
// Any non-2xx status code is an error. Response headers are in either
// *FetchIssuesResponse.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 *ProjectsLocationsConversionWorkspacesFetchIssuesCall) Do(opts ...googleapi.CallOption) (*FetchIssuesResponse, 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 := &FetchIssuesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.fetchIssues", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsConversionWorkspacesFetchIssuesCall) Pages(ctx context.Context, f func(*FetchIssuesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

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

// Get: Gets details of a single conversion workspace.
//
// - name: Name of the conversion workspace resource to get.
func (r *ProjectsLocationsConversionWorkspacesService) Get(name string) *ProjectsLocationsConversionWorkspacesGetCall {
	c := &ProjectsLocationsConversionWorkspacesGetCall{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
// details.
func (c *ProjectsLocationsConversionWorkspacesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsConversionWorkspacesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesGetCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *ConversionWorkspace.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 *ProjectsLocationsConversionWorkspacesGetCall) Do(opts ...googleapi.CallOption) (*ConversionWorkspace, 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 := &ConversionWorkspace{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// GetIamPolicy: Gets the access control policy for a resource. Returns an
// empty policy if the resource exists and does not have a policy set.
//
//   - resource: REQUIRED: The resource for which the policy is being requested.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsConversionWorkspacesService) GetIamPolicy(resource string) *ProjectsLocationsConversionWorkspacesGetIamPolicyCall {
	c := &ProjectsLocationsConversionWorkspacesGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// OptionsRequestedPolicyVersion sets the optional parameter
// "options.requestedPolicyVersion": The maximum policy version that will be
// used to format the policy. Valid values are 0, 1, and 3. Requests specifying
// an invalid value will be rejected. Requests for policies with any
// conditional role bindings must specify version 3. Policies with no
// conditional role bindings may specify any valid value or leave the field
// unset. The policy in the response might use the policy version that you
// specified, or it might use a lower policy version. For example, if you
// specify version 3, but the policy has no conditional role bindings, the
// response uses version 1. To learn which resources support conditions in
// their IAM policies, see the IAM documentation
// (https://cloud.google.com/iam/help/conditions/resource-policies).
func (c *ProjectsLocationsConversionWorkspacesGetIamPolicyCall) OptionsRequestedPolicyVersion(optionsRequestedPolicyVersion int64) *ProjectsLocationsConversionWorkspacesGetIamPolicyCall {
	c.urlParams_.Set("options.requestedPolicyVersion", fmt.Sprint(optionsRequestedPolicyVersion))
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesGetIamPolicyCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesGetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.getIamPolicy", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.getIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.getIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists conversion workspaces in a given project and location.
//
// - parent: The parent which owns this collection of conversion workspaces.
func (r *ProjectsLocationsConversionWorkspacesService) List(parent string) *ProjectsLocationsConversionWorkspacesListCall {
	c := &ProjectsLocationsConversionWorkspacesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters conversion workspaces listed in the response. The expression must
// specify the field name, a comparison operator, and the value that you want
// to use for filtering. The value must be a string, a number, or a boolean.
// The comparison operator must be either =, !=, >, or <. For example, list
// conversion workspaces created this year by specifying **createTime %gt;
// 2020-01-01T00:00:00.000000000Z.** You can also filter nested fields. For
// example, you could specify **source.version = "12.c.1"** to select all
// conversion workspaces with source database version equal to 12.c.1.
func (c *ProjectsLocationsConversionWorkspacesListCall) Filter(filter string) *ProjectsLocationsConversionWorkspacesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// conversion workspaces to return. The service may return fewer than this
// value. If unspecified, at most 50 sets are returned.
func (c *ProjectsLocationsConversionWorkspacesListCall) PageSize(pageSize int64) *ProjectsLocationsConversionWorkspacesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The nextPageToken value
// received in the previous call to conversionWorkspaces.list, used in the
// subsequent request to retrieve the next page of results. On first call this
// should be left blank. When paginating, all other parameters provided to
// conversionWorkspaces.list must match the call that provided the page token.
func (c *ProjectsLocationsConversionWorkspacesListCall) PageToken(pageToken string) *ProjectsLocationsConversionWorkspacesListCall {
	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
// details.
func (c *ProjectsLocationsConversionWorkspacesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsConversionWorkspacesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesListCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/conversionWorkspaces")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListConversionWorkspacesResponse.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 *ProjectsLocationsConversionWorkspacesListCall) Do(opts ...googleapi.CallOption) (*ListConversionWorkspacesResponse, 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 := &ListConversionWorkspacesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsConversionWorkspacesListCall) Pages(ctx context.Context, f func(*ListConversionWorkspacesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

type ProjectsLocationsConversionWorkspacesPatchCall struct {
	s                   *Service
	name                string
	conversionworkspace *ConversionWorkspace
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// Patch: Updates the parameters of a single conversion workspace.
//
//   - name: Full name of the workspace resource, in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) Patch(name string, conversionworkspace *ConversionWorkspace) *ProjectsLocationsConversionWorkspacesPatchCall {
	c := &ProjectsLocationsConversionWorkspacesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.conversionworkspace = conversionworkspace
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsConversionWorkspacesPatchCall) RequestId(requestId string) *ProjectsLocationsConversionWorkspacesPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. Field mask is
// used to specify the fields to be overwritten by the update in the conversion
// workspace resource.
func (c *ProjectsLocationsConversionWorkspacesPatchCall) UpdateMask(updateMask string) *ProjectsLocationsConversionWorkspacesPatchCall {
	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
// details.
func (c *ProjectsLocationsConversionWorkspacesPatchCall) Fields(s ...googleapi.Field) *ProjectsLocationsConversionWorkspacesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesPatchCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesPatchCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.conversionworkspace)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesRollbackCall struct {
	s                                  *Service
	name                               string
	rollbackconversionworkspacerequest *RollbackConversionWorkspaceRequest
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// Rollback: Rolls back a conversion workspace to the last committed snapshot.
//
// - name: Name of the conversion workspace resource to roll back to.
func (r *ProjectsLocationsConversionWorkspacesService) Rollback(name string, rollbackconversionworkspacerequest *RollbackConversionWorkspaceRequest) *ProjectsLocationsConversionWorkspacesRollbackCall {
	c := &ProjectsLocationsConversionWorkspacesRollbackCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.rollbackconversionworkspacerequest = rollbackconversionworkspacerequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesRollbackCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesRollbackCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesRollbackCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.rollbackconversionworkspacerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:rollback")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.rollback", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.rollback" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesRollbackCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.rollback", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// SearchBackgroundJobs: Searches/lists the background jobs for a specific
// conversion workspace. The background jobs are not resources like conversion
// workspaces or mapping rules, and they can't be created, updated or deleted.
// Instead, they are a way to expose the data plane jobs log.
//
//   - conversionWorkspace: Name of the conversion workspace resource whose jobs
//     are listed, in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) SearchBackgroundJobs(conversionWorkspace string) *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall {
	c := &ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.conversionWorkspace = conversionWorkspace
	return c
}

// CompletedUntilTime sets the optional parameter "completedUntilTime": If
// provided, only returns jobs that completed until (not including) the given
// timestamp.
func (c *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall) CompletedUntilTime(completedUntilTime string) *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall {
	c.urlParams_.Set("completedUntilTime", completedUntilTime)
	return c
}

// MaxSize sets the optional parameter "maxSize": The maximum number of jobs to
// return. The service may return fewer than this value. If unspecified, at
// most 100 jobs are returned. The maximum value is 100; values above 100 are
// coerced to 100.
func (c *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall) MaxSize(maxSize int64) *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall {
	c.urlParams_.Set("maxSize", fmt.Sprint(maxSize))
	return c
}

// ReturnMostRecentPerJobType sets the optional parameter
// "returnMostRecentPerJobType": Whether or not to return just the most recent
// job per job type,
func (c *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall) ReturnMostRecentPerJobType(returnMostRecentPerJobType bool) *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall {
	c.urlParams_.Set("returnMostRecentPerJobType", fmt.Sprint(returnMostRecentPerJobType))
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+conversionWorkspace}:searchBackgroundJobs")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"conversionWorkspace": c.conversionWorkspace,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.searchBackgroundJobs", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.searchBackgroundJobs" call.
// Any non-2xx status code is an error. Response headers are in either
// *SearchBackgroundJobsResponse.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 *ProjectsLocationsConversionWorkspacesSearchBackgroundJobsCall) Do(opts ...googleapi.CallOption) (*SearchBackgroundJobsResponse, 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 := &SearchBackgroundJobsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.searchBackgroundJobs", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesSeedCall struct {
	s                              *Service
	name                           string
	seedconversionworkspacerequest *SeedConversionWorkspaceRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Seed: Imports a snapshot of the source database into the conversion
// workspace.
//
//   - name: Name of the conversion workspace resource to seed with new database
//     structure, in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) Seed(name string, seedconversionworkspacerequest *SeedConversionWorkspaceRequest) *ProjectsLocationsConversionWorkspacesSeedCall {
	c := &ProjectsLocationsConversionWorkspacesSeedCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.seedconversionworkspacerequest = seedconversionworkspacerequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesSeedCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesSeedCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesSeedCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.seedconversionworkspacerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:seed")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.seed", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.seed" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesSeedCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.seed", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesSetDraftEntityDdlCall struct {
	s                        *Service
	conversionWorkspace      string
	setdraftentityddlrequest *SetDraftEntityDdlRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// SetDraftEntityDdl: Updates the draft DDL of an entity.
//
//   - conversionWorkspace: Name of the conversion workspace resource in the form
//     of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesService) SetDraftEntityDdl(conversionWorkspace string, setdraftentityddlrequest *SetDraftEntityDdlRequest) *ProjectsLocationsConversionWorkspacesSetDraftEntityDdlCall {
	c := &ProjectsLocationsConversionWorkspacesSetDraftEntityDdlCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.conversionWorkspace = conversionWorkspace
	c.setdraftentityddlrequest = setdraftentityddlrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesSetDraftEntityDdlCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesSetDraftEntityDdlCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesSetDraftEntityDdlCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.setdraftentityddlrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+conversionWorkspace}:setDraftEntityDdl")
	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{
		"conversionWorkspace": c.conversionWorkspace,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.setDraftEntityDdl", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.setDraftEntityDdl" call.
// Any non-2xx status code is an error. Response headers are in either
// *SetDraftEntityDdlResponse.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 *ProjectsLocationsConversionWorkspacesSetDraftEntityDdlCall) Do(opts ...googleapi.CallOption) (*SetDraftEntityDdlResponse, 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 := &SetDraftEntityDdlResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.setDraftEntityDdl", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesSetIamPolicyCall struct {
	s                   *Service
	resource            string
	setiampolicyrequest *SetIamPolicyRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// SetIamPolicy: Sets the access control policy on the specified resource.
// Replaces any existing policy. Can return `NOT_FOUND`, `INVALID_ARGUMENT`,
// and `PERMISSION_DENIED` errors.
//
//   - resource: REQUIRED: The resource for which the policy is being specified.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsConversionWorkspacesService) SetIamPolicy(resource string, setiampolicyrequest *SetIamPolicyRequest) *ProjectsLocationsConversionWorkspacesSetIamPolicyCall {
	c := &ProjectsLocationsConversionWorkspacesSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.setiampolicyrequest = setiampolicyrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesSetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.setiampolicyrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.setIamPolicy", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.setIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.setIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesTestIamPermissionsCall struct {
	s                         *Service
	resource                  string
	testiampermissionsrequest *TestIamPermissionsRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the specified
// resource. If the resource does not exist, this will return an empty set of
// permissions, not a `NOT_FOUND` error. Note: This operation is designed to be
// used for building permission-aware UIs and command-line tools, not for
// authorization checking. This operation may "fail open" without warning.
//
//   - resource: REQUIRED: The resource for which the policy detail is being
//     requested. See Resource names
//     (https://cloud.google.com/apis/design/resource_names) for the appropriate
//     value for this field.
func (r *ProjectsLocationsConversionWorkspacesService) TestIamPermissions(resource string, testiampermissionsrequest *TestIamPermissionsRequest) *ProjectsLocationsConversionWorkspacesTestIamPermissionsCall {
	c := &ProjectsLocationsConversionWorkspacesTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.testiampermissionsrequest = testiampermissionsrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesTestIamPermissionsCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.testiampermissionsrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.testIamPermissions", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.testIamPermissions" call.
// Any non-2xx status code is an error. Response headers are in either
// *TestIamPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &TestIamPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.testIamPermissions", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesMappingRulesCreateCall struct {
	s           *Service
	parent      string
	mappingrule *MappingRule
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Create: Creates a new mapping rule for a given conversion workspace.
//
// - parent: The parent which owns this collection of mapping rules.
func (r *ProjectsLocationsConversionWorkspacesMappingRulesService) Create(parent string, mappingrule *MappingRule) *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall {
	c := &ProjectsLocationsConversionWorkspacesMappingRulesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.mappingrule = mappingrule
	return c
}

// MappingRuleId sets the optional parameter "mappingRuleId": Required. The ID
// of the rule to create.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall) MappingRuleId(mappingRuleId string) *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall {
	c.urlParams_.Set("mappingRuleId", mappingRuleId)
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall) RequestId(requestId string) *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.mappingrule)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/mappingRules")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.mappingRules.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *MappingRule.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 *ProjectsLocationsConversionWorkspacesMappingRulesCreateCall) Do(opts ...googleapi.CallOption) (*MappingRule, 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 := &MappingRule{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes a single mapping rule.
//
// - name: Name of the mapping rule resource to delete.
func (r *ProjectsLocationsConversionWorkspacesMappingRulesService) Delete(name string) *ProjectsLocationsConversionWorkspacesMappingRulesDeleteCall {
	c := &ProjectsLocationsConversionWorkspacesMappingRulesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesDeleteCall) RequestId(requestId string) *ProjectsLocationsConversionWorkspacesMappingRulesDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesDeleteCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesMappingRulesDeleteCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesMappingRulesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.mappingRules.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Gets the details of a mapping rule.
//
//   - name: Name of the mapping rule resource to get. Example:
//     conversionWorkspaces/123/mappingRules/rule123 In order to retrieve a
//     previous revision of the mapping rule, also provide the revision ID.
//     Example:
//     conversionWorkspace/123/mappingRules/rule123@c7cfa2a8c7cfa2a8c7cfa2a8c7cfa2
//     a8.
func (r *ProjectsLocationsConversionWorkspacesMappingRulesService) Get(name string) *ProjectsLocationsConversionWorkspacesMappingRulesGetCall {
	c := &ProjectsLocationsConversionWorkspacesMappingRulesGetCall{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
// details.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsConversionWorkspacesMappingRulesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesMappingRulesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesGetCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesMappingRulesGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesMappingRulesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.mappingRules.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *MappingRule.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 *ProjectsLocationsConversionWorkspacesMappingRulesGetCall) Do(opts ...googleapi.CallOption) (*MappingRule, 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 := &MappingRule{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsConversionWorkspacesMappingRulesImportCall struct {
	s                         *Service
	parent                    string
	importmappingrulesrequest *ImportMappingRulesRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Import: Imports the mapping rules for a given conversion workspace. Supports
// various formats of external rules files.
//
//   - parent: Name of the conversion workspace resource to import the rules to
//     in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesMappingRulesService) Import(parent string, importmappingrulesrequest *ImportMappingRulesRequest) *ProjectsLocationsConversionWorkspacesMappingRulesImportCall {
	c := &ProjectsLocationsConversionWorkspacesMappingRulesImportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.importmappingrulesrequest = importmappingrulesrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesImportCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesMappingRulesImportCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesMappingRulesImportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.importmappingrulesrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/mappingRules:import")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.import", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.mappingRules.import" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesImportCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.import", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists the mapping rules for a specific conversion workspace.
//
//   - parent: Name of the conversion workspace resource whose mapping rules are
//     listed in the form of:
//     projects/{project}/locations/{location}/conversionWorkspaces/{conversion_wo
//     rkspace}.
func (r *ProjectsLocationsConversionWorkspacesMappingRulesService) List(parent string) *ProjectsLocationsConversionWorkspacesMappingRulesListCall {
	c := &ProjectsLocationsConversionWorkspacesMappingRulesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of rules
// to return. The service may return fewer than this value.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesListCall) PageSize(pageSize int64) *ProjectsLocationsConversionWorkspacesMappingRulesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The nextPageToken value
// received in the previous call to mappingRules.list, used in the subsequent
// request to retrieve the next page of results. On first call this should be
// left blank. When paginating, all other parameters provided to
// mappingRules.list must match the call that provided the page token.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesListCall) PageToken(pageToken string) *ProjectsLocationsConversionWorkspacesMappingRulesListCall {
	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
// details.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsConversionWorkspacesMappingRulesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsConversionWorkspacesMappingRulesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsConversionWorkspacesMappingRulesListCall) Context(ctx context.Context) *ProjectsLocationsConversionWorkspacesMappingRulesListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsConversionWorkspacesMappingRulesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/mappingRules")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.conversionWorkspaces.mappingRules.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListMappingRulesResponse.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 *ProjectsLocationsConversionWorkspacesMappingRulesListCall) Do(opts ...googleapi.CallOption) (*ListMappingRulesResponse, 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 := &ListMappingRulesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.conversionWorkspaces.mappingRules.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsConversionWorkspacesMappingRulesListCall) Pages(ctx context.Context, f func(*ListMappingRulesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

type ProjectsLocationsMigrationJobsCreateCall struct {
	s            *Service
	parent       string
	migrationjob *MigrationJob
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a new migration job in a given project and location.
//
// - parent: The parent which owns this collection of migration jobs.
func (r *ProjectsLocationsMigrationJobsService) Create(parent string, migrationjob *MigrationJob) *ProjectsLocationsMigrationJobsCreateCall {
	c := &ProjectsLocationsMigrationJobsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.migrationjob = migrationjob
	return c
}

// MigrationJobId sets the optional parameter "migrationJobId": Required. The
// ID of the instance to create.
func (c *ProjectsLocationsMigrationJobsCreateCall) MigrationJobId(migrationJobId string) *ProjectsLocationsMigrationJobsCreateCall {
	c.urlParams_.Set("migrationJobId", migrationJobId)
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsMigrationJobsCreateCall) RequestId(requestId string) *ProjectsLocationsMigrationJobsCreateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsCreateCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsCreateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.migrationjob)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/migrationJobs")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes a single migration job.
//
// - name: Name of the migration job resource to delete.
func (r *ProjectsLocationsMigrationJobsService) Delete(name string) *ProjectsLocationsMigrationJobsDeleteCall {
	c := &ProjectsLocationsMigrationJobsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Force sets the optional parameter "force": The destination CloudSQL
// connection profile is always deleted with the migration job. In case of
// force delete, the destination CloudSQL replica database is also deleted.
func (c *ProjectsLocationsMigrationJobsDeleteCall) Force(force bool) *ProjectsLocationsMigrationJobsDeleteCall {
	c.urlParams_.Set("force", fmt.Sprint(force))
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsMigrationJobsDeleteCall) RequestId(requestId string) *ProjectsLocationsMigrationJobsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsDeleteCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsDeleteCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsDemoteDestinationCall struct {
	s                        *Service
	name                     string
	demotedestinationrequest *DemoteDestinationRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// DemoteDestination: Demotes the destination database to become a read replica
// of the source. This is applicable for the following migrations: 1. MySQL to
// Cloud SQL for MySQL 2. PostgreSQL to Cloud SQL for PostgreSQL 3. PostgreSQL
// to AlloyDB for PostgreSQL.
//
// - name: Name of the migration job resource to demote its destination.
func (r *ProjectsLocationsMigrationJobsService) DemoteDestination(name string, demotedestinationrequest *DemoteDestinationRequest) *ProjectsLocationsMigrationJobsDemoteDestinationCall {
	c := &ProjectsLocationsMigrationJobsDemoteDestinationCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.demotedestinationrequest = demotedestinationrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsDemoteDestinationCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsDemoteDestinationCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsDemoteDestinationCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.demotedestinationrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:demoteDestination")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.demoteDestination", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.demoteDestination" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsDemoteDestinationCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.demoteDestination", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// FetchSourceObjects: Retrieves objects from the source database that can be
// selected for data migration. This is applicable for the following
// migrations: 1. PostgreSQL to Cloud SQL for PostgreSQL 2. PostgreSQL to
// AlloyDB for PostgreSQL.
//
//   - name: The resource name for the migration job for which source objects
//     should be returned.
func (r *ProjectsLocationsMigrationJobsService) FetchSourceObjects(name string) *ProjectsLocationsMigrationJobsFetchSourceObjectsCall {
	c := &ProjectsLocationsMigrationJobsFetchSourceObjectsCall{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
// details.
func (c *ProjectsLocationsMigrationJobsFetchSourceObjectsCall) Fields(s ...googleapi.Field) *ProjectsLocationsMigrationJobsFetchSourceObjectsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsMigrationJobsFetchSourceObjectsCall) IfNoneMatch(entityTag string) *ProjectsLocationsMigrationJobsFetchSourceObjectsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsFetchSourceObjectsCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsFetchSourceObjectsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsFetchSourceObjectsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:fetchSourceObjects")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.fetchSourceObjects", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.fetchSourceObjects" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsFetchSourceObjectsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.fetchSourceObjects", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsGenerateSshScriptCall struct {
	s                        *Service
	migrationJob             string
	generatesshscriptrequest *GenerateSshScriptRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// GenerateSshScript: Generate a SSH configuration script to configure the
// reverse SSH connectivity.
//
//   - migrationJob: Name of the migration job resource to generate the SSH
//     script.
func (r *ProjectsLocationsMigrationJobsService) GenerateSshScript(migrationJob string, generatesshscriptrequest *GenerateSshScriptRequest) *ProjectsLocationsMigrationJobsGenerateSshScriptCall {
	c := &ProjectsLocationsMigrationJobsGenerateSshScriptCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.migrationJob = migrationJob
	c.generatesshscriptrequest = generatesshscriptrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsGenerateSshScriptCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsGenerateSshScriptCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsGenerateSshScriptCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.generatesshscriptrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+migrationJob}:generateSshScript")
	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{
		"migrationJob": c.migrationJob,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.generateSshScript", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.generateSshScript" call.
// Any non-2xx status code is an error. Response headers are in either
// *SshScript.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 *ProjectsLocationsMigrationJobsGenerateSshScriptCall) Do(opts ...googleapi.CallOption) (*SshScript, 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 := &SshScript{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.generateSshScript", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsGenerateTcpProxyScriptCall struct {
	s                             *Service
	migrationJob                  string
	generatetcpproxyscriptrequest *GenerateTcpProxyScriptRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// GenerateTcpProxyScript: Generate a TCP Proxy configuration script to
// configure a cloud-hosted VM running a TCP Proxy.
//
//   - migrationJob: Name of the migration job resource to generate the TCP Proxy
//     script.
func (r *ProjectsLocationsMigrationJobsService) GenerateTcpProxyScript(migrationJob string, generatetcpproxyscriptrequest *GenerateTcpProxyScriptRequest) *ProjectsLocationsMigrationJobsGenerateTcpProxyScriptCall {
	c := &ProjectsLocationsMigrationJobsGenerateTcpProxyScriptCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.migrationJob = migrationJob
	c.generatetcpproxyscriptrequest = generatetcpproxyscriptrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsGenerateTcpProxyScriptCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsGenerateTcpProxyScriptCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsGenerateTcpProxyScriptCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.generatetcpproxyscriptrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+migrationJob}:generateTcpProxyScript")
	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{
		"migrationJob": c.migrationJob,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.generateTcpProxyScript", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.generateTcpProxyScript" call.
// Any non-2xx status code is an error. Response headers are in either
// *TcpProxyScript.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 *ProjectsLocationsMigrationJobsGenerateTcpProxyScriptCall) Do(opts ...googleapi.CallOption) (*TcpProxyScript, 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 := &TcpProxyScript{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.generateTcpProxyScript", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Gets details of a single migration job.
//
// - name: Name of the migration job resource to get.
func (r *ProjectsLocationsMigrationJobsService) Get(name string) *ProjectsLocationsMigrationJobsGetCall {
	c := &ProjectsLocationsMigrationJobsGetCall{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
// details.
func (c *ProjectsLocationsMigrationJobsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsMigrationJobsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsMigrationJobsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsMigrationJobsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsGetCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *MigrationJob.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 *ProjectsLocationsMigrationJobsGetCall) Do(opts ...googleapi.CallOption) (*MigrationJob, 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 := &MigrationJob{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// GetIamPolicy: Gets the access control policy for a resource. Returns an
// empty policy if the resource exists and does not have a policy set.
//
//   - resource: REQUIRED: The resource for which the policy is being requested.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsMigrationJobsService) GetIamPolicy(resource string) *ProjectsLocationsMigrationJobsGetIamPolicyCall {
	c := &ProjectsLocationsMigrationJobsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// OptionsRequestedPolicyVersion sets the optional parameter
// "options.requestedPolicyVersion": The maximum policy version that will be
// used to format the policy. Valid values are 0, 1, and 3. Requests specifying
// an invalid value will be rejected. Requests for policies with any
// conditional role bindings must specify version 3. Policies with no
// conditional role bindings may specify any valid value or leave the field
// unset. The policy in the response might use the policy version that you
// specified, or it might use a lower policy version. For example, if you
// specify version 3, but the policy has no conditional role bindings, the
// response uses version 1. To learn which resources support conditions in
// their IAM policies, see the IAM documentation
// (https://cloud.google.com/iam/help/conditions/resource-policies).
func (c *ProjectsLocationsMigrationJobsGetIamPolicyCall) OptionsRequestedPolicyVersion(optionsRequestedPolicyVersion int64) *ProjectsLocationsMigrationJobsGetIamPolicyCall {
	c.urlParams_.Set("options.requestedPolicyVersion", fmt.Sprint(optionsRequestedPolicyVersion))
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsMigrationJobsGetIamPolicyCall) IfNoneMatch(entityTag string) *ProjectsLocationsMigrationJobsGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsGetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.getIamPolicy", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.getIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.getIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists migration jobs in a given project and location.
//
// - parent: The parent which owns this collection of migrationJobs.
func (r *ProjectsLocationsMigrationJobsService) List(parent string) *ProjectsLocationsMigrationJobsListCall {
	c := &ProjectsLocationsMigrationJobsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters migration jobs listed in the response. The expression must specify
// the field name, a comparison operator, and the value that you want to use
// for filtering. The value must be a string, a number, or a boolean. The
// comparison operator must be either =, !=, >, or <. For example, list
// migration jobs created this year by specifying **createTime %gt;
// 2020-01-01T00:00:00.000000000Z.** You can also filter nested fields. For
// example, you could specify **reverseSshConnectivity.vmIp = "1.2.3.4"** to
// select all migration jobs connecting through the specific SSH tunnel
// bastion.
func (c *ProjectsLocationsMigrationJobsListCall) Filter(filter string) *ProjectsLocationsMigrationJobsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Sort the results based on the
// migration job name. Valid values are: "name", "name asc", and "name desc".
func (c *ProjectsLocationsMigrationJobsListCall) OrderBy(orderBy string) *ProjectsLocationsMigrationJobsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// migration jobs to return. The service may return fewer than this value. If
// unspecified, at most 50 migration jobs will be returned. The maximum value
// is 1000; values above 1000 are coerced to 1000.
func (c *ProjectsLocationsMigrationJobsListCall) PageSize(pageSize int64) *ProjectsLocationsMigrationJobsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The nextPageToken value
// received in the previous call to migrationJobs.list, used in the subsequent
// request to retrieve the next page of results. On first call this should be
// left blank. When paginating, all other parameters provided to
// migrationJobs.list must match the call that provided the page token.
func (c *ProjectsLocationsMigrationJobsListCall) PageToken(pageToken string) *ProjectsLocationsMigrationJobsListCall {
	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
// details.
func (c *ProjectsLocationsMigrationJobsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsMigrationJobsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsMigrationJobsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsMigrationJobsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsListCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/migrationJobs")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListMigrationJobsResponse.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 *ProjectsLocationsMigrationJobsListCall) Do(opts ...googleapi.CallOption) (*ListMigrationJobsResponse, 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 := &ListMigrationJobsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsMigrationJobsListCall) Pages(ctx context.Context, f func(*ListMigrationJobsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

type ProjectsLocationsMigrationJobsPatchCall struct {
	s            *Service
	name         string
	migrationjob *MigrationJob
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Patch: Updates the parameters of a single migration job.
//
//   - name: The name (URI) of this migration job resource, in the form of:
//     projects/{project}/locations/{location}/migrationJobs/{migrationJob}.
func (r *ProjectsLocationsMigrationJobsService) Patch(name string, migrationjob *MigrationJob) *ProjectsLocationsMigrationJobsPatchCall {
	c := &ProjectsLocationsMigrationJobsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.migrationjob = migrationjob
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsMigrationJobsPatchCall) RequestId(requestId string) *ProjectsLocationsMigrationJobsPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. Field mask is
// used to specify the fields to be overwritten by the update in the conversion
// workspace resource.
func (c *ProjectsLocationsMigrationJobsPatchCall) UpdateMask(updateMask string) *ProjectsLocationsMigrationJobsPatchCall {
	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
// details.
func (c *ProjectsLocationsMigrationJobsPatchCall) Fields(s ...googleapi.Field) *ProjectsLocationsMigrationJobsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsPatchCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsPatchCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.migrationjob)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsPromoteCall struct {
	s                          *Service
	name                       string
	promotemigrationjobrequest *PromoteMigrationJobRequest
	urlParams_                 gensupport.URLParams
	ctx_                       context.Context
	header_                    http.Header
}

// Promote: Promote a migration job, stopping replication to the destination
// and promoting the destination to be a standalone database.
//
// - name: Name of the migration job resource to promote.
func (r *ProjectsLocationsMigrationJobsService) Promote(name string, promotemigrationjobrequest *PromoteMigrationJobRequest) *ProjectsLocationsMigrationJobsPromoteCall {
	c := &ProjectsLocationsMigrationJobsPromoteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.promotemigrationjobrequest = promotemigrationjobrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsPromoteCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsPromoteCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsPromoteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.promotemigrationjobrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:promote")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.promote", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.promote" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsPromoteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.promote", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsRestartCall struct {
	s                          *Service
	name                       string
	restartmigrationjobrequest *RestartMigrationJobRequest
	urlParams_                 gensupport.URLParams
	ctx_                       context.Context
	header_                    http.Header
}

// Restart: Restart a stopped or failed migration job, resetting the
// destination instance to its original state and starting the migration
// process from scratch.
//
// - name: Name of the migration job resource to restart.
func (r *ProjectsLocationsMigrationJobsService) Restart(name string, restartmigrationjobrequest *RestartMigrationJobRequest) *ProjectsLocationsMigrationJobsRestartCall {
	c := &ProjectsLocationsMigrationJobsRestartCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.restartmigrationjobrequest = restartmigrationjobrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsRestartCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsRestartCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsRestartCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.restartmigrationjobrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:restart")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.restart", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.restart" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsRestartCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.restart", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsResumeCall struct {
	s                         *Service
	name                      string
	resumemigrationjobrequest *ResumeMigrationJobRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Resume: Resume a migration job that is currently stopped and is resumable
// (was stopped during CDC phase).
//
// - name: Name of the migration job resource to resume.
func (r *ProjectsLocationsMigrationJobsService) Resume(name string, resumemigrationjobrequest *ResumeMigrationJobRequest) *ProjectsLocationsMigrationJobsResumeCall {
	c := &ProjectsLocationsMigrationJobsResumeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.resumemigrationjobrequest = resumemigrationjobrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsResumeCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsResumeCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsResumeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.resumemigrationjobrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:resume")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.resume", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.resume" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsResumeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.resume", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsSetIamPolicyCall struct {
	s                   *Service
	resource            string
	setiampolicyrequest *SetIamPolicyRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// SetIamPolicy: Sets the access control policy on the specified resource.
// Replaces any existing policy. Can return `NOT_FOUND`, `INVALID_ARGUMENT`,
// and `PERMISSION_DENIED` errors.
//
//   - resource: REQUIRED: The resource for which the policy is being specified.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsMigrationJobsService) SetIamPolicy(resource string, setiampolicyrequest *SetIamPolicyRequest) *ProjectsLocationsMigrationJobsSetIamPolicyCall {
	c := &ProjectsLocationsMigrationJobsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.setiampolicyrequest = setiampolicyrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsSetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.setiampolicyrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.setIamPolicy", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.setIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.setIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsStartCall struct {
	s                        *Service
	name                     string
	startmigrationjobrequest *StartMigrationJobRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// Start: Start an already created migration job.
//
// - name: Name of the migration job resource to start.
func (r *ProjectsLocationsMigrationJobsService) Start(name string, startmigrationjobrequest *StartMigrationJobRequest) *ProjectsLocationsMigrationJobsStartCall {
	c := &ProjectsLocationsMigrationJobsStartCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.startmigrationjobrequest = startmigrationjobrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsStartCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsStartCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsStartCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.startmigrationjobrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:start")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.start", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.start" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsStartCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.start", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsStopCall struct {
	s                       *Service
	name                    string
	stopmigrationjobrequest *StopMigrationJobRequest
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Stop: Stops a running migration job.
//
// - name: Name of the migration job resource to stop.
func (r *ProjectsLocationsMigrationJobsService) Stop(name string, stopmigrationjobrequest *StopMigrationJobRequest) *ProjectsLocationsMigrationJobsStopCall {
	c := &ProjectsLocationsMigrationJobsStopCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.stopmigrationjobrequest = stopmigrationjobrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsStopCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsStopCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsStopCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.stopmigrationjobrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:stop")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.stop", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.stop" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsStopCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.stop", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsTestIamPermissionsCall struct {
	s                         *Service
	resource                  string
	testiampermissionsrequest *TestIamPermissionsRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the specified
// resource. If the resource does not exist, this will return an empty set of
// permissions, not a `NOT_FOUND` error. Note: This operation is designed to be
// used for building permission-aware UIs and command-line tools, not for
// authorization checking. This operation may "fail open" without warning.
//
//   - resource: REQUIRED: The resource for which the policy detail is being
//     requested. See Resource names
//     (https://cloud.google.com/apis/design/resource_names) for the appropriate
//     value for this field.
func (r *ProjectsLocationsMigrationJobsService) TestIamPermissions(resource string, testiampermissionsrequest *TestIamPermissionsRequest) *ProjectsLocationsMigrationJobsTestIamPermissionsCall {
	c := &ProjectsLocationsMigrationJobsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.testiampermissionsrequest = testiampermissionsrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsTestIamPermissionsCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.testiampermissionsrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.testIamPermissions", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.testIamPermissions" call.
// Any non-2xx status code is an error. Response headers are in either
// *TestIamPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &TestIamPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.testIamPermissions", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsVerifyCall struct {
	s                         *Service
	name                      string
	verifymigrationjobrequest *VerifyMigrationJobRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Verify: Verify a migration job, making sure the destination can reach the
// source and that all configuration and prerequisites are met.
//
// - name: Name of the migration job resource to verify.
func (r *ProjectsLocationsMigrationJobsService) Verify(name string, verifymigrationjobrequest *VerifyMigrationJobRequest) *ProjectsLocationsMigrationJobsVerifyCall {
	c := &ProjectsLocationsMigrationJobsVerifyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.verifymigrationjobrequest = verifymigrationjobrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsVerifyCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsVerifyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsVerifyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.verifymigrationjobrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:verify")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.verify", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.verify" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsVerifyCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.verify", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Use this method to get details about a migration job object.
//
// - name: The name of the migration job object resource to get.
func (r *ProjectsLocationsMigrationJobsObjectsService) Get(name string) *ProjectsLocationsMigrationJobsObjectsGetCall {
	c := &ProjectsLocationsMigrationJobsObjectsGetCall{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
// details.
func (c *ProjectsLocationsMigrationJobsObjectsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsMigrationJobsObjectsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsMigrationJobsObjectsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsMigrationJobsObjectsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsObjectsGetCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsObjectsGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsObjectsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.objects.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *MigrationJobObject.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 *ProjectsLocationsMigrationJobsObjectsGetCall) Do(opts ...googleapi.CallOption) (*MigrationJobObject, 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 := &MigrationJobObject{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// GetIamPolicy: Gets the access control policy for a resource. Returns an
// empty policy if the resource exists and does not have a policy set.
//
//   - resource: REQUIRED: The resource for which the policy is being requested.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsMigrationJobsObjectsService) GetIamPolicy(resource string) *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall {
	c := &ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// OptionsRequestedPolicyVersion sets the optional parameter
// "options.requestedPolicyVersion": The maximum policy version that will be
// used to format the policy. Valid values are 0, 1, and 3. Requests specifying
// an invalid value will be rejected. Requests for policies with any
// conditional role bindings must specify version 3. Policies with no
// conditional role bindings may specify any valid value or leave the field
// unset. The policy in the response might use the policy version that you
// specified, or it might use a lower policy version. For example, if you
// specify version 3, but the policy has no conditional role bindings, the
// response uses version 1. To learn which resources support conditions in
// their IAM policies, see the IAM documentation
// (https://cloud.google.com/iam/help/conditions/resource-policies).
func (c *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall) OptionsRequestedPolicyVersion(optionsRequestedPolicyVersion int64) *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall {
	c.urlParams_.Set("options.requestedPolicyVersion", fmt.Sprint(optionsRequestedPolicyVersion))
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall) IfNoneMatch(entityTag string) *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.getIamPolicy", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.objects.getIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsObjectsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.getIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Use this method to list the objects of a specific migration job.
//
// - parent: The parent migration job that owns the collection of objects.
func (r *ProjectsLocationsMigrationJobsObjectsService) List(parent string) *ProjectsLocationsMigrationJobsObjectsListCall {
	c := &ProjectsLocationsMigrationJobsObjectsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of objects
// to return. Default is 50. The maximum value is 1000; values above 1000 will
// be coerced to 1000.
func (c *ProjectsLocationsMigrationJobsObjectsListCall) PageSize(pageSize int64) *ProjectsLocationsMigrationJobsObjectsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token received from
// a previous `ListMigrationJObObjectsRequest` call. Provide this to retrieve
// the subsequent page. When paginating, all other parameters provided to
// `ListMigrationJobObjectsRequest` must match the call that provided the page
// token.
func (c *ProjectsLocationsMigrationJobsObjectsListCall) PageToken(pageToken string) *ProjectsLocationsMigrationJobsObjectsListCall {
	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
// details.
func (c *ProjectsLocationsMigrationJobsObjectsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsMigrationJobsObjectsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsMigrationJobsObjectsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsMigrationJobsObjectsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsObjectsListCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsObjectsListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsObjectsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/objects")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.objects.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListMigrationJobObjectsResponse.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 *ProjectsLocationsMigrationJobsObjectsListCall) Do(opts ...googleapi.CallOption) (*ListMigrationJobObjectsResponse, 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 := &ListMigrationJobObjectsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsMigrationJobsObjectsListCall) Pages(ctx context.Context, f func(*ListMigrationJobObjectsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

type ProjectsLocationsMigrationJobsObjectsLookupCall struct {
	s                               *Service
	parent                          string
	lookupmigrationjobobjectrequest *LookupMigrationJobObjectRequest
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// Lookup: Use this method to look up a migration job object by its source
// object identifier.
//
// - parent: The parent migration job that owns the collection of objects.
func (r *ProjectsLocationsMigrationJobsObjectsService) Lookup(parent string, lookupmigrationjobobjectrequest *LookupMigrationJobObjectRequest) *ProjectsLocationsMigrationJobsObjectsLookupCall {
	c := &ProjectsLocationsMigrationJobsObjectsLookupCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.lookupmigrationjobobjectrequest = lookupmigrationjobobjectrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsObjectsLookupCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsObjectsLookupCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsObjectsLookupCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.lookupmigrationjobobjectrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/objects:lookup")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.lookup", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.objects.lookup" call.
// Any non-2xx status code is an error. Response headers are in either
// *MigrationJobObject.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 *ProjectsLocationsMigrationJobsObjectsLookupCall) Do(opts ...googleapi.CallOption) (*MigrationJobObject, 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 := &MigrationJobObject{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.lookup", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsObjectsSetIamPolicyCall struct {
	s                   *Service
	resource            string
	setiampolicyrequest *SetIamPolicyRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// SetIamPolicy: Sets the access control policy on the specified resource.
// Replaces any existing policy. Can return `NOT_FOUND`, `INVALID_ARGUMENT`,
// and `PERMISSION_DENIED` errors.
//
//   - resource: REQUIRED: The resource for which the policy is being specified.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsMigrationJobsObjectsService) SetIamPolicy(resource string, setiampolicyrequest *SetIamPolicyRequest) *ProjectsLocationsMigrationJobsObjectsSetIamPolicyCall {
	c := &ProjectsLocationsMigrationJobsObjectsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.setiampolicyrequest = setiampolicyrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsObjectsSetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsObjectsSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsObjectsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.setiampolicyrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.setIamPolicy", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.objects.setIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsObjectsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.setIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsMigrationJobsObjectsTestIamPermissionsCall struct {
	s                         *Service
	resource                  string
	testiampermissionsrequest *TestIamPermissionsRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the specified
// resource. If the resource does not exist, this will return an empty set of
// permissions, not a `NOT_FOUND` error. Note: This operation is designed to be
// used for building permission-aware UIs and command-line tools, not for
// authorization checking. This operation may "fail open" without warning.
//
//   - resource: REQUIRED: The resource for which the policy detail is being
//     requested. See Resource names
//     (https://cloud.google.com/apis/design/resource_names) for the appropriate
//     value for this field.
func (r *ProjectsLocationsMigrationJobsObjectsService) TestIamPermissions(resource string, testiampermissionsrequest *TestIamPermissionsRequest) *ProjectsLocationsMigrationJobsObjectsTestIamPermissionsCall {
	c := &ProjectsLocationsMigrationJobsObjectsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.testiampermissionsrequest = testiampermissionsrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsMigrationJobsObjectsTestIamPermissionsCall) Context(ctx context.Context) *ProjectsLocationsMigrationJobsObjectsTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsMigrationJobsObjectsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.testiampermissionsrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.testIamPermissions", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.migrationJobs.objects.testIamPermissions" call.
// Any non-2xx status code is an error. Response headers are in either
// *TestIamPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsMigrationJobsObjectsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &TestIamPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.migrationJobs.objects.testIamPermissions", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Cancel: Starts asynchronous cancellation on a long-running operation. The
// server makes a best effort to cancel the operation, but success is not
// guaranteed. If the server doesn't support this method, it returns
// `google.rpc.Code.UNIMPLEMENTED`. Clients can use Operations.GetOperation or
// other methods to check whether the cancellation succeeded or whether the
// operation completed despite cancellation. On successful cancellation, the
// operation is not deleted; instead, it becomes an operation with an
// Operation.error value with a google.rpc.Status.code of `1`, corresponding to
// `Code.CANCELLED`.
//
// - name: The name of the operation resource to be cancelled.
func (r *ProjectsLocationsOperationsService) Cancel(name string, canceloperationrequest *CancelOperationRequest) *ProjectsLocationsOperationsCancelCall {
	c := &ProjectsLocationsOperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.canceloperationrequest = canceloperationrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsOperationsCancelCall) Context(ctx context.Context) *ProjectsLocationsOperationsCancelCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsOperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.canceloperationrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.operations.cancel", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.operations.cancel" call.
// Any non-2xx status code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsOperationsCancelCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.operations.cancel", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes a long-running operation. This method indicates that the
// client is no longer interested in the operation result. It does not cancel
// the operation. If the server doesn't support this method, it returns
// `google.rpc.Code.UNIMPLEMENTED`.
//
// - name: The name of the operation resource to be deleted.
func (r *ProjectsLocationsOperationsService) Delete(name string) *ProjectsLocationsOperationsDeleteCall {
	c := &ProjectsLocationsOperationsDeleteCall{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
// details.
func (c *ProjectsLocationsOperationsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsOperationsDeleteCall) Context(ctx context.Context) *ProjectsLocationsOperationsDeleteCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsOperationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.operations.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.operations.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsOperationsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.operations.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Gets the latest state of a long-running operation. Clients can use this
// method to poll the operation result at intervals as recommended by the API
// service.
//
// - name: The name of the operation resource.
func (r *ProjectsLocationsOperationsService) Get(name string) *ProjectsLocationsOperationsGetCall {
	c := &ProjectsLocationsOperationsGetCall{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
// details.
func (c *ProjectsLocationsOperationsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsOperationsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsOperationsGetCall) Context(ctx context.Context) *ProjectsLocationsOperationsGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.operations.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.operations.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.operations.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists operations that match the specified filter in the request. If
// the server doesn't support this method, it returns `UNIMPLEMENTED`.
//
// - name: The name of the operation's parent resource.
func (r *ProjectsLocationsOperationsService) List(name string) *ProjectsLocationsOperationsListCall {
	c := &ProjectsLocationsOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list filter.
func (c *ProjectsLocationsOperationsListCall) Filter(filter string) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list page
// size.
func (c *ProjectsLocationsOperationsListCall) PageSize(pageSize int64) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

// ReturnPartialSuccess sets the optional parameter "returnPartialSuccess":
// When set to `true`, operations that are reachable are returned as normal,
// and those that are unreachable are returned in the
// ListOperationsResponse.unreachable field. This can only be `true` when
// reading across collections. For example, when `parent` is set to
// "projects/example/locations/-". This field is not supported by default and
// will result in an `UNIMPLEMENTED` error if set unless explicitly documented
// otherwise in service or product specific documentation.
func (c *ProjectsLocationsOperationsListCall) ReturnPartialSuccess(returnPartialSuccess bool) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("returnPartialSuccess", fmt.Sprint(returnPartialSuccess))
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsOperationsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsOperationsListCall) Context(ctx context.Context) *ProjectsLocationsOperationsListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.operations.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.operations.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsOperationsListCall) Do(opts ...googleapi.CallOption) (*ListOperationsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &ListOperationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.operations.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsOperationsListCall) Pages(ctx context.Context, f func(*ListOperationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

type ProjectsLocationsPrivateConnectionsCreateCall struct {
	s                 *Service
	parent            string
	privateconnection *PrivateConnection
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Creates a new private connection in a given project and location.
//
// - parent: The parent that owns the collection of PrivateConnections.
func (r *ProjectsLocationsPrivateConnectionsService) Create(parent string, privateconnection *PrivateConnection) *ProjectsLocationsPrivateConnectionsCreateCall {
	c := &ProjectsLocationsPrivateConnectionsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.privateconnection = privateconnection
	return c
}

// PrivateConnectionId sets the optional parameter "privateConnectionId":
// Required. The private connection identifier.
func (c *ProjectsLocationsPrivateConnectionsCreateCall) PrivateConnectionId(privateConnectionId string) *ProjectsLocationsPrivateConnectionsCreateCall {
	c.urlParams_.Set("privateConnectionId", privateConnectionId)
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsPrivateConnectionsCreateCall) RequestId(requestId string) *ProjectsLocationsPrivateConnectionsCreateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// SkipValidation sets the optional parameter "skipValidation": If set to true,
// will skip validations.
func (c *ProjectsLocationsPrivateConnectionsCreateCall) SkipValidation(skipValidation bool) *ProjectsLocationsPrivateConnectionsCreateCall {
	c.urlParams_.Set("skipValidation", fmt.Sprint(skipValidation))
	return c
}

// ValidateOnly sets the optional parameter "validateOnly": For PSC Interface
// only - get the tenant project before creating the resource.
func (c *ProjectsLocationsPrivateConnectionsCreateCall) ValidateOnly(validateOnly bool) *ProjectsLocationsPrivateConnectionsCreateCall {
	c.urlParams_.Set("validateOnly", fmt.Sprint(validateOnly))
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPrivateConnectionsCreateCall) Context(ctx context.Context) *ProjectsLocationsPrivateConnectionsCreateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsPrivateConnectionsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.privateconnection)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/privateConnections")
	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,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.privateConnections.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsPrivateConnectionsCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes a single Database Migration Service private connection.
//
// - name: The name of the private connection to delete.
func (r *ProjectsLocationsPrivateConnectionsService) Delete(name string) *ProjectsLocationsPrivateConnectionsDeleteCall {
	c := &ProjectsLocationsPrivateConnectionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// RequestId sets the optional parameter "requestId": A unique ID used to
// identify the request. If the server receives two requests with the same ID,
// then the second request is ignored. It is recommended to always set this
// value to a UUID. The ID must contain only letters (a-z, A-Z), numbers (0-9),
// underscores (_), and hyphens (-). The maximum length is 40 characters.
func (c *ProjectsLocationsPrivateConnectionsDeleteCall) RequestId(requestId string) *ProjectsLocationsPrivateConnectionsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPrivateConnectionsDeleteCall) Context(ctx context.Context) *ProjectsLocationsPrivateConnectionsDeleteCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsPrivateConnectionsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.privateConnections.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsPrivateConnectionsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Gets details of a single private connection.
//
// - name: The name of the private connection to get.
func (r *ProjectsLocationsPrivateConnectionsService) Get(name string) *ProjectsLocationsPrivateConnectionsGetCall {
	c := &ProjectsLocationsPrivateConnectionsGetCall{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
// details.
func (c *ProjectsLocationsPrivateConnectionsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsPrivateConnectionsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsPrivateConnectionsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsPrivateConnectionsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPrivateConnectionsGetCall) Context(ctx context.Context) *ProjectsLocationsPrivateConnectionsGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsPrivateConnectionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.privateConnections.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *PrivateConnection.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 *ProjectsLocationsPrivateConnectionsGetCall) Do(opts ...googleapi.CallOption) (*PrivateConnection, 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 := &PrivateConnection{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// GetIamPolicy: Gets the access control policy for a resource. Returns an
// empty policy if the resource exists and does not have a policy set.
//
//   - resource: REQUIRED: The resource for which the policy is being requested.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsPrivateConnectionsService) GetIamPolicy(resource string) *ProjectsLocationsPrivateConnectionsGetIamPolicyCall {
	c := &ProjectsLocationsPrivateConnectionsGetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	return c
}

// OptionsRequestedPolicyVersion sets the optional parameter
// "options.requestedPolicyVersion": The maximum policy version that will be
// used to format the policy. Valid values are 0, 1, and 3. Requests specifying
// an invalid value will be rejected. Requests for policies with any
// conditional role bindings must specify version 3. Policies with no
// conditional role bindings may specify any valid value or leave the field
// unset. The policy in the response might use the policy version that you
// specified, or it might use a lower policy version. For example, if you
// specify version 3, but the policy has no conditional role bindings, the
// response uses version 1. To learn which resources support conditions in
// their IAM policies, see the IAM documentation
// (https://cloud.google.com/iam/help/conditions/resource-policies).
func (c *ProjectsLocationsPrivateConnectionsGetIamPolicyCall) OptionsRequestedPolicyVersion(optionsRequestedPolicyVersion int64) *ProjectsLocationsPrivateConnectionsGetIamPolicyCall {
	c.urlParams_.Set("options.requestedPolicyVersion", fmt.Sprint(optionsRequestedPolicyVersion))
	return c
}

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

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsPrivateConnectionsGetIamPolicyCall) IfNoneMatch(entityTag string) *ProjectsLocationsPrivateConnectionsGetIamPolicyCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPrivateConnectionsGetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsPrivateConnectionsGetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsPrivateConnectionsGetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:getIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.getIamPolicy", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.privateConnections.getIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsPrivateConnectionsGetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.getIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Retrieves a list of private connections in a given project and
// location.
//
// - parent: The parent that owns the collection of private connections.
func (r *ProjectsLocationsPrivateConnectionsService) List(parent string) *ProjectsLocationsPrivateConnectionsListCall {
	c := &ProjectsLocationsPrivateConnectionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": A filter expression that
// filters private connections listed in the response. The expression must
// specify the field name, a comparison operator, and the value that you want
// to use for filtering. The value must be a string, a number, or a boolean.
// The comparison operator must be either =, !=, >, or <. For example, list
// private connections created this year by specifying **createTime %gt;
// 2021-01-01T00:00:00.000000000Z**.
func (c *ProjectsLocationsPrivateConnectionsListCall) Filter(filter string) *ProjectsLocationsPrivateConnectionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Order by fields for the
// result.
func (c *ProjectsLocationsPrivateConnectionsListCall) OrderBy(orderBy string) *ProjectsLocationsPrivateConnectionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of private
// connections to return. If unspecified, at most 50 private connections that
// are returned. The maximum value is 1000; values above 1000 are coerced to
// 1000.
func (c *ProjectsLocationsPrivateConnectionsListCall) PageSize(pageSize int64) *ProjectsLocationsPrivateConnectionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token received from
// a previous `ListPrivateConnections` call. Provide this to retrieve the
// subsequent page. When paginating, all other parameters provided to
// `ListPrivateConnections` must match the call that provided the page token.
func (c *ProjectsLocationsPrivateConnectionsListCall) PageToken(pageToken string) *ProjectsLocationsPrivateConnectionsListCall {
	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
// details.
func (c *ProjectsLocationsPrivateConnectionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsPrivateConnectionsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an 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.
func (c *ProjectsLocationsPrivateConnectionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsPrivateConnectionsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPrivateConnectionsListCall) Context(ctx context.Context) *ProjectsLocationsPrivateConnectionsListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsPrivateConnectionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/privateConnections")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.privateConnections.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListPrivateConnectionsResponse.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 *ProjectsLocationsPrivateConnectionsListCall) Do(opts ...googleapi.CallOption) (*ListPrivateConnectionsResponse, 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 := &ListPrivateConnectionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// 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 *ProjectsLocationsPrivateConnectionsListCall) Pages(ctx context.Context, f func(*ListPrivateConnectionsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	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)
	}
}

type ProjectsLocationsPrivateConnectionsSetIamPolicyCall struct {
	s                   *Service
	resource            string
	setiampolicyrequest *SetIamPolicyRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// SetIamPolicy: Sets the access control policy on the specified resource.
// Replaces any existing policy. Can return `NOT_FOUND`, `INVALID_ARGUMENT`,
// and `PERMISSION_DENIED` errors.
//
//   - resource: REQUIRED: The resource for which the policy is being specified.
//     See Resource names (https://cloud.google.com/apis/design/resource_names)
//     for the appropriate value for this field.
func (r *ProjectsLocationsPrivateConnectionsService) SetIamPolicy(resource string, setiampolicyrequest *SetIamPolicyRequest) *ProjectsLocationsPrivateConnectionsSetIamPolicyCall {
	c := &ProjectsLocationsPrivateConnectionsSetIamPolicyCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.setiampolicyrequest = setiampolicyrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPrivateConnectionsSetIamPolicyCall) Context(ctx context.Context) *ProjectsLocationsPrivateConnectionsSetIamPolicyCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsPrivateConnectionsSetIamPolicyCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.setiampolicyrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:setIamPolicy")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.setIamPolicy", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.privateConnections.setIamPolicy" call.
// Any non-2xx status code is an error. Response headers are in either
// *Policy.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsPrivateConnectionsSetIamPolicyCall) Do(opts ...googleapi.CallOption) (*Policy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &Policy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.setIamPolicy", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsPrivateConnectionsTestIamPermissionsCall struct {
	s                         *Service
	resource                  string
	testiampermissionsrequest *TestIamPermissionsRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// TestIamPermissions: Returns permissions that a caller has on the specified
// resource. If the resource does not exist, this will return an empty set of
// permissions, not a `NOT_FOUND` error. Note: This operation is designed to be
// used for building permission-aware UIs and command-line tools, not for
// authorization checking. This operation may "fail open" without warning.
//
//   - resource: REQUIRED: The resource for which the policy detail is being
//     requested. See Resource names
//     (https://cloud.google.com/apis/design/resource_names) for the appropriate
//     value for this field.
func (r *ProjectsLocationsPrivateConnectionsService) TestIamPermissions(resource string, testiampermissionsrequest *TestIamPermissionsRequest) *ProjectsLocationsPrivateConnectionsTestIamPermissionsCall {
	c := &ProjectsLocationsPrivateConnectionsTestIamPermissionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resource = resource
	c.testiampermissionsrequest = testiampermissionsrequest
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsPrivateConnectionsTestIamPermissionsCall) Context(ctx context.Context) *ProjectsLocationsPrivateConnectionsTestIamPermissionsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ProjectsLocationsPrivateConnectionsTestIamPermissionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.testiampermissionsrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+resource}:testIamPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"resource": c.resource,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.testIamPermissions", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "datamigration.projects.locations.privateConnections.testIamPermissions" call.
// Any non-2xx status code is an error. Response headers are in either
// *TestIamPermissionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsPrivateConnectionsTestIamPermissionsCall) Do(opts ...googleapi.CallOption) (*TestIamPermissionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, 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 := &TestIamPermissionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "datamigration.projects.locations.privateConnections.testIamPermissions", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}
