// 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 cloudchannel provides access to the Cloud Channel API.
//
// For product documentation, see: https://cloud.google.com/channel
//
// # 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/cloudchannel/v1"
//	...
//	ctx := context.Background()
//	cloudchannelService, err := cloudchannel.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for
// authentication. For information on how to create and obtain Application
// Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// # Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate.
// To restrict scopes, use [google.golang.org/api/option.WithScopes]:
//
//	cloudchannelService, err := cloudchannel.NewService(ctx, option.WithScopes(cloudchannel.AppsReportsUsageReadonlyScope))
//
// To use an API key for authentication (note: some APIs do not support API
// keys), use [google.golang.org/api/option.WithAPIKey]:
//
//	cloudchannelService, err := cloudchannel.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, ...)
//	cloudchannelService, err := cloudchannel.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See [google.golang.org/api/option.ClientOption] for details on options.
package cloudchannel // import "google.golang.org/api/cloudchannel/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 = "cloudchannel:v1"
const apiName = "cloudchannel"
const apiVersion = "v1"
const basePath = "https://cloudchannel.googleapis.com/"
const basePathTemplate = "https://cloudchannel.UNIVERSE_DOMAIN/"
const mtlsBasePath = "https://cloudchannel.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// Manage users on your domain
	AppsOrderScope = "https://www.googleapis.com/auth/apps.order"

	// View usage reports for your Google Workspace domain
	AppsReportsUsageReadonlyScope = "https://www.googleapis.com/auth/apps.reports.usage.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := internaloption.WithDefaultScopes(
		"https://www.googleapis.com/auth/apps.order",
		"https://www.googleapis.com/auth/apps.reports.usage.readonly",
	)
	// 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.Accounts = NewAccountsService(s)
	s.Integrators = NewIntegratorsService(s)
	s.Operations = NewOperationsService(s)
	s.Products = NewProductsService(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

	Accounts *AccountsService

	Integrators *IntegratorsService

	Operations *OperationsService

	Products *ProductsService
}

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

func NewAccountsService(s *Service) *AccountsService {
	rs := &AccountsService{s: s}
	rs.ChannelPartnerLinks = NewAccountsChannelPartnerLinksService(s)
	rs.Customers = NewAccountsCustomersService(s)
	rs.Offers = NewAccountsOffersService(s)
	rs.ReportJobs = NewAccountsReportJobsService(s)
	rs.Reports = NewAccountsReportsService(s)
	rs.SkuGroups = NewAccountsSkuGroupsService(s)
	return rs
}

type AccountsService struct {
	s *Service

	ChannelPartnerLinks *AccountsChannelPartnerLinksService

	Customers *AccountsCustomersService

	Offers *AccountsOffersService

	ReportJobs *AccountsReportJobsService

	Reports *AccountsReportsService

	SkuGroups *AccountsSkuGroupsService
}

func NewAccountsChannelPartnerLinksService(s *Service) *AccountsChannelPartnerLinksService {
	rs := &AccountsChannelPartnerLinksService{s: s}
	rs.ChannelPartnerRepricingConfigs = NewAccountsChannelPartnerLinksChannelPartnerRepricingConfigsService(s)
	rs.Customers = NewAccountsChannelPartnerLinksCustomersService(s)
	return rs
}

type AccountsChannelPartnerLinksService struct {
	s *Service

	ChannelPartnerRepricingConfigs *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService

	Customers *AccountsChannelPartnerLinksCustomersService
}

func NewAccountsChannelPartnerLinksChannelPartnerRepricingConfigsService(s *Service) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService {
	rs := &AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService{s: s}
	return rs
}

type AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService struct {
	s *Service
}

func NewAccountsChannelPartnerLinksCustomersService(s *Service) *AccountsChannelPartnerLinksCustomersService {
	rs := &AccountsChannelPartnerLinksCustomersService{s: s}
	return rs
}

type AccountsChannelPartnerLinksCustomersService struct {
	s *Service
}

func NewAccountsCustomersService(s *Service) *AccountsCustomersService {
	rs := &AccountsCustomersService{s: s}
	rs.CustomerRepricingConfigs = NewAccountsCustomersCustomerRepricingConfigsService(s)
	rs.Entitlements = NewAccountsCustomersEntitlementsService(s)
	return rs
}

type AccountsCustomersService struct {
	s *Service

	CustomerRepricingConfigs *AccountsCustomersCustomerRepricingConfigsService

	Entitlements *AccountsCustomersEntitlementsService
}

func NewAccountsCustomersCustomerRepricingConfigsService(s *Service) *AccountsCustomersCustomerRepricingConfigsService {
	rs := &AccountsCustomersCustomerRepricingConfigsService{s: s}
	return rs
}

type AccountsCustomersCustomerRepricingConfigsService struct {
	s *Service
}

func NewAccountsCustomersEntitlementsService(s *Service) *AccountsCustomersEntitlementsService {
	rs := &AccountsCustomersEntitlementsService{s: s}
	return rs
}

type AccountsCustomersEntitlementsService struct {
	s *Service
}

func NewAccountsOffersService(s *Service) *AccountsOffersService {
	rs := &AccountsOffersService{s: s}
	return rs
}

type AccountsOffersService struct {
	s *Service
}

func NewAccountsReportJobsService(s *Service) *AccountsReportJobsService {
	rs := &AccountsReportJobsService{s: s}
	return rs
}

type AccountsReportJobsService struct {
	s *Service
}

func NewAccountsReportsService(s *Service) *AccountsReportsService {
	rs := &AccountsReportsService{s: s}
	return rs
}

type AccountsReportsService struct {
	s *Service
}

func NewAccountsSkuGroupsService(s *Service) *AccountsSkuGroupsService {
	rs := &AccountsSkuGroupsService{s: s}
	rs.BillableSkus = NewAccountsSkuGroupsBillableSkusService(s)
	return rs
}

type AccountsSkuGroupsService struct {
	s *Service

	BillableSkus *AccountsSkuGroupsBillableSkusService
}

func NewAccountsSkuGroupsBillableSkusService(s *Service) *AccountsSkuGroupsBillableSkusService {
	rs := &AccountsSkuGroupsBillableSkusService{s: s}
	return rs
}

type AccountsSkuGroupsBillableSkusService struct {
	s *Service
}

func NewIntegratorsService(s *Service) *IntegratorsService {
	rs := &IntegratorsService{s: s}
	return rs
}

type IntegratorsService struct {
	s *Service
}

func NewOperationsService(s *Service) *OperationsService {
	rs := &OperationsService{s: s}
	return rs
}

type OperationsService struct {
	s *Service
}

func NewProductsService(s *Service) *ProductsService {
	rs := &ProductsService{s: s}
	rs.Skus = NewProductsSkusService(s)
	return rs
}

type ProductsService struct {
	s *Service

	Skus *ProductsSkusService
}

func NewProductsSkusService(s *Service) *ProductsSkusService {
	rs := &ProductsSkusService{s: s}
	return rs
}

type ProductsSkusService struct {
	s *Service
}

// GoogleCloudChannelV1ActivateEntitlementRequest: Request message for
// CloudChannelService.ActivateEntitlement.
type GoogleCloudChannelV1ActivateEntitlementRequest struct {
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,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 GoogleCloudChannelV1ActivateEntitlementRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ActivateEntitlementRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1AdminUser: Information needed to create an Admin User
// for Google Workspace.
type GoogleCloudChannelV1AdminUser struct {
	// Email: Primary email of the admin user.
	Email string `json:"email,omitempty"`
	// FamilyName: Family name of the admin user.
	FamilyName string `json:"familyName,omitempty"`
	// GivenName: Given name of the admin user.
	GivenName string `json:"givenName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Email") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. 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. "Email") 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 GoogleCloudChannelV1AdminUser) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1AdminUser
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1AssociationInfo: Association links that an entitlement
// has to other entitlements.
type GoogleCloudChannelV1AssociationInfo struct {
	// BaseEntitlement: The name of the base entitlement, for which this
	// entitlement is an add-on.
	BaseEntitlement string `json:"baseEntitlement,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BaseEntitlement") 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. "BaseEntitlement") 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 GoogleCloudChannelV1AssociationInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1AssociationInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1BillableSku: Represents the Billable SKU information.
type GoogleCloudChannelV1BillableSku struct {
	// Service: Resource name of Service which contains Repricing SKU. Format:
	// services/{service}. Example: "services/B7D9-FDCB-15D8".
	Service string `json:"service,omitempty"`
	// ServiceDisplayName: Unique human readable name for the Service.
	ServiceDisplayName string `json:"serviceDisplayName,omitempty"`
	// Sku: Resource name of Billable SKU. Format: billableSkus/{sku}. Example:
	// billableSkus/6E1B-6634-470F".
	Sku string `json:"sku,omitempty"`
	// SkuDisplayName: Unique human readable name for the SKU.
	SkuDisplayName string `json:"skuDisplayName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Service") 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. "Service") 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 GoogleCloudChannelV1BillableSku) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1BillableSku
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1BillingAccount: Represents a billing account.
type GoogleCloudChannelV1BillingAccount struct {
	// CreateTime: Output only. The time when this billing account was created.
	CreateTime string `json:"createTime,omitempty"`
	// CurrencyCode: Output only. The 3-letter currency code defined in ISO 4217.
	CurrencyCode string `json:"currencyCode,omitempty"`
	// DisplayName: Display name of the billing account.
	DisplayName string `json:"displayName,omitempty"`
	// Name: Output only. Resource name of the billing account. Format:
	// accounts/{account_id}/billingAccounts/{billing_account_id}.
	Name string `json:"name,omitempty"`
	// RegionCode: Output only. The CLDR region code.
	RegionCode string `json:"regionCode,omitempty"`
	// 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 GoogleCloudChannelV1BillingAccount) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1BillingAccount
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1BillingAccountPurchaseInfo: Represents a billing account
// that can be used to make a purchase.
type GoogleCloudChannelV1BillingAccountPurchaseInfo struct {
	// BillingAccount: The billing account resource.
	BillingAccount *GoogleCloudChannelV1BillingAccount `json:"billingAccount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BillingAccount") 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. "BillingAccount") 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 GoogleCloudChannelV1BillingAccountPurchaseInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1BillingAccountPurchaseInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CancelEntitlementRequest: Request message for
// CloudChannelService.CancelEntitlement.
type GoogleCloudChannelV1CancelEntitlementRequest struct {
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,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 GoogleCloudChannelV1CancelEntitlementRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CancelEntitlementRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ChangeOfferRequest: Request message for
// CloudChannelService.ChangeOffer.
type GoogleCloudChannelV1ChangeOfferRequest struct {
	// BillingAccount: Optional. The billing account resource name that is used to
	// pay for this entitlement when setting up billing on a trial subscription.
	// This field is only relevant for multi-currency accounts. It should be left
	// empty for single currency accounts.
	BillingAccount string `json:"billingAccount,omitempty"`
	// Offer: Required. New Offer. Format: accounts/{account_id}/offers/{offer_id}.
	Offer string `json:"offer,omitempty"`
	// Parameters: Optional. Parameters needed to purchase the Offer. To view the
	// available Parameters refer to the Offer.parameter_definitions from the
	// desired offer.
	Parameters []*GoogleCloudChannelV1Parameter `json:"parameters,omitempty"`
	// PriceReferenceId: Optional. Price reference ID for the offer. Only for
	// offers that require additional price information. Used to guarantee that the
	// pricing is consistent between quoting the offer and placing the order.
	PriceReferenceId string `json:"priceReferenceId,omitempty"`
	// PurchaseOrderId: Optional. Purchase order id provided by the reseller.
	PurchaseOrderId string `json:"purchaseOrderId,omitempty"`
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BillingAccount") 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. "BillingAccount") 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 GoogleCloudChannelV1ChangeOfferRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ChangeOfferRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ChangeParametersRequest: Request message for
// CloudChannelService.ChangeParameters.
type GoogleCloudChannelV1ChangeParametersRequest struct {
	// Parameters: Required. Entitlement parameters to update. You can only change
	// editable parameters. To view the available Parameters for a request, refer
	// to the Offer.parameter_definitions from the desired offer.
	Parameters []*GoogleCloudChannelV1Parameter `json:"parameters,omitempty"`
	// PurchaseOrderId: Optional. Purchase order ID provided by the reseller.
	PurchaseOrderId string `json:"purchaseOrderId,omitempty"`
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Parameters") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. 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. "Parameters") 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 GoogleCloudChannelV1ChangeParametersRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ChangeParametersRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ChangeRenewalSettingsRequest: Request message for
// CloudChannelService.ChangeRenewalSettings.
type GoogleCloudChannelV1ChangeRenewalSettingsRequest struct {
	// RenewalSettings: Required. New renewal settings.
	RenewalSettings *GoogleCloudChannelV1RenewalSettings `json:"renewalSettings,omitempty"`
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RenewalSettings") 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. "RenewalSettings") 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 GoogleCloudChannelV1ChangeRenewalSettingsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ChangeRenewalSettingsRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ChannelPartnerLink: Entity representing a link between
// distributors and their indirect resellers in an n-tier resale channel.
type GoogleCloudChannelV1ChannelPartnerLink struct {
	// ChannelPartnerCloudIdentityInfo: Output only. Cloud Identity info of the
	// channel partner (IR).
	ChannelPartnerCloudIdentityInfo *GoogleCloudChannelV1CloudIdentityInfo `json:"channelPartnerCloudIdentityInfo,omitempty"`
	// CreateTime: Output only. Timestamp of when the channel partner link is
	// created.
	CreateTime string `json:"createTime,omitempty"`
	// InviteLinkUri: Output only. URI of the web page where partner accepts the
	// link invitation.
	InviteLinkUri string `json:"inviteLinkUri,omitempty"`
	// LinkState: Required. State of the channel partner link.
	//
	// Possible values:
	//   "CHANNEL_PARTNER_LINK_STATE_UNSPECIFIED" - Not used.
	//   "INVITED" - An invitation has been sent to the reseller to create a
	// channel partner link.
	//   "ACTIVE" - Status when the reseller is active.
	//   "REVOKED" - Status when the reseller has been revoked by the distributor.
	//   "SUSPENDED" - Status when the reseller is suspended by Google or
	// distributor.
	LinkState string `json:"linkState,omitempty"`
	// Name: Output only. Resource name for the channel partner link, in the format
	// accounts/{account_id}/channelPartnerLinks/{id}.
	Name string `json:"name,omitempty"`
	// PublicId: Output only. Public identifier that a customer must use to
	// generate a transfer token to move to this distributor-reseller combination.
	PublicId string `json:"publicId,omitempty"`
	// ResellerCloudIdentityId: Required. Cloud Identity ID of the linked reseller.
	ResellerCloudIdentityId string `json:"resellerCloudIdentityId,omitempty"`
	// UpdateTime: Output only. Timestamp of when the channel partner link is
	// 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.
	// "ChannelPartnerCloudIdentityInfo") 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. "ChannelPartnerCloudIdentityInfo")
	// 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 GoogleCloudChannelV1ChannelPartnerLink) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ChannelPartnerLink
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ChannelPartnerRepricingConfig: Configuration for how a
// distributor will rebill a channel partner (also known as a
// distributor-authorized reseller).
type GoogleCloudChannelV1ChannelPartnerRepricingConfig struct {
	// Name: Output only. Resource name of the ChannelPartnerRepricingConfig.
	// Format:
	// accounts/{account_id}/channelPartnerLinks/{channel_partner_id}/channelPartner
	// RepricingConfigs/{id}.
	Name string `json:"name,omitempty"`
	// RepricingConfig: Required. The configuration for bill modifications made by
	// a reseller before sending it to ChannelPartner.
	RepricingConfig *GoogleCloudChannelV1RepricingConfig `json:"repricingConfig,omitempty"`
	// UpdateTime: Output only. Timestamp of an update to the repricing rule. If
	// `update_time` is after RepricingConfig.effective_invoice_month then it
	// indicates this was set mid-month.
	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. "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 GoogleCloudChannelV1ChannelPartnerRepricingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ChannelPartnerRepricingConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CheckCloudIdentityAccountsExistRequest: Request message
// for CloudChannelService.CheckCloudIdentityAccountsExist.
type GoogleCloudChannelV1CheckCloudIdentityAccountsExistRequest struct {
	// Domain: Required. Domain to fetch for Cloud Identity account customers,
	// including domain and team customers. For team customers, please use the
	// domain for their emails.
	Domain string `json:"domain,omitempty"`
	// PrimaryAdminEmail: Optional. Primary admin email to fetch for Cloud Identity
	// account team customer.
	PrimaryAdminEmail string `json:"primaryAdminEmail,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 GoogleCloudChannelV1CheckCloudIdentityAccountsExistRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CheckCloudIdentityAccountsExistRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CheckCloudIdentityAccountsExistResponse: Response
// message for CloudChannelService.CheckCloudIdentityAccountsExist.
type GoogleCloudChannelV1CheckCloudIdentityAccountsExistResponse struct {
	// CloudIdentityAccounts: The Cloud Identity accounts associated with the
	// domain.
	CloudIdentityAccounts []*GoogleCloudChannelV1CloudIdentityCustomerAccount `json:"cloudIdentityAccounts,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "CloudIdentityAccounts") 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. "CloudIdentityAccounts") 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 GoogleCloudChannelV1CheckCloudIdentityAccountsExistResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CheckCloudIdentityAccountsExistResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CloudIdentityCustomerAccount: Entity representing a
// Cloud Identity account that may be associated with a Channel Services API
// partner.
type GoogleCloudChannelV1CloudIdentityCustomerAccount struct {
	// ChannelPartnerCloudIdentityId: If existing = true, and is 2-tier customer,
	// the channel partner of the customer.
	ChannelPartnerCloudIdentityId string `json:"channelPartnerCloudIdentityId,omitempty"`
	// CustomerCloudIdentityId: If existing = true, the Cloud Identity ID of the
	// customer.
	CustomerCloudIdentityId string `json:"customerCloudIdentityId,omitempty"`
	// CustomerName: If owned = true, the name of the customer that owns the Cloud
	// Identity account. Customer_name uses the format:
	// accounts/{account_id}/customers/{customer_id}
	CustomerName string `json:"customerName,omitempty"`
	// CustomerType: If existing = true, the type of the customer.
	//
	// Possible values:
	//   "CUSTOMER_TYPE_UNSPECIFIED" - Not used.
	//   "DOMAIN" - Domain-owning customer which needs domain verification to use
	// services.
	//   "TEAM" - Team customer which needs email verification to use services.
	CustomerType string `json:"customerType,omitempty"`
	// Existing: Returns true if a Cloud Identity account exists for a specific
	// domain.
	Existing bool `json:"existing,omitempty"`
	// Owned: Returns true if the Cloud Identity account is associated with a
	// customer of the Channel Services partner (with active subscriptions or
	// purchase consents).
	Owned bool `json:"owned,omitempty"`
	// ForceSendFields is a list of field names (e.g.
	// "ChannelPartnerCloudIdentityId") 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. "ChannelPartnerCloudIdentityId")
	// 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 GoogleCloudChannelV1CloudIdentityCustomerAccount) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CloudIdentityCustomerAccount
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CloudIdentityInfo: Cloud Identity information for the
// Cloud Channel Customer.
type GoogleCloudChannelV1CloudIdentityInfo struct {
	// AdminConsoleUri: Output only. URI of Customer's Admin console dashboard.
	AdminConsoleUri string `json:"adminConsoleUri,omitempty"`
	// AlternateEmail: The alternate email.
	AlternateEmail string `json:"alternateEmail,omitempty"`
	// CustomerType: CustomerType indicates verification type needed for using
	// services.
	//
	// Possible values:
	//   "CUSTOMER_TYPE_UNSPECIFIED" - Not used.
	//   "DOMAIN" - Domain-owning customer which needs domain verification to use
	// services.
	//   "TEAM" - Team customer which needs email verification to use services.
	CustomerType string `json:"customerType,omitempty"`
	// EduData: Edu information about the customer.
	EduData *GoogleCloudChannelV1EduData `json:"eduData,omitempty"`
	// IsDomainVerified: Output only. Whether the domain is verified. This field is
	// not returned for a Customer's cloud_identity_info resource. Partners can use
	// the domains.get() method of the Workspace SDK's Directory API, or listen to
	// the PRIMARY_DOMAIN_VERIFIED Pub/Sub event in to track domain verification of
	// their resolve Workspace customers.
	IsDomainVerified bool `json:"isDomainVerified,omitempty"`
	// LanguageCode: Language code.
	LanguageCode string `json:"languageCode,omitempty"`
	// PhoneNumber: Phone number associated with the Cloud Identity.
	PhoneNumber string `json:"phoneNumber,omitempty"`
	// PrimaryDomain: Output only. The primary domain name.
	PrimaryDomain string `json:"primaryDomain,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AdminConsoleUri") 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. "AdminConsoleUri") 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 GoogleCloudChannelV1CloudIdentityInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CloudIdentityInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Column: The definition of a report column. Specifies the
// data properties in the corresponding position of the report rows.
type GoogleCloudChannelV1Column struct {
	// ColumnId: The unique name of the column (for example, customer_domain,
	// channel_partner, customer_cost). You can use column IDs in
	// RunReportJobRequest.filter. To see all reports and their columns, call
	// CloudChannelReportsService.ListReports.
	ColumnId string `json:"columnId,omitempty"`
	// DataType: The type of the values for this column.
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED" - Not used.
	//   "STRING" - ReportValues for this column will use string_value.
	//   "INT" - ReportValues for this column will use int_value.
	//   "DECIMAL" - ReportValues for this column will use decimal_value.
	//   "MONEY" - ReportValues for this column will use money_value.
	//   "DATE" - ReportValues for this column will use date_value.
	//   "DATE_TIME" - ReportValues for this column will use date_time_value.
	DataType string `json:"dataType,omitempty"`
	// DisplayName: The column's display name.
	DisplayName string `json:"displayName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ColumnId") 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. "ColumnId") 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 GoogleCloudChannelV1Column) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Column
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CommitmentSettings: Commitment settings for
// commitment-based offers.
type GoogleCloudChannelV1CommitmentSettings struct {
	// EndTime: Output only. Commitment end timestamp.
	EndTime string `json:"endTime,omitempty"`
	// RenewalSettings: Optional. Renewal settings applicable for a
	// commitment-based Offer.
	RenewalSettings *GoogleCloudChannelV1RenewalSettings `json:"renewalSettings,omitempty"`
	// StartTime: Output only. Commitment start timestamp.
	StartTime string `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. 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. "EndTime") 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 GoogleCloudChannelV1CommitmentSettings) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CommitmentSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ConditionalOverride: Specifies the override to
// conditionally apply.
type GoogleCloudChannelV1ConditionalOverride struct {
	// Adjustment: Required. Information about the applied override's adjustment.
	Adjustment *GoogleCloudChannelV1RepricingAdjustment `json:"adjustment,omitempty"`
	// RebillingBasis: Required. The RebillingBasis to use for the applied
	// override. Shows the relative cost based on your repricing costs.
	//
	// Possible values:
	//   "REBILLING_BASIS_UNSPECIFIED" - Not used.
	//   "COST_AT_LIST" - Use the list cost, also known as the MSRP.
	//   "DIRECT_CUSTOMER_COST" - Pass through all discounts except the Reseller
	// Program Discount. If this is the default cost base and no adjustments are
	// specified, the output cost will be exactly what the customer would see if
	// they viewed the bill in the Google Cloud Console.
	RebillingBasis string `json:"rebillingBasis,omitempty"`
	// RepricingCondition: Required. Specifies the condition which, if met, will
	// apply the override.
	RepricingCondition *GoogleCloudChannelV1RepricingCondition `json:"repricingCondition,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Adjustment") 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. "Adjustment") 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 GoogleCloudChannelV1ConditionalOverride) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ConditionalOverride
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Constraints: Represents the constraints for buying the
// Offer.
type GoogleCloudChannelV1Constraints struct {
	// CustomerConstraints: Represents constraints required to purchase the Offer
	// for a customer.
	CustomerConstraints *GoogleCloudChannelV1CustomerConstraints `json:"customerConstraints,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomerConstraints") 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. "CustomerConstraints") 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 GoogleCloudChannelV1Constraints) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Constraints
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ContactInfo: Contact information for a customer account.
type GoogleCloudChannelV1ContactInfo struct {
	// DisplayName: Output only. The customer account contact's display name,
	// formatted as a combination of the customer's first and last name.
	DisplayName string `json:"displayName,omitempty"`
	// Email: The customer account's contact email. Required for entitlements that
	// create admin.google.com accounts, and serves as the customer's username for
	// those accounts. Use this email to invite Team customers.
	Email string `json:"email,omitempty"`
	// FirstName: The customer account contact's first name. Optional for Team
	// customers.
	FirstName string `json:"firstName,omitempty"`
	// LastName: The customer account contact's last name. Optional for Team
	// customers.
	LastName string `json:"lastName,omitempty"`
	// Phone: The customer account's contact phone number.
	Phone string `json:"phone,omitempty"`
	// Title: Optional. The customer account contact's job title.
	Title string `json:"title,omitempty"`
	// 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 GoogleCloudChannelV1ContactInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ContactInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CreateEntitlementRequest: Request message for
// CloudChannelService.CreateEntitlement
type GoogleCloudChannelV1CreateEntitlementRequest struct {
	// Entitlement: Required. The entitlement to create.
	Entitlement *GoogleCloudChannelV1Entitlement `json:"entitlement,omitempty"`
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Entitlement") 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. "Entitlement") 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 GoogleCloudChannelV1CreateEntitlementRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CreateEntitlementRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Customer: Entity representing a customer of a reseller
// or distributor.
type GoogleCloudChannelV1Customer struct {
	// AlternateEmail: Secondary contact email. You need to provide an alternate
	// email to create different domains if a primary contact email already exists.
	// Users will receive a notification with credentials when you create an
	// admin.google.com account. Secondary emails are also recovery email
	// addresses. Alternate emails are optional when you create Team customers.
	AlternateEmail string `json:"alternateEmail,omitempty"`
	// ChannelPartnerId: Cloud Identity ID of the customer's channel partner.
	// Populated only if a channel partner exists for this customer.
	ChannelPartnerId string `json:"channelPartnerId,omitempty"`
	// CloudIdentityId: Output only. The customer's Cloud Identity ID if the
	// customer has a Cloud Identity resource.
	CloudIdentityId string `json:"cloudIdentityId,omitempty"`
	// CloudIdentityInfo: Output only. Cloud Identity information for the customer.
	// Populated only if a Cloud Identity account exists for this customer.
	CloudIdentityInfo *GoogleCloudChannelV1CloudIdentityInfo `json:"cloudIdentityInfo,omitempty"`
	// CorrelationId: Optional. External CRM ID for the customer. Populated only if
	// a CRM ID exists for this customer.
	CorrelationId string `json:"correlationId,omitempty"`
	// CreateTime: Output only. Time when the customer was created.
	CreateTime string `json:"createTime,omitempty"`
	// CustomerAttestationState: Optional. Indicate if a customer is attesting
	// about the correctness of provided information. Only required if creating a
	// GCP Entitlement. NOTE: This field will be mandatory for all new GCP
	// customers starting Aug 31st, 2026 and this field will also be required for
	// all existing customers purchasing new GCP Entitlements.
	//
	// Possible values:
	//   "CUSTOMER_ATTESTATION_STATE_UNSPECIFIED" - Default value if not set yet
	//   "EXEMPT" - Customer is exempt from attesting based on exemption list at
	// https://cloud.google.com/terms/direct-tos-exemptions. Contact information of
	// customer will be mandatory.
	//   "NON_EXEMPT_AND_INFO_VERIFIED" - Customer is not exempt and has verified
	// the information provided is correct. Contact information of customer will be
	// mandatory.
	CustomerAttestationState string `json:"customerAttestationState,omitempty"`
	// Domain: Required. The customer's primary domain. Must match the primary
	// contact email's domain.
	Domain string `json:"domain,omitempty"`
	// LanguageCode: Optional. The BCP-47 language code, such as "en-US" or
	// "sr-Latn". For more information, see
	// https://www.unicode.org/reports/tr35/#Unicode_locale_identifier.
	LanguageCode string `json:"languageCode,omitempty"`
	// Name: Output only. Resource name of the customer. Format:
	// accounts/{account_id}/customers/{customer_id}
	Name string `json:"name,omitempty"`
	// OrgDisplayName: Required. Name of the organization that the customer entity
	// represents.
	OrgDisplayName string `json:"orgDisplayName,omitempty"`
	// OrgPostalAddress: Required. The organization address for the customer. To
	// enforce US laws and embargoes, we require a region, postal code, and address
	// lines. You must provide valid addresses for every customer. To set the
	// customer's language, use the Customer-level language code.
	OrgPostalAddress *GoogleTypePostalAddress `json:"orgPostalAddress,omitempty"`
	// PrimaryContactInfo: Primary contact info.
	PrimaryContactInfo *GoogleCloudChannelV1ContactInfo `json:"primaryContactInfo,omitempty"`
	// UpdateTime: Output only. Time when the customer was 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. "AlternateEmail") 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. "AlternateEmail") 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 GoogleCloudChannelV1Customer) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Customer
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CustomerConstraints: Represents constraints required to
// purchase the Offer for a customer.
type GoogleCloudChannelV1CustomerConstraints struct {
	// AllowedCustomerTypes: Allowed Customer Type.
	//
	// Possible values:
	//   "CUSTOMER_TYPE_UNSPECIFIED" - Not used.
	//   "DOMAIN" - Domain-owning customer which needs domain verification to use
	// services.
	//   "TEAM" - Team customer which needs email verification to use services.
	AllowedCustomerTypes []string `json:"allowedCustomerTypes,omitempty"`
	// AllowedRegions: Allowed geographical regions of the customer.
	AllowedRegions []string `json:"allowedRegions,omitempty"`
	// PromotionalOrderTypes: Allowed Promotional Order Type. Present for
	// Promotional offers.
	//
	// Possible values:
	//   "PROMOTIONAL_TYPE_UNSPECIFIED" - Not used.
	//   "NEW_UPGRADE" - Order used for new customers, trial conversions and
	// upgrades.
	//   "TRANSFER" - All orders for transferring an existing customer.
	//   "PROMOTION_SWITCH" - Orders for modifying an existing customer's promotion
	// on the same SKU.
	PromotionalOrderTypes []string `json:"promotionalOrderTypes,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AllowedCustomerTypes") 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. "AllowedCustomerTypes") 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 GoogleCloudChannelV1CustomerConstraints) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CustomerConstraints
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CustomerEvent: Represents Pub/Sub message content
// describing customer update.
type GoogleCloudChannelV1CustomerEvent struct {
	// Customer: Resource name of the customer. Format:
	// accounts/{account_id}/customers/{customer_id}
	Customer string `json:"customer,omitempty"`
	// EventType: Type of event which happened for the customer.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Not used.
	//   "PRIMARY_DOMAIN_CHANGED" - Primary domain for customer was changed.
	//   "PRIMARY_DOMAIN_VERIFIED" - Primary domain of the customer has been
	// verified.
	EventType string `json:"eventType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Customer") 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. "Customer") 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 GoogleCloudChannelV1CustomerEvent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CustomerEvent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1CustomerRepricingConfig: Configuration for how a
// reseller will reprice a Customer.
type GoogleCloudChannelV1CustomerRepricingConfig struct {
	// Name: Output only. Resource name of the CustomerRepricingConfig. Format:
	// accounts/{account_id}/customers/{customer_id}/customerRepricingConfigs/{id}.
	Name string `json:"name,omitempty"`
	// RepricingConfig: Required. The configuration for bill modifications made by
	// a reseller before sending it to customers.
	RepricingConfig *GoogleCloudChannelV1RepricingConfig `json:"repricingConfig,omitempty"`
	// UpdateTime: Output only. Timestamp of an update to the repricing rule. If
	// `update_time` is after RepricingConfig.effective_invoice_month then it
	// indicates this was set mid-month.
	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. "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 GoogleCloudChannelV1CustomerRepricingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1CustomerRepricingConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1DateRange: A representation of usage or invoice date
// ranges.
type GoogleCloudChannelV1DateRange struct {
	// InvoiceEndDate: The latest invoice date (inclusive). If this value is not
	// the last day of a month, this will move it forward to the last day of the
	// given month.
	InvoiceEndDate *GoogleTypeDate `json:"invoiceEndDate,omitempty"`
	// InvoiceStartDate: The earliest invoice date (inclusive). If this value is
	// not the first day of a month, this will move it back to the first day of the
	// given month.
	InvoiceStartDate *GoogleTypeDate `json:"invoiceStartDate,omitempty"`
	// UsageEndDateTime: The latest usage date time (exclusive). If you use time
	// groupings (daily, weekly, etc), each group uses midnight to midnight
	// (Pacific time). The usage end date is rounded down to include all usage from
	// the specified date. We recommend that clients pass `usage_start_date_time`
	// in Pacific time.
	UsageEndDateTime *GoogleTypeDateTime `json:"usageEndDateTime,omitempty"`
	// UsageStartDateTime: The earliest usage date time (inclusive). If you use
	// time groupings (daily, weekly, etc), each group uses midnight to midnight
	// (Pacific time). The usage start date is rounded down to include all usage
	// from the specified date. We recommend that clients pass
	// `usage_start_date_time` in Pacific time.
	UsageStartDateTime *GoogleTypeDateTime `json:"usageStartDateTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "InvoiceEndDate") 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. "InvoiceEndDate") 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 GoogleCloudChannelV1DateRange) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1DateRange
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1DiscountComponent: Represents a single component of the
// total discount applicable on a Price.
type GoogleCloudChannelV1DiscountComponent struct {
	// DiscountAbsolute: Fixed value discount.
	DiscountAbsolute *GoogleTypeMoney `json:"discountAbsolute,omitempty"`
	// DiscountPercentage: Discount percentage, represented as decimal. For
	// example, a 20% discount will be represented as 0.2.
	DiscountPercentage float64 `json:"discountPercentage,omitempty"`
	// DiscountType: Type of the discount.
	//
	// Possible values:
	//   "DISCOUNT_TYPE_UNSPECIFIED" - Not used.
	//   "REGIONAL_DISCOUNT" - Regional discount.
	//   "PROMOTIONAL_DISCOUNT" - Promotional discount.
	//   "SALES_DISCOUNT" - Sales-provided discount.
	//   "RESELLER_MARGIN" - Reseller margin.
	//   "DEAL_CODE" - Deal code discount.
	DiscountType string `json:"discountType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DiscountAbsolute") 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. "DiscountAbsolute") 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 GoogleCloudChannelV1DiscountComponent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1DiscountComponent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

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

// GoogleCloudChannelV1EduData: Required Edu Attributes
type GoogleCloudChannelV1EduData struct {
	// InstituteSize: Size of the institute.
	//
	// Possible values:
	//   "INSTITUTE_SIZE_UNSPECIFIED" - Not used.
	//   "SIZE_1_100" - 1 - 100
	//   "SIZE_101_500" - 101 - 500
	//   "SIZE_501_1000" - 501 - 1,000
	//   "SIZE_1001_2000" - 1,001 - 2,000
	//   "SIZE_2001_5000" - 2,001 - 5,000
	//   "SIZE_5001_10000" - 5,001 - 10,000
	//   "SIZE_10001_OR_MORE" - 10,001 +
	InstituteSize string `json:"instituteSize,omitempty"`
	// InstituteType: Designated institute type of customer.
	//
	// Possible values:
	//   "INSTITUTE_TYPE_UNSPECIFIED" - Not used.
	//   "K12" - Elementary/Secondary Schools & Districts
	//   "UNIVERSITY" - Higher Education Universities & Colleges
	InstituteType string `json:"instituteType,omitempty"`
	// Website: Web address for the edu customer's institution.
	Website string `json:"website,omitempty"`
	// ForceSendFields is a list of field names (e.g. "InstituteSize") 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. "InstituteSize") 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 GoogleCloudChannelV1EduData) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1EduData
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Entitlement: An entitlement is a representation of a
// customer's ability to use a service.
type GoogleCloudChannelV1Entitlement struct {
	// AssociationInfo: Association information to other entitlements.
	AssociationInfo *GoogleCloudChannelV1AssociationInfo `json:"associationInfo,omitempty"`
	// BillingAccount: Optional. The billing account resource name that is used to
	// pay for this entitlement.
	BillingAccount string `json:"billingAccount,omitempty"`
	// CommitmentSettings: Commitment settings for a commitment-based Offer.
	// Required for commitment based offers.
	CommitmentSettings *GoogleCloudChannelV1CommitmentSettings `json:"commitmentSettings,omitempty"`
	// CreateTime: Output only. The time at which the entitlement is created.
	CreateTime string `json:"createTime,omitempty"`
	// Name: Output only. Resource name of an entitlement in the form:
	// accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
	Name string `json:"name,omitempty"`
	// Offer: Required. The offer resource name for which the entitlement is to be
	// created. Takes the form: accounts/{account_id}/offers/{offer_id}.
	Offer string `json:"offer,omitempty"`
	// Parameters: Extended entitlement parameters. When creating an entitlement,
	// valid parameter names and values are defined in the
	// Offer.parameter_definitions. For Google Workspace, the following Parameters
	// may be accepted as input: - max_units: The maximum assignable units for a
	// flexible offer OR - num_units: The total commitment for commitment-based
	// offers The response may additionally include the following output-only
	// Parameters: - assigned_units: The number of licenses assigned to users. For
	// Google Cloud billing subaccounts, the following Parameter may be accepted as
	// input: - display_name: The display name of the billing subaccount.
	Parameters []*GoogleCloudChannelV1Parameter `json:"parameters,omitempty"`
	// PriceReferenceId: Optional. Price reference ID for the offer. Only for
	// offers that require additional price information. Used to guarantee that the
	// pricing is consistent between quoting the offer and placing the order.
	PriceReferenceId string `json:"priceReferenceId,omitempty"`
	// ProvisionedService: Output only. Service provisioning details for the
	// entitlement.
	ProvisionedService *GoogleCloudChannelV1ProvisionedService `json:"provisionedService,omitempty"`
	// ProvisioningState: Output only. Current provisioning state of the
	// entitlement.
	//
	// Possible values:
	//   "PROVISIONING_STATE_UNSPECIFIED" - Not used.
	//   "ACTIVE" - The entitlement is currently active.
	//   "SUSPENDED" - The entitlement is currently suspended.
	ProvisioningState string `json:"provisioningState,omitempty"`
	// PurchaseOrderId: Optional. This purchase order (PO) information is for
	// resellers to use for their company tracking usage. If a purchaseOrderId
	// value is given, it appears in the API responses and shows up in the invoice.
	// The property accepts up to 80 plain text characters. This is only supported
	// for Google Workspace entitlements.
	PurchaseOrderId string `json:"purchaseOrderId,omitempty"`
	// SuspensionReasons: Output only. Enumerable of all current suspension reasons
	// for an entitlement.
	//
	// Possible values:
	//   "SUSPENSION_REASON_UNSPECIFIED" - Not used.
	//   "RESELLER_INITIATED" - Entitlement was manually suspended by the Reseller.
	//   "TRIAL_ENDED" - Trial ended.
	//   "RENEWAL_WITH_TYPE_CANCEL" - Entitlement renewal was canceled.
	//   "PENDING_TOS_ACCEPTANCE" - Entitlement was automatically suspended on
	// creation for pending ToS acceptance on customer.
	//   "OTHER" - Other reasons (internal reasons, abuse, etc.).
	SuspensionReasons []string `json:"suspensionReasons,omitempty"`
	// TrialSettings: Output only. Settings for trial offers.
	TrialSettings *GoogleCloudChannelV1TrialSettings `json:"trialSettings,omitempty"`
	// UpdateTime: Output only. The time at which the entitlement is 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. "AssociationInfo") 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. "AssociationInfo") 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 GoogleCloudChannelV1Entitlement) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Entitlement
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1EntitlementChange: Change event entry for Entitlement
// order history
type GoogleCloudChannelV1EntitlementChange struct {
	// ActivationReason: The Entitlement's activation reason
	//
	// Possible values:
	//   "ACTIVATION_REASON_UNSPECIFIED" - Not used.
	//   "RESELLER_REVOKED_SUSPENSION" - Reseller reactivated a suspended
	// Entitlement.
	//   "CUSTOMER_ACCEPTED_PENDING_TOS" - Customer accepted pending terms of
	// service.
	//   "RENEWAL_SETTINGS_CHANGED" - Reseller updated the renewal settings on an
	// entitlement that was suspended due to cancellation, and this update
	// reactivated the entitlement.
	//   "OTHER_ACTIVATION_REASON" - Other reasons (Activated temporarily for
	// cancellation, added a payment plan to a trial entitlement, etc.)
	ActivationReason string `json:"activationReason,omitempty"`
	// CancellationReason: Cancellation reason for the Entitlement.
	//
	// Possible values:
	//   "CANCELLATION_REASON_UNSPECIFIED" - Not used.
	//   "SERVICE_TERMINATED" - Reseller triggered a cancellation of the service.
	//   "RELATIONSHIP_ENDED" - Relationship between the reseller and customer has
	// ended due to a transfer.
	//   "PARTIAL_TRANSFER" - Entitlement transferred away from reseller while
	// still keeping other entitlement(s) with the reseller.
	CancellationReason string `json:"cancellationReason,omitempty"`
	// ChangeType: The change action type.
	//
	// Possible values:
	//   "CHANGE_TYPE_UNSPECIFIED" - Not used.
	//   "CREATED" - New Entitlement was created.
	//   "PRICE_PLAN_SWITCHED" - Price plan associated with an Entitlement was
	// changed.
	//   "COMMITMENT_CHANGED" - Number of seats committed for a commitment
	// Entitlement was changed.
	//   "RENEWED" - An annual Entitlement was renewed.
	//   "SUSPENDED" - Entitlement was suspended.
	//   "ACTIVATED" - Entitlement was activated.
	//   "CANCELLED" - Entitlement was cancelled.
	//   "SKU_CHANGED" - Entitlement was upgraded or downgraded for ex. from Google
	// Workspace Business Standard to Google Workspace Business Plus.
	//   "RENEWAL_SETTING_CHANGED" - The settings for renewal of an Entitlement
	// have changed.
	//   "PAID_SUBSCRIPTION_STARTED" - Use for Google Workspace subscription.
	// Either a trial was converted to a paid subscription or a new subscription
	// with no trial is created.
	//   "LICENSE_CAP_CHANGED" - License cap was changed for the entitlement.
	//   "SUSPENSION_DETAILS_CHANGED" - The suspension details have changed (but it
	// is still suspended).
	//   "TRIAL_END_DATE_EXTENDED" - The trial end date was extended.
	//   "TRIAL_STARTED" - Entitlement started trial.
	ChangeType string `json:"changeType,omitempty"`
	// CreateTime: The submitted time of the change.
	CreateTime string `json:"createTime,omitempty"`
	// Entitlement: Required. Resource name of an entitlement in the form:
	// accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}
	Entitlement string `json:"entitlement,omitempty"`
	// Offer: Required. Resource name of the Offer at the time of change. Takes the
	// form: accounts/{account_id}/offers/{offer_id}.
	Offer string `json:"offer,omitempty"`
	// Operator: Human-readable identifier that shows what operator made a change.
	// When the operator_type is RESELLER, this is the user's email address. For
	// all other operator types, this is empty.
	Operator string `json:"operator,omitempty"`
	// OperatorType: Operator type responsible for the change.
	//
	// Possible values:
	//   "OPERATOR_TYPE_UNSPECIFIED" - Not used.
	//   "CUSTOMER_SERVICE_REPRESENTATIVE" - Customer service representative.
	//   "SYSTEM" - System auto job.
	//   "CUSTOMER" - Customer user.
	//   "RESELLER" - Reseller user.
	OperatorType string `json:"operatorType,omitempty"`
	// OtherChangeReason: e.g. purchase_number change reason, entered by CRS.
	OtherChangeReason string `json:"otherChangeReason,omitempty"`
	// Parameters: Extended parameters, such as: purchase_order_number,
	// gcp_details; internal_correlation_id, long_running_operation_id, order_id;
	// etc.
	Parameters []*GoogleCloudChannelV1Parameter `json:"parameters,omitempty"`
	// ProvisionedService: Service provisioned for an Entitlement.
	ProvisionedService *GoogleCloudChannelV1ProvisionedService `json:"provisionedService,omitempty"`
	// SuspensionReason: Suspension reason for the Entitlement.
	//
	// Possible values:
	//   "SUSPENSION_REASON_UNSPECIFIED" - Not used.
	//   "RESELLER_INITIATED" - Entitlement was manually suspended by the Reseller.
	//   "TRIAL_ENDED" - Trial ended.
	//   "RENEWAL_WITH_TYPE_CANCEL" - Entitlement renewal was canceled.
	//   "PENDING_TOS_ACCEPTANCE" - Entitlement was automatically suspended on
	// creation for pending ToS acceptance on customer.
	//   "OTHER" - Other reasons (internal reasons, abuse, etc.).
	SuspensionReason string `json:"suspensionReason,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ActivationReason") 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. "ActivationReason") 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 GoogleCloudChannelV1EntitlementChange) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1EntitlementChange
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1EntitlementEvent: Represents Pub/Sub message content
// describing entitlement update.
type GoogleCloudChannelV1EntitlementEvent struct {
	// Entitlement: Resource name of an entitlement of the form:
	// accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}
	Entitlement string `json:"entitlement,omitempty"`
	// EventType: Type of event which happened for the entitlement.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Not used.
	//   "CREATED" - A new entitlement was created.
	//   "PRICE_PLAN_SWITCHED" - The offer type associated with an entitlement was
	// changed. This is not triggered if an entitlement converts from a commit
	// offer to a flexible offer as part of a renewal.
	//   "COMMITMENT_CHANGED" - Annual commitment for a commit plan was changed.
	//   "RENEWED" - An annual entitlement was renewed.
	//   "SUSPENDED" - Entitlement was suspended.
	//   "ACTIVATED" - Entitlement was unsuspended.
	//   "CANCELLED" - Entitlement was cancelled.
	//   "SKU_CHANGED" - Entitlement was upgraded or downgraded (e.g. from Google
	// Workspace Business Standard to Google Workspace Business Plus).
	//   "RENEWAL_SETTING_CHANGED" - The renewal settings of an entitlement has
	// changed.
	//   "PAID_SERVICE_STARTED" - Paid service has started on trial entitlement.
	//   "LICENSE_ASSIGNMENT_CHANGED" - License was assigned to or revoked from a
	// user.
	//   "LICENSE_CAP_CHANGED" - License cap was changed for the entitlement.
	EventType string `json:"eventType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Entitlement") 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. "Entitlement") 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 GoogleCloudChannelV1EntitlementEvent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1EntitlementEvent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1FetchReportResultsRequest: Request message for
// CloudChannelReportsService.FetchReportResults.
type GoogleCloudChannelV1FetchReportResultsRequest struct {
	// PageSize: Optional. Requested page size of the report. The server may return
	// fewer results than requested. If you don't specify a page size, the server
	// uses a sensible default (may change over time). The maximum value is 30,000;
	// the server will change larger values to 30,000.
	PageSize int64 `json:"pageSize,omitempty"`
	// PageToken: Optional. A token that specifies a page of results beyond the
	// first page. Obtained through FetchReportResultsResponse.next_page_token of
	// the previous CloudChannelReportsService.FetchReportResults call.
	PageToken string `json:"pageToken,omitempty"`
	// PartitionKeys: Optional. List of keys specifying which report partitions to
	// return. If empty, returns all partitions.
	PartitionKeys []string `json:"partitionKeys,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PageSize") 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. "PageSize") 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 GoogleCloudChannelV1FetchReportResultsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1FetchReportResultsRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1FetchReportResultsResponse: Response message for
// CloudChannelReportsService.FetchReportResults. Contains a tabular
// representation of the report results.
type GoogleCloudChannelV1FetchReportResultsResponse struct {
	// NextPageToken: Pass this token to FetchReportResultsRequest.page_token to
	// retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// ReportMetadata: The metadata for the report results (display name, columns,
	// row count, and date ranges).
	ReportMetadata *GoogleCloudChannelV1ReportResultsMetadata `json:"reportMetadata,omitempty"`
	// Rows: The report's lists of values. Each row follows the settings and
	// ordering of the columns from `report_metadata`.
	Rows []*GoogleCloudChannelV1Row `json:"rows,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 GoogleCloudChannelV1FetchReportResultsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1FetchReportResultsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ImportCustomerRequest: Request message for
// CloudChannelService.ImportCustomer
type GoogleCloudChannelV1ImportCustomerRequest struct {
	// AuthToken: Optional. The super admin of the resold customer generates this
	// token to authorize a reseller to access their Cloud Identity and purchase
	// entitlements on their behalf. You can omit this token after authorization.
	// See https://support.google.com/a/answer/7643790 for more details.
	AuthToken string `json:"authToken,omitempty"`
	// ChannelPartnerId: Optional. Cloud Identity ID of a channel partner who will
	// be the direct reseller for the customer's order. This field is required for
	// 2-tier transfer scenarios and can be provided via the request Parent binding
	// as well.
	ChannelPartnerId string `json:"channelPartnerId,omitempty"`
	// CloudIdentityId: Required. Customer's Cloud Identity ID
	CloudIdentityId string `json:"cloudIdentityId,omitempty"`
	// Customer: Optional. Specifies the customer that will receive imported Cloud
	// Identity information. Format: accounts/{account_id}/customers/{customer_id}
	Customer string `json:"customer,omitempty"`
	// Domain: Required. Customer domain.
	Domain string `json:"domain,omitempty"`
	// OverwriteIfExists: Required. Choose to overwrite an existing customer if
	// found. This must be set to true if there is an existing customer with a
	// conflicting region code or domain.
	OverwriteIfExists bool `json:"overwriteIfExists,omitempty"`
	// PrimaryAdminEmail: Required. Customer's primary admin email.
	PrimaryAdminEmail string `json:"primaryAdminEmail,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AuthToken") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. 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. "AuthToken") 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 GoogleCloudChannelV1ImportCustomerRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ImportCustomerRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListChannelPartnerLinksResponse: Response message for
// CloudChannelService.ListChannelPartnerLinks.
type GoogleCloudChannelV1ListChannelPartnerLinksResponse struct {
	// ChannelPartnerLinks: The Channel partner links for a reseller.
	ChannelPartnerLinks []*GoogleCloudChannelV1ChannelPartnerLink `json:"channelPartnerLinks,omitempty"`
	// NextPageToken: A token to retrieve the next page of results. Pass to
	// ListChannelPartnerLinksRequest.page_token to obtain that 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. "ChannelPartnerLinks") 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. "ChannelPartnerLinks") 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 GoogleCloudChannelV1ListChannelPartnerLinksResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListChannelPartnerLinksResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListChannelPartnerRepricingConfigsResponse: Response
// message for CloudChannelService.ListChannelPartnerRepricingConfigs.
type GoogleCloudChannelV1ListChannelPartnerRepricingConfigsResponse struct {
	// ChannelPartnerRepricingConfigs: The repricing configs for this channel
	// partner.
	ChannelPartnerRepricingConfigs []*GoogleCloudChannelV1ChannelPartnerRepricingConfig `json:"channelPartnerRepricingConfigs,omitempty"`
	// NextPageToken: A token to retrieve the next page of results. Pass to
	// ListChannelPartnerRepricingConfigsRequest.page_token to obtain that 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.
	// "ChannelPartnerRepricingConfigs") 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. "ChannelPartnerRepricingConfigs")
	// 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 GoogleCloudChannelV1ListChannelPartnerRepricingConfigsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListChannelPartnerRepricingConfigsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListCustomerRepricingConfigsResponse: Response message
// for CloudChannelService.ListCustomerRepricingConfigs.
type GoogleCloudChannelV1ListCustomerRepricingConfigsResponse struct {
	// CustomerRepricingConfigs: The repricing configs for this channel partner.
	CustomerRepricingConfigs []*GoogleCloudChannelV1CustomerRepricingConfig `json:"customerRepricingConfigs,omitempty"`
	// NextPageToken: A token to retrieve the next page of results. Pass to
	// ListCustomerRepricingConfigsRequest.page_token to obtain that 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. "CustomerRepricingConfigs")
	// 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. "CustomerRepricingConfigs") 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 GoogleCloudChannelV1ListCustomerRepricingConfigsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListCustomerRepricingConfigsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListCustomersResponse: Response message for
// CloudChannelService.ListCustomers.
type GoogleCloudChannelV1ListCustomersResponse struct {
	// Customers: The customers belonging to a reseller or distributor.
	Customers []*GoogleCloudChannelV1Customer `json:"customers,omitempty"`
	// NextPageToken: A token to retrieve the next page of results. Pass to
	// ListCustomersRequest.page_token to obtain that 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. "Customers") 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. "Customers") 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 GoogleCloudChannelV1ListCustomersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListCustomersResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListEntitlementChangesResponse: Response message for
// CloudChannelService.ListEntitlementChanges
type GoogleCloudChannelV1ListEntitlementChangesResponse struct {
	// EntitlementChanges: The list of entitlement changes.
	EntitlementChanges []*GoogleCloudChannelV1EntitlementChange `json:"entitlementChanges,omitempty"`
	// NextPageToken: A token to list the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "EntitlementChanges") 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. "EntitlementChanges") 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 GoogleCloudChannelV1ListEntitlementChangesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListEntitlementChangesResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListEntitlementsResponse: Response message for
// CloudChannelService.ListEntitlements.
type GoogleCloudChannelV1ListEntitlementsResponse struct {
	// Entitlements: The reseller customer's entitlements.
	Entitlements []*GoogleCloudChannelV1Entitlement `json:"entitlements,omitempty"`
	// NextPageToken: A token to list the next page of results. Pass to
	// ListEntitlementsRequest.page_token to obtain that 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. "Entitlements") 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. "Entitlements") 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 GoogleCloudChannelV1ListEntitlementsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListEntitlementsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListOffersResponse: Response message for ListOffers.
type GoogleCloudChannelV1ListOffersResponse struct {
	// NextPageToken: A token to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Offers: The list of Offers requested. The pricing information for each Offer
	// only includes the base price. Effective prices and discounts aren't
	// populated.
	Offers []*GoogleCloudChannelV1Offer `json:"offers,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 GoogleCloudChannelV1ListOffersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListOffersResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListProductsResponse: Response message for ListProducts.
type GoogleCloudChannelV1ListProductsResponse struct {
	// NextPageToken: A token to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Products: List of Products requested.
	Products []*GoogleCloudChannelV1Product `json:"products,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 GoogleCloudChannelV1ListProductsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListProductsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListPurchasableOffersResponse: Response message for
// ListPurchasableOffers.
type GoogleCloudChannelV1ListPurchasableOffersResponse struct {
	// NextPageToken: A token to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// PurchasableOffers: The list of Offers requested.
	PurchasableOffers []*GoogleCloudChannelV1PurchasableOffer `json:"purchasableOffers,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 GoogleCloudChannelV1ListPurchasableOffersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListPurchasableOffersResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListPurchasableSkusResponse: Response message for
// ListPurchasableSkus.
type GoogleCloudChannelV1ListPurchasableSkusResponse struct {
	// NextPageToken: A token to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// PurchasableSkus: The list of SKUs requested.
	PurchasableSkus []*GoogleCloudChannelV1PurchasableSku `json:"purchasableSkus,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 GoogleCloudChannelV1ListPurchasableSkusResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListPurchasableSkusResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListReportsResponse: Response message for
// CloudChannelReportsService.ListReports.
type GoogleCloudChannelV1ListReportsResponse struct {
	// NextPageToken: Pass this token to FetchReportResultsRequest.page_token to
	// retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Reports: The reports available to the partner.
	Reports []*GoogleCloudChannelV1Report `json:"reports,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 GoogleCloudChannelV1ListReportsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListReportsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListSkuGroupBillableSkusResponse: Response message for
// ListSkuGroupBillableSkus.
type GoogleCloudChannelV1ListSkuGroupBillableSkusResponse struct {
	// BillableSkus: The list of billable SKUs in the requested SKU group.
	BillableSkus []*GoogleCloudChannelV1BillableSku `json:"billableSkus,omitempty"`
	// NextPageToken: A token to retrieve the next page of results. Pass to
	// ListSkuGroupBillableSkusRequest.page_token to obtain that 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. "BillableSkus") 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. "BillableSkus") 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 GoogleCloudChannelV1ListSkuGroupBillableSkusResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListSkuGroupBillableSkusResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListSkuGroupsResponse: Response message for
// ListSkuGroups.
type GoogleCloudChannelV1ListSkuGroupsResponse struct {
	// NextPageToken: A token to retrieve the next page of results. Pass to
	// ListSkuGroupsRequest.page_token to obtain that page.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// SkuGroups: The list of SKU groups requested.
	SkuGroups []*GoogleCloudChannelV1SkuGroup `json:"skuGroups,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 GoogleCloudChannelV1ListSkuGroupsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListSkuGroupsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListSkusResponse: Response message for ListSkus.
type GoogleCloudChannelV1ListSkusResponse struct {
	// NextPageToken: A token to retrieve the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Skus: The list of SKUs requested.
	Skus []*GoogleCloudChannelV1Sku `json:"skus,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 GoogleCloudChannelV1ListSkusResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListSkusResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListSubscribersResponse: Response Message for
// ListSubscribers.
type GoogleCloudChannelV1ListSubscribersResponse 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"`
	// ServiceAccounts: List of service accounts which have subscriber access to
	// the topic.
	ServiceAccounts []string `json:"serviceAccounts,omitempty"`
	// Topic: Name of the topic registered with the reseller.
	Topic string `json:"topic,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 GoogleCloudChannelV1ListSubscribersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListSubscribersResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListTransferableOffersRequest: Request message for
// CloudChannelService.ListTransferableOffers
type GoogleCloudChannelV1ListTransferableOffersRequest struct {
	// BillingAccount: Optional. The Billing Account to look up Offers for. Format:
	// accounts/{account_id}/billingAccounts/{billing_account_id}. This field is
	// only relevant for multi-currency accounts. It should be left empty for
	// single currency accounts.
	BillingAccount string `json:"billingAccount,omitempty"`
	// CloudIdentityId: Customer's Cloud Identity ID
	CloudIdentityId string `json:"cloudIdentityId,omitempty"`
	// CustomerName: A reseller should create a customer and use the resource name
	// of that customer here.
	CustomerName string `json:"customerName,omitempty"`
	// LanguageCode: Optional. The BCP-47 language code. For example, "en-US". The
	// response will localize in the corresponding language code, if specified. The
	// default value is "en-US".
	LanguageCode string `json:"languageCode,omitempty"`
	// PageSize: Requested page size. Server might return fewer results than
	// requested. If unspecified, returns at most 100 offers. The maximum value is
	// 1000; the server will coerce values above 1000.
	PageSize int64 `json:"pageSize,omitempty"`
	// PageToken: A token for a page of results other than the first page. Obtained
	// using ListTransferableOffersResponse.next_page_token of the previous
	// CloudChannelService.ListTransferableOffers call.
	PageToken string `json:"pageToken,omitempty"`
	// Sku: Required. The SKU to look up Offers for.
	Sku string `json:"sku,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BillingAccount") 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. "BillingAccount") 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 GoogleCloudChannelV1ListTransferableOffersRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListTransferableOffersRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListTransferableOffersResponse: Response message for
// CloudChannelService.ListTransferableOffers.
type GoogleCloudChannelV1ListTransferableOffersResponse struct {
	// NextPageToken: A token to retrieve the next page of results. Pass to
	// ListTransferableOffersRequest.page_token to obtain that page.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// TransferableOffers: Information about Offers for a customer that can be used
	// for transfer.
	TransferableOffers []*GoogleCloudChannelV1TransferableOffer `json:"transferableOffers,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 GoogleCloudChannelV1ListTransferableOffersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListTransferableOffersResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListTransferableSkusRequest: Request message for
// CloudChannelService.ListTransferableSkus
type GoogleCloudChannelV1ListTransferableSkusRequest struct {
	// AuthToken: Optional. The super admin of the resold customer generates this
	// token to authorize a reseller to access their Cloud Identity and purchase
	// entitlements on their behalf. You can omit this token after authorization.
	// See https://support.google.com/a/answer/7643790 for more details.
	AuthToken string `json:"authToken,omitempty"`
	// CloudIdentityId: Customer's Cloud Identity ID
	CloudIdentityId string `json:"cloudIdentityId,omitempty"`
	// CustomerName: A reseller is required to create a customer and use the
	// resource name of the created customer here. Customer_name uses the format:
	// accounts/{account_id}/customers/{customer_id}
	CustomerName string `json:"customerName,omitempty"`
	// LanguageCode: The BCP-47 language code. For example, "en-US". The response
	// will localize in the corresponding language code, if specified. The default
	// value is "en-US". Optional.
	LanguageCode string `json:"languageCode,omitempty"`
	// PageSize: The requested page size. Server might return fewer results than
	// requested. If unspecified, returns at most 100 SKUs. The maximum value is
	// 1000; the server will coerce values above 1000. Optional.
	PageSize int64 `json:"pageSize,omitempty"`
	// PageToken: A token for a page of results other than the first page. Obtained
	// using ListTransferableSkusResponse.next_page_token of the previous
	// CloudChannelService.ListTransferableSkus call. Optional.
	PageToken string `json:"pageToken,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AuthToken") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. 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. "AuthToken") 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 GoogleCloudChannelV1ListTransferableSkusRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListTransferableSkusRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ListTransferableSkusResponse: Response message for
// CloudChannelService.ListTransferableSkus.
type GoogleCloudChannelV1ListTransferableSkusResponse struct {
	// NextPageToken: A token to retrieve the next page of results. Pass to
	// ListTransferableSkusRequest.page_token to obtain that page.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// TransferableSkus: Information about existing SKUs for a customer that needs
	// a transfer.
	TransferableSkus []*GoogleCloudChannelV1TransferableSku `json:"transferableSkus,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 GoogleCloudChannelV1ListTransferableSkusResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ListTransferableSkusResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1MarketingInfo: Represents the marketing information for
// a Product, SKU or Offer.
type GoogleCloudChannelV1MarketingInfo struct {
	// DefaultLogo: Default logo.
	DefaultLogo *GoogleCloudChannelV1Media `json:"defaultLogo,omitempty"`
	// Description: Human readable description. Description can contain HTML.
	Description string `json:"description,omitempty"`
	// DisplayName: Human readable name.
	DisplayName string `json:"displayName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DefaultLogo") 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. "DefaultLogo") 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 GoogleCloudChannelV1MarketingInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1MarketingInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Media: Represents media information.
type GoogleCloudChannelV1Media struct {
	// Content: URL of the media.
	Content string `json:"content,omitempty"`
	// Title: Title of the media.
	Title string `json:"title,omitempty"`
	// Type: Type of the media.
	//
	// Possible values:
	//   "MEDIA_TYPE_UNSPECIFIED" - Not used.
	//   "MEDIA_TYPE_IMAGE" - Type of image.
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Content") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. 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. "Content") 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 GoogleCloudChannelV1Media) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Media
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Offer: Represents an offer made to resellers for
// purchase. An offer is associated with a Sku, has a plan for payment, a
// price, and defines the constraints for buying.
type GoogleCloudChannelV1Offer struct {
	// Constraints: Constraints on transacting the Offer.
	Constraints *GoogleCloudChannelV1Constraints `json:"constraints,omitempty"`
	// DealCode: The deal code of the offer to get a special promotion or discount.
	DealCode string `json:"dealCode,omitempty"`
	// EndTime: Output only. End of the Offer validity time.
	EndTime string `json:"endTime,omitempty"`
	// MarketingInfo: Marketing information for the Offer.
	MarketingInfo *GoogleCloudChannelV1MarketingInfo `json:"marketingInfo,omitempty"`
	// Name: Resource Name of the Offer. Format:
	// accounts/{account_id}/offers/{offer_id}
	Name string `json:"name,omitempty"`
	// ParameterDefinitions: Parameters required to use current Offer to purchase.
	ParameterDefinitions []*GoogleCloudChannelV1ParameterDefinition `json:"parameterDefinitions,omitempty"`
	// Plan: Describes the payment plan for the Offer.
	Plan *GoogleCloudChannelV1Plan `json:"plan,omitempty"`
	// PriceByResources: Price for each monetizable resource type.
	PriceByResources []*GoogleCloudChannelV1PriceByResource `json:"priceByResources,omitempty"`
	// Sku: SKU the offer is associated with.
	Sku *GoogleCloudChannelV1Sku `json:"sku,omitempty"`
	// StartTime: Start of the Offer validity time.
	StartTime string `json:"startTime,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// 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 GoogleCloudChannelV1Offer) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Offer
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1OperationMetadata: Provides contextual information about
// a google.longrunning.Operation.
type GoogleCloudChannelV1OperationMetadata struct {
	// OperationType: The RPC that initiated this Long Running Operation.
	//
	// Possible values:
	//   "OPERATION_TYPE_UNSPECIFIED" - Not used.
	//   "CREATE_ENTITLEMENT" - Long Running Operation was triggered by
	// CreateEntitlement.
	//   "CHANGE_RENEWAL_SETTINGS" - Long Running Operation was triggered by
	// ChangeRenewalSettings.
	//   "START_PAID_SERVICE" - Long Running Operation was triggered by
	// StartPaidService.
	//   "ACTIVATE_ENTITLEMENT" - Long Running Operation was triggered by
	// ActivateEntitlement.
	//   "SUSPEND_ENTITLEMENT" - Long Running Operation was triggered by
	// SuspendEntitlement.
	//   "CANCEL_ENTITLEMENT" - Long Running Operation was triggered by
	// CancelEntitlement.
	//   "TRANSFER_ENTITLEMENTS" - Long Running Operation was triggered by
	// TransferEntitlements.
	//   "TRANSFER_ENTITLEMENTS_TO_GOOGLE" - Long Running Operation was triggered
	// by TransferEntitlementsToGoogle.
	//   "CHANGE_OFFER" - Long Running Operation was triggered by ChangeOffer.
	//   "CHANGE_PARAMETERS" - Long Running Operation was triggered by
	// ChangeParameters.
	//   "PROVISION_CLOUD_IDENTITY" - Long Running Operation was triggered by
	// ProvisionCloudIdentity.
	OperationType string `json:"operationType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "OperationType") 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. "OperationType") 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 GoogleCloudChannelV1OperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1OperationMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Parameter: Definition for extended entitlement
// parameters.
type GoogleCloudChannelV1Parameter struct {
	// Editable: Output only. Specifies whether this parameter is allowed to be
	// changed. For example, for a Google Workspace Business Starter entitlement in
	// commitment plan, num_units is editable when entitlement is active.
	Editable bool `json:"editable,omitempty"`
	// Name: Name of the parameter.
	Name string `json:"name,omitempty"`
	// Value: Value of the parameter.
	Value *GoogleCloudChannelV1Value `json:"value,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Editable") 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. "Editable") 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 GoogleCloudChannelV1Parameter) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Parameter
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ParameterDefinition: Parameter's definition. Specifies
// what parameter is required to use the current Offer to purchase.
type GoogleCloudChannelV1ParameterDefinition struct {
	// AllowedValues: If not empty, parameter values must be drawn from this list.
	// For example, [us-west1, us-west2, ...] Applicable to STRING parameter type.
	AllowedValues []*GoogleCloudChannelV1Value `json:"allowedValues,omitempty"`
	// MaxValue: Maximum value of the parameter, if applicable. Inclusive. For
	// example, maximum seats when purchasing Google Workspace Business Standard.
	// Applicable to INT64 and DOUBLE parameter types.
	MaxValue *GoogleCloudChannelV1Value `json:"maxValue,omitempty"`
	// MinValue: Minimal value of the parameter, if applicable. Inclusive. For
	// example, minimal commitment when purchasing Anthos is 0.01. Applicable to
	// INT64 and DOUBLE parameter types.
	MinValue *GoogleCloudChannelV1Value `json:"minValue,omitempty"`
	// Name: Name of the parameter.
	Name string `json:"name,omitempty"`
	// Optional: If set to true, parameter is optional to purchase this Offer.
	Optional bool `json:"optional,omitempty"`
	// ParameterType: Data type of the parameter. Minimal value, Maximum value and
	// allowed values will use specified data type here.
	//
	// Possible values:
	//   "PARAMETER_TYPE_UNSPECIFIED" - Not used.
	//   "INT64" - Int64 type.
	//   "STRING" - String type.
	//   "DOUBLE" - Double type.
	//   "BOOLEAN" - Boolean type.
	ParameterType string `json:"parameterType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AllowedValues") 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. "AllowedValues") 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 GoogleCloudChannelV1ParameterDefinition) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ParameterDefinition
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1PercentageAdjustment: An adjustment that applies a flat
// markup or markdown to an entire bill.
type GoogleCloudChannelV1PercentageAdjustment struct {
	// Percentage: The percentage of the bill to adjust. For example: Mark down by
	// 1% => "-1.00" Mark up by 1% => "1.00" Pass-Through => "0.00"
	Percentage *GoogleTypeDecimal `json:"percentage,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Percentage") 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. "Percentage") 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 GoogleCloudChannelV1PercentageAdjustment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1PercentageAdjustment
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Period: Represents period in days/months/years.
type GoogleCloudChannelV1Period struct {
	// Duration: Total duration of Period Type defined.
	Duration int64 `json:"duration,omitempty"`
	// PeriodType: Period Type.
	//
	// Possible values:
	//   "PERIOD_TYPE_UNSPECIFIED" - Not used.
	//   "DAY" - Day.
	//   "MONTH" - Month.
	//   "YEAR" - Year.
	PeriodType string `json:"periodType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Duration") 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. "Duration") 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 GoogleCloudChannelV1Period) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Period
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Plan: The payment plan for the Offer. Describes how to
// make a payment.
type GoogleCloudChannelV1Plan struct {
	// BillingAccount: Reseller Billing account to charge after an offer
	// transaction. Only present for Google Cloud offers.
	BillingAccount string `json:"billingAccount,omitempty"`
	// PaymentCycle: Describes how frequently the reseller will be billed, such as
	// once per month.
	PaymentCycle *GoogleCloudChannelV1Period `json:"paymentCycle,omitempty"`
	// PaymentPlan: Describes how a reseller will be billed.
	//
	// Possible values:
	//   "PAYMENT_PLAN_UNSPECIFIED" - Not used.
	//   "COMMITMENT" - Commitment.
	//   "FLEXIBLE" - No commitment.
	//   "FREE" - Free.
	//   "TRIAL" - Trial.
	//   "OFFLINE" - Price and ordering not available through API.
	PaymentPlan string `json:"paymentPlan,omitempty"`
	// PaymentType: Specifies when the payment needs to happen.
	//
	// Possible values:
	//   "PAYMENT_TYPE_UNSPECIFIED" - Not used.
	//   "PREPAY" - Prepay. Amount has to be paid before service is rendered.
	//   "POSTPAY" - Postpay. Reseller is charged at the end of the Payment cycle.
	PaymentType string `json:"paymentType,omitempty"`
	// TrialPeriod: Present for Offers with a trial period. For trial-only Offers,
	// a paid service needs to start before the trial period ends for continued
	// service. For Regular Offers with a trial period, the regular pricing goes
	// into effect when trial period ends, or if paid service is started before the
	// end of the trial period.
	TrialPeriod *GoogleCloudChannelV1Period `json:"trialPeriod,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BillingAccount") 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. "BillingAccount") 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 GoogleCloudChannelV1Plan) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Plan
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Price: Represents the price of the Offer.
type GoogleCloudChannelV1Price struct {
	// BasePrice: Base price.
	BasePrice *GoogleTypeMoney `json:"basePrice,omitempty"`
	// Discount: Discount percentage, represented as decimal. For example, a 20%
	// discount will be represent as 0.2.
	Discount float64 `json:"discount,omitempty"`
	// DiscountComponents: Breakdown of the discount into its components. This will
	// be empty if there is no discount present.
	DiscountComponents []*GoogleCloudChannelV1DiscountComponent `json:"discountComponents,omitempty"`
	// EffectivePrice: Effective Price after applying the discounts.
	EffectivePrice *GoogleTypeMoney `json:"effectivePrice,omitempty"`
	// ExternalPriceUri: Link to external price list, such as link to Google Voice
	// rate card.
	ExternalPriceUri string `json:"externalPriceUri,omitempty"`
	// PricePeriod: The time period with respect to which base and effective prices
	// are defined. Example: 1 month, 6 months, 1 year, etc.
	PricePeriod *GoogleCloudChannelV1Period `json:"pricePeriod,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BasePrice") 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. "BasePrice") 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 GoogleCloudChannelV1Price) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Price
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

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

// GoogleCloudChannelV1PriceByResource: Represents price by resource type.
type GoogleCloudChannelV1PriceByResource struct {
	// Price: Price of the Offer. Present if there are no price phases.
	Price *GoogleCloudChannelV1Price `json:"price,omitempty"`
	// PricePhases: Specifies the price by time range.
	PricePhases []*GoogleCloudChannelV1PricePhase `json:"pricePhases,omitempty"`
	// ResourceType: Resource Type. Example: SEAT
	//
	// Possible values:
	//   "RESOURCE_TYPE_UNSPECIFIED" - Not used.
	//   "SEAT" - Seat.
	//   "MAU" - Monthly active user.
	//   "GB" - GB (used for storage SKUs).
	//   "LICENSED_USER" - Active licensed users(for Voice SKUs).
	//   "MINUTES" - Voice usage.
	//   "IAAS_USAGE" - For IaaS SKUs like Google Cloud, monetization is based on
	// usage accrued on your billing account irrespective of the type of
	// monetizable resource. This enum represents an aggregated resource/container
	// for all usage SKUs on a billing account. Currently, only applicable to
	// Google Cloud.
	//   "SUBSCRIPTION" - For Google Cloud subscriptions like Anthos or SAP.
	//   "AI_CREDITS" - As of June 2026, this field is mapped to WS Credits on
	// commerce side.
	ResourceType string `json:"resourceType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Price") 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. "Price") 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 GoogleCloudChannelV1PriceByResource) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1PriceByResource
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1PricePhase: Specifies the price by the duration of
// months. For example, a 20% discount for the first six months, then a 10%
// discount starting on the seventh month.
type GoogleCloudChannelV1PricePhase struct {
	// FirstPeriod: Defines first period for the phase.
	FirstPeriod int64 `json:"firstPeriod,omitempty"`
	// LastPeriod: Defines first period for the phase.
	LastPeriod int64 `json:"lastPeriod,omitempty"`
	// PeriodType: Defines the phase period type.
	//
	// Possible values:
	//   "PERIOD_TYPE_UNSPECIFIED" - Not used.
	//   "DAY" - Day.
	//   "MONTH" - Month.
	//   "YEAR" - Year.
	PeriodType string `json:"periodType,omitempty"`
	// Price: Price of the phase. Present if there are no price tiers.
	Price *GoogleCloudChannelV1Price `json:"price,omitempty"`
	// PriceTiers: Price by the resource tiers.
	PriceTiers []*GoogleCloudChannelV1PriceTier `json:"priceTiers,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FirstPeriod") 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. "FirstPeriod") 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 GoogleCloudChannelV1PricePhase) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1PricePhase
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1PriceTier: Defines price at resource tier level. For
// example, an offer with following definition : * Tier 1: Provide 25% discount
// for all seats between 1 and 25. * Tier 2: Provide 10% discount for all seats
// between 26 and 100. * Tier 3: Provide flat 15% discount for all seats above
// 100. Each of these tiers is represented as a PriceTier.
type GoogleCloudChannelV1PriceTier struct {
	// FirstResource: First resource for which the tier price applies.
	FirstResource int64 `json:"firstResource,omitempty"`
	// LastResource: Last resource for which the tier price applies.
	LastResource int64 `json:"lastResource,omitempty"`
	// Price: Price of the tier.
	Price *GoogleCloudChannelV1Price `json:"price,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FirstResource") 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. "FirstResource") 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 GoogleCloudChannelV1PriceTier) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1PriceTier
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Product: A Product is the entity a customer uses when
// placing an order. For example, Google Workspace, Google Voice, etc.
type GoogleCloudChannelV1Product struct {
	// MarketingInfo: Marketing information for the product.
	MarketingInfo *GoogleCloudChannelV1MarketingInfo `json:"marketingInfo,omitempty"`
	// Name: Resource Name of the Product. Format: products/{product_id}
	Name string `json:"name,omitempty"`
	// ForceSendFields is a list of field names (e.g. "MarketingInfo") 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. "MarketingInfo") 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 GoogleCloudChannelV1Product) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Product
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ProvisionCloudIdentityRequest: Request message for
// CloudChannelService.ProvisionCloudIdentity
type GoogleCloudChannelV1ProvisionCloudIdentityRequest struct {
	// CloudIdentityInfo: CloudIdentity-specific customer information.
	CloudIdentityInfo *GoogleCloudChannelV1CloudIdentityInfo `json:"cloudIdentityInfo,omitempty"`
	// User: Admin user information.
	User *GoogleCloudChannelV1AdminUser `json:"user,omitempty"`
	// ValidateOnly: Validate the request and preview the review, but do not post
	// it.
	ValidateOnly bool `json:"validateOnly,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CloudIdentityInfo") 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. "CloudIdentityInfo") 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 GoogleCloudChannelV1ProvisionCloudIdentityRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ProvisionCloudIdentityRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ProvisionedService: Service provisioned for an
// entitlement.
type GoogleCloudChannelV1ProvisionedService struct {
	// ProductId: Output only. The product pertaining to the provisioning resource
	// as specified in the Offer.
	ProductId string `json:"productId,omitempty"`
	// ProvisioningId: Output only. Provisioning ID of the entitlement. For Google
	// Workspace, this is the underlying Subscription ID. For Google Cloud, this is
	// the Billing Account ID of the billing subaccount.
	ProvisioningId string `json:"provisioningId,omitempty"`
	// SkuId: Output only. The SKU pertaining to the provisioning resource as
	// specified in the Offer.
	SkuId string `json:"skuId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ProductId") 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. "ProductId") 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 GoogleCloudChannelV1ProvisionedService) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ProvisionedService
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1PurchasableOffer: Offer that you can purchase for a
// customer. This is used in the ListPurchasableOffer API response.
type GoogleCloudChannelV1PurchasableOffer struct {
	// Offer: Offer.
	Offer *GoogleCloudChannelV1Offer `json:"offer,omitempty"`
	// PriceReferenceId: Optional. Price reference ID for the offer. Only for
	// offers that require additional price information. Used to guarantee that the
	// pricing is consistent between quoting the offer and placing the order.
	PriceReferenceId string `json:"priceReferenceId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Offer") 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. "Offer") 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 GoogleCloudChannelV1PurchasableOffer) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1PurchasableOffer
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1PurchasableSku: SKU that you can purchase. This is used
// in ListPurchasableSku API response.
type GoogleCloudChannelV1PurchasableSku struct {
	// Sku: SKU
	Sku *GoogleCloudChannelV1Sku `json:"sku,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Sku") 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. "Sku") 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 GoogleCloudChannelV1PurchasableSku) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1PurchasableSku
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1QueryEligibleBillingAccountsResponse: Response message
// for QueryEligibleBillingAccounts.
type GoogleCloudChannelV1QueryEligibleBillingAccountsResponse struct {
	// SkuPurchaseGroups: List of SKU purchase groups where each group represents a
	// set of SKUs that must be purchased using the same billing account. Each SKU
	// from [QueryEligibleBillingAccountsRequest.skus] will appear in exactly one
	// SKU group.
	SkuPurchaseGroups []*GoogleCloudChannelV1SkuPurchaseGroup `json:"skuPurchaseGroups,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "SkuPurchaseGroups") 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. "SkuPurchaseGroups") 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 GoogleCloudChannelV1QueryEligibleBillingAccountsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1QueryEligibleBillingAccountsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RegisterSubscriberRequest: Request Message for
// RegisterSubscriber.
type GoogleCloudChannelV1RegisterSubscriberRequest struct {
	// Account: Optional. Resource name of the account. Required if integrator is
	// not provided. Otherwise, leave this field empty/unset.
	Account string `json:"account,omitempty"`
	// Integrator: Optional. Resource name of the integrator. Required if account
	// is not provided. Otherwise, leave this field empty/unset.
	Integrator string `json:"integrator,omitempty"`
	// ServiceAccount: Required. Service account that provides subscriber access to
	// the registered topic.
	ServiceAccount string `json:"serviceAccount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Account") 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. "Account") 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 GoogleCloudChannelV1RegisterSubscriberRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RegisterSubscriberRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RegisterSubscriberResponse: Response Message for
// RegisterSubscriber.
type GoogleCloudChannelV1RegisterSubscriberResponse struct {
	// Topic: Name of the topic the subscriber will listen to.
	Topic string `json:"topic,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Topic") 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. "Topic") 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 GoogleCloudChannelV1RegisterSubscriberResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RegisterSubscriberResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RenewalSettings: Renewal settings for renewable Offers.
type GoogleCloudChannelV1RenewalSettings struct {
	// EnableRenewal: If false, the plan will be completed at the end date.
	EnableRenewal bool `json:"enableRenewal,omitempty"`
	// PaymentCycle: Describes how frequently the reseller will be billed, such as
	// once per month.
	PaymentCycle *GoogleCloudChannelV1Period `json:"paymentCycle,omitempty"`
	// PaymentPlan: Describes how a reseller will be billed.
	//
	// Possible values:
	//   "PAYMENT_PLAN_UNSPECIFIED" - Not used.
	//   "COMMITMENT" - Commitment.
	//   "FLEXIBLE" - No commitment.
	//   "FREE" - Free.
	//   "TRIAL" - Trial.
	//   "OFFLINE" - Price and ordering not available through API.
	PaymentPlan string `json:"paymentPlan,omitempty"`
	// ResizeUnitCount: If true and enable_renewal = true, the unit (for example
	// seats or licenses) will be set to the number of active units at renewal
	// time.
	ResizeUnitCount bool `json:"resizeUnitCount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EnableRenewal") 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. "EnableRenewal") 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 GoogleCloudChannelV1RenewalSettings) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RenewalSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Report: The ID and description of a report that was used
// to generate report data. For example, "Google Cloud Daily Spend", "Google
// Workspace License Activity", etc.
type GoogleCloudChannelV1Report struct {
	// Columns: The list of columns included in the report. This defines the schema
	// of the report results.
	Columns []*GoogleCloudChannelV1Column `json:"columns,omitempty"`
	// Description: A description of other aspects of the report, such as the
	// products it supports.
	Description string `json:"description,omitempty"`
	// DisplayName: A human-readable name for this report.
	DisplayName string `json:"displayName,omitempty"`
	// Name: Required. The report's resource name. Specifies the account and report
	// used to generate report data. The report_id identifier is a UID (for
	// example, `613bf59q`). Name uses the format:
	// accounts/{account_id}/reports/{report_id}
	Name string `json:"name,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 GoogleCloudChannelV1Report) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Report
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ReportJob: The result of a RunReportJob operation.
// Contains the name to use in FetchReportResultsRequest.report_job and the
// status of the operation.
type GoogleCloudChannelV1ReportJob struct {
	// Name: Required. The resource name of a report job. Name uses the format:
	// `accounts/{account_id}/reportJobs/{report_job_id}`
	Name string `json:"name,omitempty"`
	// ReportStatus: The current status of report generation.
	ReportStatus *GoogleCloudChannelV1ReportStatus `json:"reportStatus,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 GoogleCloudChannelV1ReportJob) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ReportJob
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ReportResultsMetadata: The features describing the data.
// Returned by CloudChannelReportsService.RunReportJob and
// CloudChannelReportsService.FetchReportResults.
type GoogleCloudChannelV1ReportResultsMetadata struct {
	// DateRange: The date range of reported usage.
	DateRange *GoogleCloudChannelV1DateRange `json:"dateRange,omitempty"`
	// PrecedingDateRange: The usage dates immediately preceding `date_range` with
	// the same duration. Use this to calculate trending usage and costs. This is
	// only populated if you request trending data. For example, if `date_range` is
	// July 1-15, `preceding_date_range` will be June 16-30.
	PrecedingDateRange *GoogleCloudChannelV1DateRange `json:"precedingDateRange,omitempty"`
	// Report: Details of the completed report.
	Report *GoogleCloudChannelV1Report `json:"report,omitempty"`
	// RowCount: The total number of rows of data in the final report.
	RowCount int64 `json:"rowCount,omitempty,string"`
	// ForceSendFields is a list of field names (e.g. "DateRange") 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. "DateRange") 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 GoogleCloudChannelV1ReportResultsMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ReportResultsMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ReportStatus: Status of a report generation process.
type GoogleCloudChannelV1ReportStatus struct {
	// EndTime: The report generation's completion time.
	EndTime string `json:"endTime,omitempty"`
	// StartTime: The report generation's start time.
	StartTime string `json:"startTime,omitempty"`
	// State: The current state of the report generation process.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Not used.
	//   "STARTED" - Report processing started.
	//   "WRITING" - Data generated from the report is being staged.
	//   "AVAILABLE" - Report data is available for access.
	//   "FAILED" - Report failed.
	State string `json:"state,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. 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. "EndTime") 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 GoogleCloudChannelV1ReportStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ReportStatus
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1ReportValue: A single report value.
type GoogleCloudChannelV1ReportValue struct {
	// DateTimeValue: A value of type `google.type.DateTime` (year, month, day,
	// hour, minute, second, and UTC offset or timezone.)
	DateTimeValue *GoogleTypeDateTime `json:"dateTimeValue,omitempty"`
	// DateValue: A value of type `google.type.Date` (year, month, day).
	DateValue *GoogleTypeDate `json:"dateValue,omitempty"`
	// DecimalValue: A value of type `google.type.Decimal`, representing
	// non-integer numeric values.
	DecimalValue *GoogleTypeDecimal `json:"decimalValue,omitempty"`
	// IntValue: A value of type `int`.
	IntValue int64 `json:"intValue,omitempty,string"`
	// MoneyValue: A value of type `google.type.Money` (currency code, whole units,
	// decimal units).
	MoneyValue *GoogleTypeMoney `json:"moneyValue,omitempty"`
	// StringValue: A value of type `string`.
	StringValue string `json:"stringValue,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DateTimeValue") 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. "DateTimeValue") 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 GoogleCloudChannelV1ReportValue) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1ReportValue
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RepricingAdjustment: A type that represents the various
// adjustments you can apply to a bill.
type GoogleCloudChannelV1RepricingAdjustment struct {
	// PercentageAdjustment: Flat markup or markdown on an entire bill.
	PercentageAdjustment *GoogleCloudChannelV1PercentageAdjustment `json:"percentageAdjustment,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PercentageAdjustment") 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. "PercentageAdjustment") 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 GoogleCloudChannelV1RepricingAdjustment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RepricingAdjustment
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RepricingCondition: Represents the various repricing
// conditions you can use for a conditional override.
type GoogleCloudChannelV1RepricingCondition struct {
	// SkuGroupCondition: SKU Group condition for override.
	SkuGroupCondition *GoogleCloudChannelV1SkuGroupCondition `json:"skuGroupCondition,omitempty"`
	// ForceSendFields is a list of field names (e.g. "SkuGroupCondition") 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. "SkuGroupCondition") 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 GoogleCloudChannelV1RepricingCondition) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RepricingCondition
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RepricingConfig: Configuration for repricing a Google
// bill over a period of time.
type GoogleCloudChannelV1RepricingConfig struct {
	// Adjustment: Required. Information about the adjustment.
	Adjustment *GoogleCloudChannelV1RepricingAdjustment `json:"adjustment,omitempty"`
	// ChannelPartnerGranularity: Applies the repricing configuration at the
	// channel partner level. Only ChannelPartnerRepricingConfig supports this
	// value. Deprecated: This is no longer supported. Use
	// RepricingConfig.entitlement_granularity instead.
	ChannelPartnerGranularity *GoogleCloudChannelV1RepricingConfigChannelPartnerGranularity `json:"channelPartnerGranularity,omitempty"`
	// ConditionalOverrides: The conditional overrides to apply for this
	// configuration. If you list multiple overrides, only the first valid override
	// is used. If you don't list any overrides, the API uses the normal adjustment
	// and rebilling basis.
	ConditionalOverrides []*GoogleCloudChannelV1ConditionalOverride `json:"conditionalOverrides,omitempty"`
	// EffectiveInvoiceMonth: Required. The YearMonth when these adjustments
	// activate. The Day field needs to be "0" since we only accept YearMonth
	// repricing boundaries.
	EffectiveInvoiceMonth *GoogleTypeDate `json:"effectiveInvoiceMonth,omitempty"`
	// EntitlementGranularity: Required. Applies the repricing configuration at the
	// entitlement level. Note: If a ChannelPartnerRepricingConfig using
	// RepricingConfig.EntitlementGranularity becomes effective, then no existing
	// or future RepricingConfig.ChannelPartnerGranularity will apply to the
	// RepricingConfig.EntitlementGranularity.entitlement. This is the recommended
	// value for both CustomerRepricingConfig and ChannelPartnerRepricingConfig.
	EntitlementGranularity *GoogleCloudChannelV1RepricingConfigEntitlementGranularity `json:"entitlementGranularity,omitempty"`
	// RebillingBasis: Required. The RebillingBasis to use for this bill. Specifies
	// the relative cost based on repricing costs you will apply.
	//
	// Possible values:
	//   "REBILLING_BASIS_UNSPECIFIED" - Not used.
	//   "COST_AT_LIST" - Use the list cost, also known as the MSRP.
	//   "DIRECT_CUSTOMER_COST" - Pass through all discounts except the Reseller
	// Program Discount. If this is the default cost base and no adjustments are
	// specified, the output cost will be exactly what the customer would see if
	// they viewed the bill in the Google Cloud Console.
	RebillingBasis string `json:"rebillingBasis,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Adjustment") 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. "Adjustment") 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 GoogleCloudChannelV1RepricingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RepricingConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RepricingConfigChannelPartnerGranularity: Applies the
// repricing configuration at the channel partner level. The channel partner
// value is derived from the resource name. Takes an empty json object.
// Deprecated: This is no longer supported. Use
// RepricingConfig.EntitlementGranularity instead.
type GoogleCloudChannelV1RepricingConfigChannelPartnerGranularity struct {
}

// GoogleCloudChannelV1RepricingConfigEntitlementGranularity: Applies the
// repricing configuration at the entitlement level.
type GoogleCloudChannelV1RepricingConfigEntitlementGranularity struct {
	// Entitlement: Resource name of the entitlement. Format:
	// accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}
	Entitlement string `json:"entitlement,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Entitlement") 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. "Entitlement") 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 GoogleCloudChannelV1RepricingConfigEntitlementGranularity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RepricingConfigEntitlementGranularity
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Row: A row of report values.
type GoogleCloudChannelV1Row struct {
	// PartitionKey: The key for the partition this row belongs to. This field is
	// empty if the report is not partitioned.
	PartitionKey string `json:"partitionKey,omitempty"`
	// Values: The list of values in the row.
	Values []*GoogleCloudChannelV1ReportValue `json:"values,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PartitionKey") 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. "PartitionKey") 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 GoogleCloudChannelV1Row) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Row
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RunReportJobRequest: Request message for
// CloudChannelReportsService.RunReportJob.
type GoogleCloudChannelV1RunReportJobRequest struct {
	// DateRange: Optional. The range of usage or invoice dates to include in the
	// result.
	DateRange *GoogleCloudChannelV1DateRange `json:"dateRange,omitempty"`
	// Filter: Optional. A structured string that defines conditions on dimension
	// columns to restrict the report output. Filters support logical operators
	// (AND, OR, NOT) and conditional operators (=, !=, <, >, <=, and >=) using
	// `column_id` as keys. For example:
	// `(customer:"accounts/C123abc/customers/S456def" OR
	// customer:"accounts/C123abc/customers/S789ghi") AND invoice_start_date.year
	// >= 2022`
	Filter string `json:"filter,omitempty"`
	// LanguageCode: Optional. The BCP-47 language code, such as "en-US". If
	// specified, the response is localized to the corresponding language code if
	// the original data sources support it. Default is "en-US".
	LanguageCode string `json:"languageCode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DateRange") 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. "DateRange") 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 GoogleCloudChannelV1RunReportJobRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RunReportJobRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1RunReportJobResponse: Response message for
// CloudChannelReportsService.RunReportJob.
type GoogleCloudChannelV1RunReportJobResponse struct {
	// ReportJob: Pass `report_job.name` to FetchReportResultsRequest.report_job to
	// retrieve the report's results.
	ReportJob *GoogleCloudChannelV1ReportJob `json:"reportJob,omitempty"`
	// ReportMetadata: The metadata for the report's results (display name,
	// columns, row count, and date range). If you view this before the operation
	// finishes, you may see incomplete data.
	ReportMetadata *GoogleCloudChannelV1ReportResultsMetadata `json:"reportMetadata,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ReportJob") 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. "ReportJob") 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 GoogleCloudChannelV1RunReportJobResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1RunReportJobResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Sku: Represents a product's purchasable Stock Keeping
// Unit (SKU). SKUs represent the different variations of the product. For
// example, Google Workspace Business Standard and Google Workspace Business
// Plus are Google Workspace product SKUs.
type GoogleCloudChannelV1Sku struct {
	// MarketingInfo: Marketing information for the SKU.
	MarketingInfo *GoogleCloudChannelV1MarketingInfo `json:"marketingInfo,omitempty"`
	// Name: Resource Name of the SKU. Format: products/{product_id}/skus/{sku_id}
	Name string `json:"name,omitempty"`
	// Product: Product the SKU is associated with.
	Product *GoogleCloudChannelV1Product `json:"product,omitempty"`
	// ForceSendFields is a list of field names (e.g. "MarketingInfo") 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. "MarketingInfo") 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 GoogleCloudChannelV1Sku) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Sku
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1SkuGroup: Represents the SKU group information.
type GoogleCloudChannelV1SkuGroup struct {
	// DisplayName: Unique human readable identifier for the SKU group.
	DisplayName string `json:"displayName,omitempty"`
	// Name: Resource name of SKU group. Format:
	// accounts/{account}/skuGroups/{sku_group}. Example:
	// "accounts/C01234/skuGroups/3d50fd57-3157-4577-a5a9-a219b8490041".
	Name string `json:"name,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with empty 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 GoogleCloudChannelV1SkuGroup) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1SkuGroup
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1SkuGroupCondition: A condition that applies the override
// if a line item SKU is found in the SKU group.
type GoogleCloudChannelV1SkuGroupCondition struct {
	// SkuGroup: Specifies a SKU group (https://cloud.google.com/skus/sku-groups).
	// Resource name of SKU group. Format:
	// accounts/{account}/skuGroups/{sku_group}. Example:
	// "accounts/C01234/skuGroups/3d50fd57-3157-4577-a5a9-a219b8490041".
	SkuGroup string `json:"skuGroup,omitempty"`
	// ForceSendFields is a list of field names (e.g. "SkuGroup") 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. "SkuGroup") 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 GoogleCloudChannelV1SkuGroupCondition) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1SkuGroupCondition
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1SkuPurchaseGroup: Represents a set of SKUs that must be
// purchased using the same billing account.
type GoogleCloudChannelV1SkuPurchaseGroup struct {
	// BillingAccountPurchaseInfos: List of billing accounts that are eligible to
	// purhcase these SKUs.
	BillingAccountPurchaseInfos []*GoogleCloudChannelV1BillingAccountPurchaseInfo `json:"billingAccountPurchaseInfos,omitempty"`
	// Skus: Resource names of the SKUs included in this group. Format:
	// products/{product_id}/skus/{sku_id}.
	Skus []string `json:"skus,omitempty"`
	// ForceSendFields is a list of field names (e.g.
	// "BillingAccountPurchaseInfos") 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. "BillingAccountPurchaseInfos") 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 GoogleCloudChannelV1SkuPurchaseGroup) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1SkuPurchaseGroup
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1StartPaidServiceRequest: Request message for
// CloudChannelService.StartPaidService.
type GoogleCloudChannelV1StartPaidServiceRequest struct {
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,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 GoogleCloudChannelV1StartPaidServiceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1StartPaidServiceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1SubscriberEvent: Represents information which resellers
// will get as part of notification from Pub/Sub.
type GoogleCloudChannelV1SubscriberEvent struct {
	// CustomerEvent: Customer event sent as part of Pub/Sub event to partners.
	CustomerEvent *GoogleCloudChannelV1CustomerEvent `json:"customerEvent,omitempty"`
	// EntitlementEvent: Entitlement event sent as part of Pub/Sub event to
	// partners.
	EntitlementEvent *GoogleCloudChannelV1EntitlementEvent `json:"entitlementEvent,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CustomerEvent") 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. "CustomerEvent") 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 GoogleCloudChannelV1SubscriberEvent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1SubscriberEvent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1SuspendEntitlementRequest: Request message for
// CloudChannelService.SuspendEntitlement.
type GoogleCloudChannelV1SuspendEntitlementRequest struct {
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,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 GoogleCloudChannelV1SuspendEntitlementRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1SuspendEntitlementRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1TransferEligibility: Specifies transfer eligibility of a
// SKU.
type GoogleCloudChannelV1TransferEligibility struct {
	// Description: Localized description if reseller is not eligible to transfer
	// the SKU.
	Description string `json:"description,omitempty"`
	// IneligibilityReason: Specified the reason for ineligibility.
	//
	// Possible values:
	//   "REASON_UNSPECIFIED" - Not used.
	//   "PENDING_TOS_ACCEPTANCE" - Reseller needs to accept TOS before
	// transferring the SKU.
	//   "SKU_NOT_ELIGIBLE" - Reseller not eligible to sell the SKU.
	//   "SKU_SUSPENDED" - SKU subscription is suspended
	//   "CHANNEL_PARTNER_NOT_AUTHORIZED_FOR_SKU" - The reseller is not authorized
	// to transact on this Product. See
	// https://support.google.com/channelservices/answer/9759265
	IneligibilityReason string `json:"ineligibilityReason,omitempty"`
	// IsEligible: Whether reseller is eligible to transfer the SKU.
	IsEligible bool `json:"isEligible,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 GoogleCloudChannelV1TransferEligibility) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1TransferEligibility
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1TransferEntitlementsRequest: Request message for
// CloudChannelService.TransferEntitlements.
type GoogleCloudChannelV1TransferEntitlementsRequest struct {
	// AuthToken: The super admin of the resold customer generates this token to
	// authorize a reseller to access their Cloud Identity and purchase
	// entitlements on their behalf. You can omit this token after authorization.
	// See https://support.google.com/a/answer/7643790 for more details.
	AuthToken string `json:"authToken,omitempty"`
	// Entitlements: Required. The new entitlements to create or transfer.
	Entitlements []*GoogleCloudChannelV1Entitlement `json:"entitlements,omitempty"`
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AuthToken") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. 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. "AuthToken") 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 GoogleCloudChannelV1TransferEntitlementsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1TransferEntitlementsRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1TransferEntitlementsResponse: Response message for
// CloudChannelService.TransferEntitlements. This is put in the response field
// of google.longrunning.Operation.
type GoogleCloudChannelV1TransferEntitlementsResponse struct {
	// Entitlements: The transferred entitlements.
	Entitlements []*GoogleCloudChannelV1Entitlement `json:"entitlements,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Entitlements") 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. "Entitlements") 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 GoogleCloudChannelV1TransferEntitlementsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1TransferEntitlementsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1TransferEntitlementsToGoogleRequest: Request message for
// CloudChannelService.TransferEntitlementsToGoogle.
type GoogleCloudChannelV1TransferEntitlementsToGoogleRequest struct {
	// Entitlements: Required. The entitlements to transfer to Google.
	Entitlements []*GoogleCloudChannelV1Entitlement `json:"entitlements,omitempty"`
	// RequestId: Optional. You can specify an optional unique request ID, and if
	// you need to retry your request, the server will know to ignore the request
	// if it's complete. For example, you make an initial request and the request
	// times out. If you make the request again with the same request ID, the
	// server can check if it received the original operation with the same request
	// ID. If it did, it will ignore the second request. The request ID must be a
	// valid UUID (https://tools.ietf.org/html/rfc4122) with the exception that
	// zero UUID is not supported (`00000000-0000-0000-0000-000000000000`).
	RequestId string `json:"requestId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Entitlements") 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. "Entitlements") 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 GoogleCloudChannelV1TransferEntitlementsToGoogleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1TransferEntitlementsToGoogleRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1TransferableOffer: TransferableOffer represents an Offer
// that can be used in Transfer. Read-only.
type GoogleCloudChannelV1TransferableOffer struct {
	// Offer: Offer with parameter constraints updated to allow the Transfer.
	Offer *GoogleCloudChannelV1Offer `json:"offer,omitempty"`
	// PriceReferenceId: Optional. Price reference ID for the offer. Only for
	// offers that require additional price information. Used to guarantee that the
	// pricing is consistent between quoting the offer and placing the order.
	PriceReferenceId string `json:"priceReferenceId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Offer") 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. "Offer") 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 GoogleCloudChannelV1TransferableOffer) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1TransferableOffer
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1TransferableSku: TransferableSku represents information
// a reseller needs to view existing provisioned services for a customer that
// they do not own. Read-only.
type GoogleCloudChannelV1TransferableSku struct {
	// LegacySku: Optional. The customer to transfer has an entitlement with the
	// populated legacy SKU.
	LegacySku *GoogleCloudChannelV1Sku `json:"legacySku,omitempty"`
	// Sku: The SKU pertaining to the provisioning resource as specified in the
	// Offer.
	Sku *GoogleCloudChannelV1Sku `json:"sku,omitempty"`
	// TransferEligibility: Describes the transfer eligibility of a SKU.
	TransferEligibility *GoogleCloudChannelV1TransferEligibility `json:"transferEligibility,omitempty"`
	// ForceSendFields is a list of field names (e.g. "LegacySku") 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. "LegacySku") 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 GoogleCloudChannelV1TransferableSku) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1TransferableSku
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1TrialSettings: Settings for trial offers.
type GoogleCloudChannelV1TrialSettings struct {
	// EndTime: Date when the trial ends. The value is in milliseconds using the
	// UNIX Epoch format. See an example Epoch converter
	// (https://www.epochconverter.com).
	EndTime string `json:"endTime,omitempty"`
	// Trial: Determines if the entitlement is in a trial or not: * `true` - The
	// entitlement is in trial. * `false` - The entitlement is not in trial.
	Trial bool `json:"trial,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. 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. "EndTime") 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 GoogleCloudChannelV1TrialSettings) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1TrialSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1UnregisterSubscriberRequest: Request Message for
// UnregisterSubscriber.
type GoogleCloudChannelV1UnregisterSubscriberRequest struct {
	// Account: Optional. Resource name of the account. Required if integrator is
	// not provided. Otherwise, leave this field empty/unset.
	Account string `json:"account,omitempty"`
	// Integrator: Optional. Resource name of the integrator. Required if account
	// is not provided. Otherwise, leave this field empty/unset.
	Integrator string `json:"integrator,omitempty"`
	// ServiceAccount: Required. Service account to unregister from subscriber
	// access to the topic.
	ServiceAccount string `json:"serviceAccount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Account") 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. "Account") 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 GoogleCloudChannelV1UnregisterSubscriberRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1UnregisterSubscriberRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1UnregisterSubscriberResponse: Response Message for
// UnregisterSubscriber.
type GoogleCloudChannelV1UnregisterSubscriberResponse struct {
	// Topic: Name of the topic the service account subscriber access was removed
	// from.
	Topic string `json:"topic,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Topic") 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. "Topic") 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 GoogleCloudChannelV1UnregisterSubscriberResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1UnregisterSubscriberResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1UpdateChannelPartnerLinkRequest: Request message for
// CloudChannelService.UpdateChannelPartnerLink
type GoogleCloudChannelV1UpdateChannelPartnerLinkRequest struct {
	// ChannelPartnerLink: Required. The channel partner link to update. Only
	// channel_partner_link.link_state is allowed for updates.
	ChannelPartnerLink *GoogleCloudChannelV1ChannelPartnerLink `json:"channelPartnerLink,omitempty"`
	// UpdateMask: Required. The update mask that applies to the resource. The only
	// allowable value for an update mask is channel_partner_link.link_state.
	UpdateMask string `json:"updateMask,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ChannelPartnerLink") 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. "ChannelPartnerLink") 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 GoogleCloudChannelV1UpdateChannelPartnerLinkRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1UpdateChannelPartnerLinkRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1Value: Data type and value of a parameter.
type GoogleCloudChannelV1Value struct {
	// BoolValue: Represents a boolean value.
	BoolValue bool `json:"boolValue,omitempty"`
	// DoubleValue: Represents a double value.
	DoubleValue float64 `json:"doubleValue,omitempty"`
	// Int64Value: Represents an int64 value.
	Int64Value int64 `json:"int64Value,omitempty,string"`
	// ProtoValue: Represents an 'Any' proto value.
	ProtoValue googleapi.RawMessage `json:"protoValue,omitempty"`
	// StringValue: Represents a string value.
	StringValue string `json:"stringValue,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BoolValue") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. 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. "BoolValue") 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 GoogleCloudChannelV1Value) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1Value
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

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

// GoogleCloudChannelV1alpha1AssociationInfo: Association links that an
// entitlement has to other entitlements.
type GoogleCloudChannelV1alpha1AssociationInfo struct {
	// BaseEntitlement: The name of the base entitlement, for which this
	// entitlement is an add-on.
	BaseEntitlement string `json:"baseEntitlement,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BaseEntitlement") 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. "BaseEntitlement") 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 GoogleCloudChannelV1alpha1AssociationInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1AssociationInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1ChannelPartnerEvent: Represents Pub/Sub messages
// about updates to a Channel Partner. You can retrieve updated values through
// the ChannelPartnerLinks API.
type GoogleCloudChannelV1alpha1ChannelPartnerEvent struct {
	// ChannelPartner: Resource name for the Channel Partner Link. Channel_partner
	// uses the format:
	// accounts/{account_id}/channelPartnerLinks/{channel_partner_id}
	ChannelPartner string `json:"channelPartner,omitempty"`
	// EventType: Type of event which happened for the channel partner.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Default value. Does not display if there are no
	// errors.
	//   "LINK_STATE_CHANGED" - The Channel Partner link state changed.
	//   "PARTNER_ADVANTAGE_INFO_CHANGED" - The Channel Partner's Partner Advantage
	// information changed. This can entail the Channel Partner's authorization to
	// sell a product in a particular region.
	EventType string `json:"eventType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ChannelPartner") 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. "ChannelPartner") 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 GoogleCloudChannelV1alpha1ChannelPartnerEvent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1ChannelPartnerEvent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1Column: The definition of a report column.
// Specifies the data properties in the corresponding position of the report
// rows.
type GoogleCloudChannelV1alpha1Column struct {
	// ColumnId: The unique name of the column (for example, customer_domain,
	// channel_partner, customer_cost). You can use column IDs in
	// RunReportJobRequest.filter. To see all reports and their columns, call
	// CloudChannelReportsService.ListReports.
	ColumnId string `json:"columnId,omitempty"`
	// DataType: The type of the values for this column.
	//
	// Possible values:
	//   "DATA_TYPE_UNSPECIFIED" - Not used.
	//   "STRING" - ReportValues for this column will use string_value.
	//   "INT" - ReportValues for this column will use int_value.
	//   "DECIMAL" - ReportValues for this column will use decimal_value.
	//   "MONEY" - ReportValues for this column will use money_value.
	//   "DATE" - ReportValues for this column will use date_value.
	//   "DATE_TIME" - ReportValues for this column will use date_time_value.
	DataType string `json:"dataType,omitempty"`
	// DisplayName: The column's display name.
	DisplayName string `json:"displayName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ColumnId") 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. "ColumnId") 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 GoogleCloudChannelV1alpha1Column) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1Column
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1CommitmentSettings: Commitment settings for
// commitment-based offers.
type GoogleCloudChannelV1alpha1CommitmentSettings struct {
	// EndTime: Output only. Commitment end timestamp.
	EndTime string `json:"endTime,omitempty"`
	// RenewalSettings: Optional. Renewal settings applicable for a
	// commitment-based Offer.
	RenewalSettings *GoogleCloudChannelV1alpha1RenewalSettings `json:"renewalSettings,omitempty"`
	// StartTime: Output only. Commitment start timestamp.
	StartTime string `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. 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. "EndTime") 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 GoogleCloudChannelV1alpha1CommitmentSettings) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1CommitmentSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1CustomerEvent: Represents Pub/Sub message content
// describing customer update.
type GoogleCloudChannelV1alpha1CustomerEvent struct {
	// Customer: Resource name of the customer. Format:
	// accounts/{account_id}/customers/{customer_id}
	Customer string `json:"customer,omitempty"`
	// EventType: Type of event which happened for the customer.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Not used.
	//   "PRIMARY_DOMAIN_CHANGED" - Primary domain for customer was changed.
	//   "PRIMARY_DOMAIN_VERIFIED" - Primary domain of the customer has been
	// verified.
	EventType string `json:"eventType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Customer") 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. "Customer") 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 GoogleCloudChannelV1alpha1CustomerEvent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1CustomerEvent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1DateRange: A representation of usage or invoice
// date ranges.
type GoogleCloudChannelV1alpha1DateRange struct {
	// InvoiceEndDate: The latest invoice date (inclusive). If this value is not
	// the last day of a month, this will move it forward to the last day of the
	// given month.
	InvoiceEndDate *GoogleTypeDate `json:"invoiceEndDate,omitempty"`
	// InvoiceStartDate: The earliest invoice date (inclusive). If this value is
	// not the first day of a month, this will move it back to the first day of the
	// given month.
	InvoiceStartDate *GoogleTypeDate `json:"invoiceStartDate,omitempty"`
	// UsageEndDateTime: The latest usage date time (exclusive). If you use time
	// groupings (daily, weekly, etc), each group uses midnight to midnight
	// (Pacific time). The usage end date is rounded down to include all usage from
	// the specified date. We recommend that clients pass `usage_start_date_time`
	// in Pacific time.
	UsageEndDateTime *GoogleTypeDateTime `json:"usageEndDateTime,omitempty"`
	// UsageStartDateTime: The earliest usage date time (inclusive). If you use
	// time groupings (daily, weekly, etc), each group uses midnight to midnight
	// (Pacific time). The usage start date is rounded down to include all usage
	// from the specified date. We recommend that clients pass
	// `usage_start_date_time` in Pacific time.
	UsageStartDateTime *GoogleTypeDateTime `json:"usageStartDateTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "InvoiceEndDate") 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. "InvoiceEndDate") 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 GoogleCloudChannelV1alpha1DateRange) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1DateRange
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1Entitlement: An entitlement is a representation of
// a customer's ability to use a service.
type GoogleCloudChannelV1alpha1Entitlement struct {
	// AssignedUnits: The current number of users that are assigned a license for
	// the product defined in provisioned_service.skuId. Read-only. Deprecated: Use
	// `parameters` instead.
	AssignedUnits int64 `json:"assignedUnits,omitempty"`
	// AssociationInfo: Association information to other entitlements.
	AssociationInfo *GoogleCloudChannelV1alpha1AssociationInfo `json:"associationInfo,omitempty"`
	// BillingAccount: Optional. The billing account resource name that is used to
	// pay for this entitlement.
	BillingAccount string `json:"billingAccount,omitempty"`
	// ChannelPartnerId: Cloud Identity ID of a channel partner who will be the
	// direct reseller for the customer's order. This field is generally used in
	// 2-tier ordering, where the order is placed by a top-level distributor on
	// behalf of their channel partner or reseller. Required for distributors.
	// Deprecated: `channel_partner_id` has been moved to the Customer.
	ChannelPartnerId string `json:"channelPartnerId,omitempty"`
	// CommitmentSettings: Commitment settings for a commitment-based Offer.
	// Required for commitment based offers.
	CommitmentSettings *GoogleCloudChannelV1alpha1CommitmentSettings `json:"commitmentSettings,omitempty"`
	// CreateTime: Output only. The time at which the entitlement is created.
	CreateTime string `json:"createTime,omitempty"`
	// MaxUnits: Maximum number of units for a non commitment-based Offer, such as
	// Flexible, Trial or Free entitlements. For commitment-based entitlements,
	// this is a read-only field, which only the internal support team can update.
	// Deprecated: Use `parameters` instead.
	MaxUnits int64 `json:"maxUnits,omitempty"`
	// Name: Output only. Resource name of an entitlement in the form:
	// accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
	Name string `json:"name,omitempty"`
	// NumUnits: Number of units for a commitment-based Offer. For example, for
	// seat-based Offers, this would be the number of seats; for license-based
	// Offers, this would be the number of licenses. Required for creating
	// commitment-based Offers. Deprecated: Use `parameters` instead.
	NumUnits int64 `json:"numUnits,omitempty"`
	// Offer: Required. The offer resource name for which the entitlement is to be
	// created. Takes the form: accounts/{account_id}/offers/{offer_id}.
	Offer string `json:"offer,omitempty"`
	// Parameters: Extended entitlement parameters. When creating an entitlement,
	// valid parameter names and values are defined in the
	// Offer.parameter_definitions. For Google Workspace, the following Parameters
	// may be accepted as input: - max_units: The maximum assignable units for a
	// flexible offer OR - num_units: The total commitment for commitment-based
	// offers The response may additionally include the following output-only
	// Parameters: - assigned_units: The number of licenses assigned to users. For
	// Google Cloud billing subaccounts, the following Parameter may be accepted as
	// input: - display_name: The display name of the billing subaccount.
	Parameters []*GoogleCloudChannelV1alpha1Parameter `json:"parameters,omitempty"`
	// PriceReferenceId: Optional. Price reference ID for the offer. Only for
	// offers that require additional price information. Used to guarantee that the
	// pricing is consistent between quoting the offer and placing the order.
	PriceReferenceId string `json:"priceReferenceId,omitempty"`
	// ProvisionedService: Output only. Service provisioning details for the
	// entitlement.
	ProvisionedService *GoogleCloudChannelV1alpha1ProvisionedService `json:"provisionedService,omitempty"`
	// ProvisioningState: Output only. Current provisioning state of the
	// entitlement.
	//
	// Possible values:
	//   "PROVISIONING_STATE_UNSPECIFIED" - Not used.
	//   "ACTIVE" - The entitlement is currently active.
	//   "CANCELED" - The entitlement was canceled. After an entitlement is
	// `CANCELED`, its status will not change. Deprecated: Canceled entitlements
	// will no longer be visible.
	//   "COMPLETE" - The entitlement reached end of term and was not renewed.
	// After an entitlement is `COMPLETE`, its status will not change. Deprecated:
	// This is represented as ProvisioningState=SUSPENDED and suspensionReason in
	// (TRIAL_ENDED, RENEWAL_WITH_TYPE_CANCEL)
	//   "PENDING" - The entitlement is pending. Deprecated: This is represented as
	// ProvisioningState=SUSPENDED and suspensionReason=PENDING_TOS_ACCEPTANCE
	//   "SUSPENDED" - The entitlement is currently suspended.
	ProvisioningState string `json:"provisioningState,omitempty"`
	// PurchaseOrderId: Optional. This purchase order (PO) information is for
	// resellers to use for their company tracking usage. If a purchaseOrderId
	// value is given, it appears in the API responses and shows up in the invoice.
	// The property accepts up to 80 plain text characters. This is only supported
	// for Google Workspace entitlements.
	PurchaseOrderId string `json:"purchaseOrderId,omitempty"`
	// SuspensionReasons: Output only. Enumerable of all current suspension reasons
	// for an entitlement.
	//
	// Possible values:
	//   "SUSPENSION_REASON_UNSPECIFIED" - Not used.
	//   "RESELLER_INITIATED" - Entitlement was manually suspended by the Reseller.
	//   "TRIAL_ENDED" - Trial ended.
	//   "RENEWAL_WITH_TYPE_CANCEL" - Entitlement renewal was canceled.
	//   "PENDING_TOS_ACCEPTANCE" - Entitlement was automatically suspended on
	// creation for pending ToS acceptance on customer.
	//   "OTHER" - Other reasons (internal reasons, abuse, etc.).
	SuspensionReasons []string `json:"suspensionReasons,omitempty"`
	// TrialSettings: Output only. Settings for trial offers.
	TrialSettings *GoogleCloudChannelV1alpha1TrialSettings `json:"trialSettings,omitempty"`
	// UpdateTime: Output only. The time at which the entitlement is updated.
	UpdateTime string `json:"updateTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AssignedUnits") 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. "AssignedUnits") 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 GoogleCloudChannelV1alpha1Entitlement) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1Entitlement
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1EntitlementEvent: Represents Pub/Sub message
// content describing entitlement update.
type GoogleCloudChannelV1alpha1EntitlementEvent struct {
	// Entitlement: Resource name of an entitlement of the form:
	// accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}
	Entitlement string `json:"entitlement,omitempty"`
	// EventType: Type of event which happened for the entitlement.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Not used.
	//   "CREATED" - A new entitlement was created.
	//   "PRICE_PLAN_SWITCHED" - The offer type associated with an entitlement was
	// changed. This is not triggered if an entitlement converts from a commit
	// offer to a flexible offer as part of a renewal.
	//   "COMMITMENT_CHANGED" - Annual commitment for a commit plan was changed.
	//   "RENEWED" - An annual entitlement was renewed.
	//   "SUSPENDED" - Entitlement was suspended.
	//   "ACTIVATED" - Entitlement was unsuspended.
	//   "CANCELLED" - Entitlement was cancelled.
	//   "SKU_CHANGED" - Entitlement was upgraded or downgraded (e.g. from Google
	// Workspace Business Standard to Google Workspace Business Plus).
	//   "RENEWAL_SETTING_CHANGED" - The renewal settings of an entitlement has
	// changed.
	//   "PAID_SERVICE_STARTED" - Paid service has started on trial entitlement.
	//   "LICENSE_ASSIGNMENT_CHANGED" - License was assigned to or revoked from a
	// user.
	//   "LICENSE_CAP_CHANGED" - License cap was changed for the entitlement.
	EventType string `json:"eventType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Entitlement") 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. "Entitlement") 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 GoogleCloudChannelV1alpha1EntitlementEvent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1EntitlementEvent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1OperationMetadata: Provides contextual information
// about a google.longrunning.Operation.
type GoogleCloudChannelV1alpha1OperationMetadata struct {
	// OperationType: The RPC that initiated this Long Running Operation.
	//
	// Possible values:
	//   "OPERATION_TYPE_UNSPECIFIED" - Not used.
	//   "CREATE_ENTITLEMENT" - Long Running Operation was triggered by
	// CreateEntitlement.
	//   "CHANGE_QUANTITY" - Long Running Operation was triggered by
	// ChangeQuantity.
	//   "CHANGE_RENEWAL_SETTINGS" - Long Running Operation was triggered by
	// ChangeRenewalSettings.
	//   "CHANGE_PLAN" - Long Running Operation was triggered by ChangePlan.
	//   "START_PAID_SERVICE" - Long Running Operation was triggered by
	// StartPaidService.
	//   "CHANGE_SKU" - Long Running Operation was triggered by ChangeSku.
	//   "ACTIVATE_ENTITLEMENT" - Long Running Operation was triggered by
	// ActivateEntitlement.
	//   "SUSPEND_ENTITLEMENT" - Long Running Operation was triggered by
	// SuspendEntitlement.
	//   "CANCEL_ENTITLEMENT" - Long Running Operation was triggered by
	// CancelEntitlement.
	//   "TRANSFER_ENTITLEMENTS" - Long Running Operation was triggered by
	// TransferEntitlements.
	//   "TRANSFER_ENTITLEMENTS_TO_GOOGLE" - Long Running Operation was triggered
	// by TransferEntitlementsToGoogle.
	//   "CHANGE_OFFER" - Long Running Operation was triggered by ChangeOffer.
	//   "CHANGE_PARAMETERS" - Long Running Operation was triggered by
	// ChangeParameters.
	//   "PROVISION_CLOUD_IDENTITY" - Long Running Operation was triggered by
	// ProvisionCloudIdentity.
	OperationType string `json:"operationType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "OperationType") 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. "OperationType") 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 GoogleCloudChannelV1alpha1OperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1OperationMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1OpportunityEvent: Represents Pub/Sub message
// content describing opportunity updates.
type GoogleCloudChannelV1alpha1OpportunityEvent struct {
	// EventType: Type of event which happened for the opportunity.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Not used.
	//   "CREATED" - New opportunity created.
	//   "UPDATED" - Existing opportunity updated.
	//   "PARTNER_DETACHED" - Partner has been detached from the opportunity and
	// can no longer access it.
	EventType string `json:"eventType,omitempty"`
	// Opportunity: Resource name of the opportunity. Format:
	// opportunities/{opportunity}
	Opportunity string `json:"opportunity,omitempty"`
	// Partner: Resource name of the partner. Format: partners/{partner}
	Partner string `json:"partner,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EventType") 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. "EventType") 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 GoogleCloudChannelV1alpha1OpportunityEvent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1OpportunityEvent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1Parameter: Definition for extended entitlement
// parameters.
type GoogleCloudChannelV1alpha1Parameter struct {
	// Editable: Output only. Specifies whether this parameter is allowed to be
	// changed. For example, for a Google Workspace Business Starter entitlement in
	// commitment plan, num_units is editable when entitlement is active.
	Editable bool `json:"editable,omitempty"`
	// Name: Name of the parameter.
	Name string `json:"name,omitempty"`
	// Value: Value of the parameter.
	Value *GoogleCloudChannelV1alpha1Value `json:"value,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Editable") 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. "Editable") 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 GoogleCloudChannelV1alpha1Parameter) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1Parameter
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1Period: Represents period in days/months/years.
type GoogleCloudChannelV1alpha1Period struct {
	// Duration: Total duration of Period Type defined.
	Duration int64 `json:"duration,omitempty"`
	// PeriodType: Period Type.
	//
	// Possible values:
	//   "PERIOD_TYPE_UNSPECIFIED" - Not used.
	//   "DAY" - Day.
	//   "MONTH" - Month.
	//   "YEAR" - Year.
	PeriodType string `json:"periodType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Duration") 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. "Duration") 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 GoogleCloudChannelV1alpha1Period) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1Period
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1ProvisionedService: Service provisioned for an
// entitlement.
type GoogleCloudChannelV1alpha1ProvisionedService struct {
	// ProductId: Output only. The product pertaining to the provisioning resource
	// as specified in the Offer.
	ProductId string `json:"productId,omitempty"`
	// ProvisioningId: Output only. Provisioning ID of the entitlement. For Google
	// Workspace, this is the underlying Subscription ID. For Google Cloud, this is
	// the Billing Account ID of the billing subaccount.
	ProvisioningId string `json:"provisioningId,omitempty"`
	// SkuId: Output only. The SKU pertaining to the provisioning resource as
	// specified in the Offer.
	SkuId string `json:"skuId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ProductId") 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. "ProductId") 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 GoogleCloudChannelV1alpha1ProvisionedService) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1ProvisionedService
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1RenewalSettings: Renewal settings for renewable
// Offers.
type GoogleCloudChannelV1alpha1RenewalSettings struct {
	// DisableCommitment: If true, disables commitment-based offer on renewal and
	// switches to flexible or pay as you go. Deprecated: Use `payment_plan`
	// instead.
	DisableCommitment bool `json:"disableCommitment,omitempty"`
	// EnableRenewal: If false, the plan will be completed at the end date.
	EnableRenewal bool `json:"enableRenewal,omitempty"`
	// PaymentCycle: Describes how frequently the reseller will be billed, such as
	// once per month.
	PaymentCycle *GoogleCloudChannelV1alpha1Period `json:"paymentCycle,omitempty"`
	// PaymentOption: Set if enable_renewal=true. Deprecated: Use `payment_cycle`
	// instead.
	//
	// Possible values:
	//   "PAYMENT_OPTION_UNSPECIFIED" - Not used.
	//   "ANNUAL" - Paid in yearly installments.
	//   "MONTHLY" - Paid in monthly installments.
	PaymentOption string `json:"paymentOption,omitempty"`
	// PaymentPlan: Describes how a reseller will be billed.
	//
	// Possible values:
	//   "PAYMENT_PLAN_UNSPECIFIED" - Not used.
	//   "COMMITMENT" - Commitment.
	//   "FLEXIBLE" - No commitment.
	//   "FREE" - Free.
	//   "TRIAL" - Trial.
	//   "OFFLINE" - Price and ordering not available through API.
	PaymentPlan string `json:"paymentPlan,omitempty"`
	// ResizeUnitCount: If true and enable_renewal = true, the unit (for example
	// seats or licenses) will be set to the number of active units at renewal
	// time.
	ResizeUnitCount bool `json:"resizeUnitCount,omitempty"`
	// ScheduledRenewalOffer: Output only. The offer resource name that the
	// entitlement will renew on at the end date. Takes the form:
	// accounts/{account_id}/offers/{offer_id}.
	ScheduledRenewalOffer string `json:"scheduledRenewalOffer,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DisableCommitment") 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. "DisableCommitment") 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 GoogleCloudChannelV1alpha1RenewalSettings) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1RenewalSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1Report: The ID and description of a report that
// was used to generate report data. For example, "Google Cloud Daily Spend",
// "Google Workspace License Activity", etc.
type GoogleCloudChannelV1alpha1Report struct {
	// Columns: The list of columns included in the report. This defines the schema
	// of the report results.
	Columns []*GoogleCloudChannelV1alpha1Column `json:"columns,omitempty"`
	// Description: A description of other aspects of the report, such as the
	// products it supports.
	Description string `json:"description,omitempty"`
	// DisplayName: A human-readable name for this report.
	DisplayName string `json:"displayName,omitempty"`
	// Name: Required. The report's resource name. Specifies the account and report
	// used to generate report data. The report_id identifier is a UID (for
	// example, `613bf59q`). Name uses the format:
	// accounts/{account_id}/reports/{report_id}
	Name string `json:"name,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 GoogleCloudChannelV1alpha1Report) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1Report
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1ReportJob: The result of a RunReportJob operation.
// Contains the name to use in FetchReportResultsRequest.report_job and the
// status of the operation.
type GoogleCloudChannelV1alpha1ReportJob struct {
	// Name: Required. The resource name of a report job. Name uses the format:
	// `accounts/{account_id}/reportJobs/{report_job_id}`
	Name string `json:"name,omitempty"`
	// ReportStatus: The current status of report generation.
	ReportStatus *GoogleCloudChannelV1alpha1ReportStatus `json:"reportStatus,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 GoogleCloudChannelV1alpha1ReportJob) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1ReportJob
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1ReportResultsMetadata: The features describing the
// data. Returned by CloudChannelReportsService.RunReportJob and
// CloudChannelReportsService.FetchReportResults.
type GoogleCloudChannelV1alpha1ReportResultsMetadata struct {
	// DateRange: The date range of reported usage.
	DateRange *GoogleCloudChannelV1alpha1DateRange `json:"dateRange,omitempty"`
	// PrecedingDateRange: The usage dates immediately preceding `date_range` with
	// the same duration. Use this to calculate trending usage and costs. This is
	// only populated if you request trending data. For example, if `date_range` is
	// July 1-15, `preceding_date_range` will be June 16-30.
	PrecedingDateRange *GoogleCloudChannelV1alpha1DateRange `json:"precedingDateRange,omitempty"`
	// Report: Details of the completed report.
	Report *GoogleCloudChannelV1alpha1Report `json:"report,omitempty"`
	// RowCount: The total number of rows of data in the final report.
	RowCount int64 `json:"rowCount,omitempty,string"`
	// ForceSendFields is a list of field names (e.g. "DateRange") 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. "DateRange") 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 GoogleCloudChannelV1alpha1ReportResultsMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1ReportResultsMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1ReportStatus: Status of a report generation
// process.
type GoogleCloudChannelV1alpha1ReportStatus struct {
	// EndTime: The report generation's completion time.
	EndTime string `json:"endTime,omitempty"`
	// StartTime: The report generation's start time.
	StartTime string `json:"startTime,omitempty"`
	// State: The current state of the report generation process.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Not used.
	//   "STARTED" - Report processing started.
	//   "WRITING" - Data generated from the report is being staged.
	//   "AVAILABLE" - Report data is available for access.
	//   "FAILED" - Report failed.
	State string `json:"state,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. 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. "EndTime") 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 GoogleCloudChannelV1alpha1ReportStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1ReportStatus
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1RunReportJobResponse: Response message for
// CloudChannelReportsService.RunReportJob.
type GoogleCloudChannelV1alpha1RunReportJobResponse struct {
	// ReportJob: Pass `report_job.name` to FetchReportResultsRequest.report_job to
	// retrieve the report's results.
	ReportJob *GoogleCloudChannelV1alpha1ReportJob `json:"reportJob,omitempty"`
	// ReportMetadata: The metadata for the report's results (display name,
	// columns, row count, and date range). If you view this before the operation
	// finishes, you may see incomplete data.
	ReportMetadata *GoogleCloudChannelV1alpha1ReportResultsMetadata `json:"reportMetadata,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ReportJob") 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. "ReportJob") 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 GoogleCloudChannelV1alpha1RunReportJobResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1RunReportJobResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1SubscriberEvent: Represents information which
// resellers will get as part of notification from Pub/Sub.
type GoogleCloudChannelV1alpha1SubscriberEvent struct {
	// ChannelPartnerEvent: Channel Partner event sent as part of Pub/Sub event to
	// partners.
	ChannelPartnerEvent *GoogleCloudChannelV1alpha1ChannelPartnerEvent `json:"channelPartnerEvent,omitempty"`
	// CustomerEvent: Customer event sent as part of Pub/Sub event to partners.
	CustomerEvent *GoogleCloudChannelV1alpha1CustomerEvent `json:"customerEvent,omitempty"`
	// EntitlementEvent: Entitlement event sent as part of Pub/Sub event to
	// partners.
	EntitlementEvent *GoogleCloudChannelV1alpha1EntitlementEvent `json:"entitlementEvent,omitempty"`
	// OpportunityEvent: Opportunity event sent as part of Pub/Sub event to
	// partners/integrators.
	OpportunityEvent *GoogleCloudChannelV1alpha1OpportunityEvent `json:"opportunityEvent,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ChannelPartnerEvent") 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. "ChannelPartnerEvent") 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 GoogleCloudChannelV1alpha1SubscriberEvent) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1SubscriberEvent
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1TransferEntitlementsResponse: Response message for
// CloudChannelService.TransferEntitlements. This is put in the response field
// of google.longrunning.Operation.
type GoogleCloudChannelV1alpha1TransferEntitlementsResponse struct {
	// Entitlements: The transferred entitlements.
	Entitlements []*GoogleCloudChannelV1alpha1Entitlement `json:"entitlements,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Entitlements") 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. "Entitlements") 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 GoogleCloudChannelV1alpha1TransferEntitlementsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1TransferEntitlementsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1TrialSettings: Settings for trial offers.
type GoogleCloudChannelV1alpha1TrialSettings struct {
	// EndTime: Date when the trial ends. The value is in milliseconds using the
	// UNIX Epoch format. See an example Epoch converter
	// (https://www.epochconverter.com).
	EndTime string `json:"endTime,omitempty"`
	// Trial: Determines if the entitlement is in a trial or not: * `true` - The
	// entitlement is in trial. * `false` - The entitlement is not in trial.
	Trial bool `json:"trial,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. 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. "EndTime") 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 GoogleCloudChannelV1alpha1TrialSettings) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1TrialSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudChannelV1alpha1Value: Data type and value of a parameter.
type GoogleCloudChannelV1alpha1Value struct {
	// BoolValue: Represents a boolean value.
	BoolValue bool `json:"boolValue,omitempty"`
	// DoubleValue: Represents a double value.
	DoubleValue float64 `json:"doubleValue,omitempty"`
	// Int64Value: Represents an int64 value.
	Int64Value int64 `json:"int64Value,omitempty,string"`
	// ProtoValue: Represents an 'Any' proto value.
	ProtoValue googleapi.RawMessage `json:"protoValue,omitempty"`
	// StringValue: Represents a string value.
	StringValue string `json:"stringValue,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BoolValue") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. 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. "BoolValue") 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 GoogleCloudChannelV1alpha1Value) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudChannelV1alpha1Value
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

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

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

// GoogleLongrunningListOperationsResponse: The response message for
// Operations.ListOperations.
type GoogleLongrunningListOperationsResponse 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 []*GoogleLongrunningOperation `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 GoogleLongrunningListOperationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleLongrunningListOperationsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleLongrunningOperation: This resource represents a long-running
// operation that is the result of a network API call.
type GoogleLongrunningOperation 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 *GoogleRpcStatus `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 GoogleLongrunningOperation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleLongrunningOperation
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

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

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

// GoogleTypeDate: Represents a whole or partial calendar date, such as a
// birthday. The time of day and time zone are either specified elsewhere or
// are insignificant. The date is relative to the Gregorian Calendar. This can
// represent one of the following: * A full date, with non-zero year, month,
// and day values. * A month and day, with a zero year (for example, an
// anniversary). * A year on its own, with a zero month and a zero day. * A
// year and month, with a zero day (for example, a credit card expiration
// date). Related types: * google.type.TimeOfDay * google.type.DateTime *
// google.protobuf.Timestamp
type GoogleTypeDate struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and month,
	// or 0 to specify a year by itself or a year and month where the day isn't
	// significant.
	Day int64 `json:"day,omitempty"`
	// Month: Month of a year. Must be from 1 to 12, or 0 to specify a year without
	// a month and day.
	Month int64 `json:"month,omitempty"`
	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a date
	// without a year.
	Year int64 `json:"year,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Day") 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. "Day") 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 GoogleTypeDate) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypeDate
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleTypeDateTime: Represents civil time (or occasionally physical time).
// This type can represent a civil time in one of a few possible ways: * When
// utc_offset is set and time_zone is unset: a civil time on a calendar day
// with a particular offset from UTC. * When time_zone is set and utc_offset is
// unset: a civil time on a calendar day in a particular time zone. * When
// neither time_zone nor utc_offset is set: a civil time on a calendar day in
// local time. The date is relative to the Proleptic Gregorian Calendar. If
// year, month, or day are 0, the DateTime is considered not to have a specific
// year, month, or day respectively. This type may also be used to represent a
// physical time if all the date and time fields are set and either case of the
// `time_offset` oneof is set. Consider using `Timestamp` message for physical
// time instead. If your use case also would like to store the user's timezone,
// that can be done in another field. This type is more flexible than some
// applications may want. Make sure to document and validate your application's
// limitations.
type GoogleTypeDateTime struct {
	// Day: Optional. Day of month. Must be from 1 to 31 and valid for the year and
	// month, or 0 if specifying a datetime without a day.
	Day int64 `json:"day,omitempty"`
	// Hours: Optional. Hours of day in 24 hour format. Should be from 0 to 23,
	// defaults to 0 (midnight). An API may choose to allow the value "24:00:00"
	// for scenarios like business closing time.
	Hours int64 `json:"hours,omitempty"`
	// Minutes: Optional. Minutes of hour of day. Must be from 0 to 59, defaults to
	// 0.
	Minutes int64 `json:"minutes,omitempty"`
	// Month: Optional. Month of year. Must be from 1 to 12, or 0 if specifying a
	// datetime without a month.
	Month int64 `json:"month,omitempty"`
	// Nanos: Optional. Fractions of seconds in nanoseconds. Must be from 0 to
	// 999,999,999, defaults to 0.
	Nanos int64 `json:"nanos,omitempty"`
	// Seconds: Optional. Seconds of minutes of the time. Must normally be from 0
	// to 59, defaults to 0. An API may allow the value 60 if it allows
	// leap-seconds.
	Seconds int64 `json:"seconds,omitempty"`
	// TimeZone: Time zone.
	TimeZone *GoogleTypeTimeZone `json:"timeZone,omitempty"`
	// UtcOffset: UTC offset. Must be whole seconds, between -18 hours and +18
	// hours. For example, a UTC offset of -4:00 would be represented as { seconds:
	// -14400 }.
	UtcOffset string `json:"utcOffset,omitempty"`
	// Year: Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a
	// datetime without a year.
	Year int64 `json:"year,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Day") 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. "Day") 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 GoogleTypeDateTime) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypeDateTime
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleTypeDecimal: A representation of a decimal value, such as 2.5. Clients
// may convert values into language-native decimal formats, such as Java's
// BigDecimal
// (https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html)
// or Python's decimal.Decimal
// (https://docs.python.org/3/library/decimal.html).
type GoogleTypeDecimal struct {
	// Value: The decimal value, as a string. The string representation consists of
	// an optional sign, `+` (`U+002B`) or `-` (`U+002D`), followed by a sequence
	// of zero or more decimal digits ("the integer"), optionally followed by a
	// fraction, optionally followed by an exponent. An empty string **should** be
	// interpreted as `0`. The fraction consists of a decimal point followed by
	// zero or more decimal digits. The string must contain at least one digit in
	// either the integer or the fraction. The number formed by the sign, the
	// integer and the fraction is referred to as the significand. The exponent
	// consists of the character `e` (`U+0065`) or `E` (`U+0045`) followed by one
	// or more decimal digits. Services **should** normalize decimal values before
	// storing them by: - Removing an explicitly-provided `+` sign (`+2.5` ->
	// `2.5`). - Replacing a zero-length integer value with `0` (`.5` -> `0.5`). -
	// Coercing the exponent character to upper-case, with explicit sign (`2.5e8`
	// -> `2.5E+8`). - Removing an explicitly-provided zero exponent (`2.5E0` ->
	// `2.5`). Services **may** perform additional normalization based on its own
	// needs and the internal decimal implementation selected, such as shifting the
	// decimal point and exponent value together (example: `2.5E-1` <-> `0.25`).
	// Additionally, services **may** preserve trailing zeroes in the fraction to
	// indicate increased precision, but are not required to do so. Note that only
	// the `.` character is supported to divide the integer and the fraction; `,`
	// **should not** be supported regardless of locale. Additionally, thousand
	// separators **should not** be supported. If a service does support them,
	// values **must** be normalized. The ENBF grammar is: DecimalString = '' |
	// [Sign] Significand [Exponent]; Sign = '+' | '-'; Significand = Digits '.' |
	// [Digits] '.' Digits; Exponent = ('e' | 'E') [Sign] Digits; Digits = { '0' |
	// '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; Services **should**
	// clearly document the range of supported values, the maximum supported
	// precision (total number of digits), and, if applicable, the scale (number of
	// digits after the decimal point), as well as how it behaves when receiving
	// out-of-bounds values. Services **may** choose to accept values passed as
	// input even when the value has a higher precision or scale than the service
	// supports, and **should** round the value to fit the supported scale.
	// Alternatively, the service **may** error with `400 Bad Request`
	// (`INVALID_ARGUMENT` in gRPC) if precision would be lost. Services **should**
	// error with `400 Bad Request` (`INVALID_ARGUMENT` in gRPC) if the service
	// receives a value outside of the supported range.
	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 GoogleTypeDecimal) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypeDecimal
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleTypeMoney: Represents an amount of money with its currency type.
type GoogleTypeMoney struct {
	// CurrencyCode: The three-letter currency code defined in ISO 4217.
	CurrencyCode string `json:"currencyCode,omitempty"`
	// Nanos: Number of nano (10^-9) units of the amount. The value must be between
	// -999,999,999 and +999,999,999 inclusive. If `units` is positive, `nanos`
	// must be positive or zero. If `units` is zero, `nanos` can be positive, zero,
	// or negative. If `units` is negative, `nanos` must be negative or zero. For
	// example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
	Nanos int64 `json:"nanos,omitempty"`
	// Units: The whole units of the amount. For example if `currencyCode` is
	// "USD", then 1 unit is one US dollar.
	Units int64 `json:"units,omitempty,string"`
	// ForceSendFields is a list of field names (e.g. "CurrencyCode") 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. "CurrencyCode") 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 GoogleTypeMoney) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypeMoney
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleTypePostalAddress: Represents a postal address, such as for postal
// delivery or payments addresses. With a postal address, a postal service can
// deliver items to a premise, P.O. box, or similar. A postal address is not
// intended to model geographical locations like roads, towns, or mountains. In
// typical usage, an address would be created by user input or from importing
// existing data, depending on the type of process. Advice on address input or
// editing: - Use an internationalization-ready address widget such as
// https://github.com/google/libaddressinput. - Users should not be presented
// with UI elements for input or editing of fields outside countries where that
// field is used. For more guidance on how to use this schema, see:
// https://support.google.com/business/answer/6397478.
type GoogleTypePostalAddress struct {
	// AddressLines: Unstructured address lines describing the lower levels of an
	// address. Because values in `address_lines` do not have type information and
	// may sometimes contain multiple values in a single field (for example,
	// "Austin, TX"), it is important that the line order is clear. The order of
	// address lines should be "envelope order" for the country or region of the
	// address. In places where this can vary (for example, Japan),
	// `address_language` is used to make it explicit (for example, "ja" for
	// large-to-small ordering and "ja-Latn" or "en" for small-to-large). In this
	// way, the most specific line of an address can be selected based on the
	// language. The minimum permitted structural representation of an address
	// consists of a `region_code` with all remaining information placed in the
	// `address_lines`. It would be possible to format such an address very
	// approximately without geocoding, but no semantic reasoning could be made
	// about any of the address components until it was at least partially
	// resolved. Creating an address only containing a `region_code` and
	// `address_lines` and then geocoding is the recommended way to handle
	// completely unstructured addresses (as opposed to guessing which parts of the
	// address should be localities or administrative areas).
	AddressLines []string `json:"addressLines,omitempty"`
	// AdministrativeArea: Optional. Highest administrative subdivision which is
	// used for postal addresses of a country or region. For example, this can be a
	// state, a province, an oblast, or a prefecture. For Spain, this is the
	// province and not the autonomous community (for example, "Barcelona" and not
	// "Catalonia"). Many countries don't use an administrative area in postal
	// addresses. For example, in Switzerland, this should be left unpopulated.
	AdministrativeArea string `json:"administrativeArea,omitempty"`
	// LanguageCode: Optional. BCP-47 language code of the contents of this address
	// (if known). This is often the UI language of the input form or is expected
	// to match one of the languages used in the address' country/region, or their
	// transliterated equivalents. This can affect formatting in certain countries,
	// but is not critical to the correctness of the data and will never affect any
	// validation or other non-formatting related operations. If this value is not
	// known, it should be omitted (rather than specifying a possibly incorrect
	// default). Examples: "zh-Hant", "ja", "ja-Latn", "en".
	LanguageCode string `json:"languageCode,omitempty"`
	// Locality: Optional. Generally refers to the city or town portion of the
	// address. Examples: US city, IT comune, UK post town. In regions of the world
	// where localities are not well defined or do not fit into this structure
	// well, leave `locality` empty and use `address_lines`.
	Locality string `json:"locality,omitempty"`
	// Organization: Optional. The name of the organization at the address.
	Organization string `json:"organization,omitempty"`
	// PostalCode: Optional. Postal code of the address. Not all countries use or
	// require postal codes to be present, but where they are used, they may
	// trigger additional validation with other parts of the address (for example,
	// state or zip code validation in the United States).
	PostalCode string `json:"postalCode,omitempty"`
	// Recipients: Optional. The recipient at the address. This field may, under
	// certain circumstances, contain multiline information. For example, it might
	// contain "care of" information.
	Recipients []string `json:"recipients,omitempty"`
	// RegionCode: Required. CLDR region code of the country/region of the address.
	// This is never inferred and it is up to the user to ensure the value is
	// correct. See https://cldr.unicode.org/ and
	// https://www.unicode.org/cldr/charts/30/supplemental/territory_information.html
	// for details. Example: "CH" for Switzerland.
	RegionCode string `json:"regionCode,omitempty"`
	// Revision: The schema revision of the `PostalAddress`. This must be set to 0,
	// which is the latest revision. All new revisions **must** be backward
	// compatible with old revisions.
	Revision int64 `json:"revision,omitempty"`
	// SortingCode: Optional. Additional, country-specific, sorting code. This is
	// not used in most regions. Where it is used, the value is either a string
	// like "CEDEX", optionally followed by a number (for example, "CEDEX 7"), or
	// just a number alone, representing the "sector code" (Jamaica), "delivery
	// area indicator" (Malawi) or "post office indicator" (Côte d'Ivoire).
	SortingCode string `json:"sortingCode,omitempty"`
	// Sublocality: Optional. Sublocality of the address. For example, this can be
	// a neighborhood, borough, or district.
	Sublocality string `json:"sublocality,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AddressLines") 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. "AddressLines") 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 GoogleTypePostalAddress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypePostalAddress
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleTypeTimeZone: Represents a time zone from the IANA Time Zone Database
// (https://www.iana.org/time-zones).
type GoogleTypeTimeZone struct {
	// Id: IANA Time Zone Database time zone. For example "America/New_York".
	Id string `json:"id,omitempty"`
	// Version: Optional. IANA Time Zone Database version number. For example
	// "2019a".
	Version string `json:"version,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Id") 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. "Id") 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 GoogleTypeTimeZone) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypeTimeZone
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

type AccountsCheckCloudIdentityAccountsExistCall struct {
	s                                                          *Service
	parent                                                     string
	googlecloudchannelv1checkcloudidentityaccountsexistrequest *GoogleCloudChannelV1CheckCloudIdentityAccountsExistRequest
	urlParams_                                                 gensupport.URLParams
	ctx_                                                       context.Context
	header_                                                    http.Header
}

// CheckCloudIdentityAccountsExist: Confirms the existence of Cloud Identity
// accounts based on the domain and if the Cloud Identity accounts are owned by
// the reseller. Possible error codes: * PERMISSION_DENIED: The reseller
// account making the request is different from the reseller account in the API
// request. * INVALID_ARGUMENT: Required request parameters are missing or
// invalid. * INVALID_VALUE: Invalid domain value in the request. Return value:
// A list of CloudIdentityCustomerAccount resources for the domain (may be
// empty) Note: in the v1alpha1 version of the API, a NOT_FOUND error returns
// if no CloudIdentityCustomerAccount resources match the domain.
//
//   - parent: The reseller account's resource name. Parent uses the format:
//     accounts/{account_id}.
func (r *AccountsService) CheckCloudIdentityAccountsExist(parent string, googlecloudchannelv1checkcloudidentityaccountsexistrequest *GoogleCloudChannelV1CheckCloudIdentityAccountsExistRequest) *AccountsCheckCloudIdentityAccountsExistCall {
	c := &AccountsCheckCloudIdentityAccountsExistCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1checkcloudidentityaccountsexistrequest = googlecloudchannelv1checkcloudidentityaccountsexistrequest
	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 *AccountsCheckCloudIdentityAccountsExistCall) Fields(s ...googleapi.Field) *AccountsCheckCloudIdentityAccountsExistCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCheckCloudIdentityAccountsExistCall) Context(ctx context.Context) *AccountsCheckCloudIdentityAccountsExistCall {
	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 *AccountsCheckCloudIdentityAccountsExistCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCheckCloudIdentityAccountsExistCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1checkcloudidentityaccountsexistrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:checkCloudIdentityAccountsExist")
	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", "cloudchannel.accounts.checkCloudIdentityAccountsExist", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.checkCloudIdentityAccountsExist" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1CheckCloudIdentityAccountsExistResponse.ServerResponse.H
// eader or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *AccountsCheckCloudIdentityAccountsExistCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1CheckCloudIdentityAccountsExistResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1CheckCloudIdentityAccountsExistResponse{
		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", "cloudchannel.accounts.checkCloudIdentityAccountsExist", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// ListSubscribers: Lists service accounts with subscriber privileges on the
// Pub/Sub topic created for this Channel Services account or integrator.
// Possible error codes: * PERMISSION_DENIED: The reseller account making the
// request and the provided reseller account are different, or the impersonated
// user is not a super admin. * INVALID_ARGUMENT: Required request parameters
// are missing or invalid. * NOT_FOUND: The topic resource doesn't exist. *
// INTERNAL: Any non-user error related to a technical issue in the backend.
// Contact Cloud Channel support. * UNKNOWN: Any non-user error related to a
// technical issue in the backend. Contact Cloud Channel support. Return value:
// A list of service email addresses.
//
//   - account: Optional. Resource name of the account. Required if integrator is
//     not provided. Otherwise, leave this field empty/unset.
func (r *AccountsService) ListSubscribers(account string) *AccountsListSubscribersCall {
	c := &AccountsListSubscribersCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.account = account
	return c
}

// Integrator sets the optional parameter "integrator": Resource name of the
// integrator. Required if account is not provided. Otherwise, leave this field
// empty/unset.
func (c *AccountsListSubscribersCall) Integrator(integrator string) *AccountsListSubscribersCall {
	c.urlParams_.Set("integrator", integrator)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// service accounts to return. The service may return fewer than this value. If
// unspecified, returns at most 100 service accounts. The maximum value is
// 1000; the server will coerce values above 1000.
func (c *AccountsListSubscribersCall) PageSize(pageSize int64) *AccountsListSubscribersCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *AccountsListSubscribersCall) Context(ctx context.Context) *AccountsListSubscribersCall {
	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 *AccountsListSubscribersCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsListSubscribersCall) 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/{+account}:listSubscribers")
	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{
		"account": c.account,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "cloudchannel.accounts.listSubscribers", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.listSubscribers" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListSubscribersResponse.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 *AccountsListSubscribersCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListSubscribersResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListSubscribersResponse{
		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", "cloudchannel.accounts.listSubscribers", "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 *AccountsListSubscribersCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListSubscribersResponse) 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 AccountsListTransferableOffersCall struct {
	s                                                 *Service
	parent                                            string
	googlecloudchannelv1listtransferableoffersrequest *GoogleCloudChannelV1ListTransferableOffersRequest
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// ListTransferableOffers: List TransferableOffers of a customer based on Cloud
// Identity ID or Customer Name in the request. Use this method when a reseller
// gets the entitlement information of an unowned customer. The reseller should
// provide the customer's Cloud Identity ID or Customer Name. Possible error
// codes: * PERMISSION_DENIED: * The customer doesn't belong to the reseller
// and has no auth token. * The customer provided incorrect reseller
// information when generating auth token. * The reseller account making the
// request is different from the reseller account in the query. * The reseller
// is not authorized to transact on this Product. See
// https://support.google.com/channelservices/answer/9759265 *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. Return
// value: List of TransferableOffer for the given customer and SKU.
//
// - parent: The resource name of the reseller's account.
func (r *AccountsService) ListTransferableOffers(parent string, googlecloudchannelv1listtransferableoffersrequest *GoogleCloudChannelV1ListTransferableOffersRequest) *AccountsListTransferableOffersCall {
	c := &AccountsListTransferableOffersCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1listtransferableoffersrequest = googlecloudchannelv1listtransferableoffersrequest
	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 *AccountsListTransferableOffersCall) Fields(s ...googleapi.Field) *AccountsListTransferableOffersCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsListTransferableOffersCall) Context(ctx context.Context) *AccountsListTransferableOffersCall {
	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 *AccountsListTransferableOffersCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsListTransferableOffersCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1listtransferableoffersrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:listTransferableOffers")
	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", "cloudchannel.accounts.listTransferableOffers", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.listTransferableOffers" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListTransferableOffersResponse.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 *AccountsListTransferableOffersCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListTransferableOffersResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListTransferableOffersResponse{
		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", "cloudchannel.accounts.listTransferableOffers", "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 *AccountsListTransferableOffersCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListTransferableOffersResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.googlecloudchannelv1listtransferableoffersrequest.PageToken = pt }(c.googlecloudchannelv1listtransferableoffersrequest.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.googlecloudchannelv1listtransferableoffersrequest.PageToken = x.NextPageToken
	}
}

type AccountsListTransferableSkusCall struct {
	s                                               *Service
	parent                                          string
	googlecloudchannelv1listtransferableskusrequest *GoogleCloudChannelV1ListTransferableSkusRequest
	urlParams_                                      gensupport.URLParams
	ctx_                                            context.Context
	header_                                         http.Header
}

// ListTransferableSkus: List TransferableSkus of a customer based on the Cloud
// Identity ID or Customer Name in the request. Use this method to list the
// entitlements information of an unowned customer. You should provide the
// customer's Cloud Identity ID or Customer Name. Possible error codes: *
// PERMISSION_DENIED: * The customer doesn't belong to the reseller and has no
// auth token. * The supplied auth token is invalid. * The reseller account
// making the request is different from the reseller account in the query. *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. Return
// value: A list of the customer's TransferableSku.
//
//   - parent: The reseller account's resource name. Parent uses the format:
//     accounts/{account_id}.
func (r *AccountsService) ListTransferableSkus(parent string, googlecloudchannelv1listtransferableskusrequest *GoogleCloudChannelV1ListTransferableSkusRequest) *AccountsListTransferableSkusCall {
	c := &AccountsListTransferableSkusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1listtransferableskusrequest = googlecloudchannelv1listtransferableskusrequest
	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 *AccountsListTransferableSkusCall) Fields(s ...googleapi.Field) *AccountsListTransferableSkusCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsListTransferableSkusCall) Context(ctx context.Context) *AccountsListTransferableSkusCall {
	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 *AccountsListTransferableSkusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsListTransferableSkusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1listtransferableskusrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:listTransferableSkus")
	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", "cloudchannel.accounts.listTransferableSkus", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.listTransferableSkus" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListTransferableSkusResponse.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 *AccountsListTransferableSkusCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListTransferableSkusResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListTransferableSkusResponse{
		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", "cloudchannel.accounts.listTransferableSkus", "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 *AccountsListTransferableSkusCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListTransferableSkusResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.googlecloudchannelv1listtransferableskusrequest.PageToken = pt }(c.googlecloudchannelv1listtransferableskusrequest.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.googlecloudchannelv1listtransferableskusrequest.PageToken = x.NextPageToken
	}
}

type AccountsRegisterCall struct {
	s                                             *Service
	account                                       string
	googlecloudchannelv1registersubscriberrequest *GoogleCloudChannelV1RegisterSubscriberRequest
	urlParams_                                    gensupport.URLParams
	ctx_                                          context.Context
	header_                                       http.Header
}

// Register: Registers a service account with subscriber privileges on the
// Pub/Sub topic for this Channel Services account or integrator. After you
// create a subscriber, you get the events through SubscriberEvent Possible
// error codes: * PERMISSION_DENIED: The reseller account making the request
// and the provided reseller account are different, or the impersonated user is
// not a super admin. * INVALID_ARGUMENT: Required request parameters are
// missing or invalid. * INTERNAL: Any non-user error related to a technical
// issue in the backend. Contact Cloud Channel support. * UNKNOWN: Any non-user
// error related to a technical issue in the backend. Contact Cloud Channel
// support. Return value: The topic name with the registered service email
// address.
//
//   - account: Optional. Resource name of the account. Required if integrator is
//     not provided. Otherwise, leave this field empty/unset.
func (r *AccountsService) Register(account string, googlecloudchannelv1registersubscriberrequest *GoogleCloudChannelV1RegisterSubscriberRequest) *AccountsRegisterCall {
	c := &AccountsRegisterCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.account = account
	c.googlecloudchannelv1registersubscriberrequest = googlecloudchannelv1registersubscriberrequest
	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 *AccountsRegisterCall) Fields(s ...googleapi.Field) *AccountsRegisterCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsRegisterCall) Context(ctx context.Context) *AccountsRegisterCall {
	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 *AccountsRegisterCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "cloudchannel.accounts.register" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1RegisterSubscriberResponse.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 *AccountsRegisterCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1RegisterSubscriberResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1RegisterSubscriberResponse{
		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", "cloudchannel.accounts.register", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsUnregisterCall struct {
	s                                               *Service
	account                                         string
	googlecloudchannelv1unregistersubscriberrequest *GoogleCloudChannelV1UnregisterSubscriberRequest
	urlParams_                                      gensupport.URLParams
	ctx_                                            context.Context
	header_                                         http.Header
}

// Unregister: Unregisters a service account with subscriber privileges on the
// Pub/Sub topic created for this Channel Services account or integrator. If
// there are no service accounts left with subscriber privileges, this deletes
// the topic. You can call ListSubscribers to check for these accounts.
// Possible error codes: * PERMISSION_DENIED: The reseller account making the
// request and the provided reseller account are different, or the impersonated
// user is not a super admin. * INVALID_ARGUMENT: Required request parameters
// are missing or invalid. * NOT_FOUND: The topic resource doesn't exist. *
// INTERNAL: Any non-user error related to a technical issue in the backend.
// Contact Cloud Channel support. * UNKNOWN: Any non-user error related to a
// technical issue in the backend. Contact Cloud Channel support. Return value:
// The topic name that unregistered the service email address. Returns a
// success response if the service email address wasn't registered with the
// topic.
//
//   - account: Optional. Resource name of the account. Required if integrator is
//     not provided. Otherwise, leave this field empty/unset.
func (r *AccountsService) Unregister(account string, googlecloudchannelv1unregistersubscriberrequest *GoogleCloudChannelV1UnregisterSubscriberRequest) *AccountsUnregisterCall {
	c := &AccountsUnregisterCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.account = account
	c.googlecloudchannelv1unregistersubscriberrequest = googlecloudchannelv1unregistersubscriberrequest
	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 *AccountsUnregisterCall) Fields(s ...googleapi.Field) *AccountsUnregisterCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsUnregisterCall) Context(ctx context.Context) *AccountsUnregisterCall {
	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 *AccountsUnregisterCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "cloudchannel.accounts.unregister" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1UnregisterSubscriberResponse.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 *AccountsUnregisterCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1UnregisterSubscriberResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1UnregisterSubscriberResponse{
		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", "cloudchannel.accounts.unregister", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsChannelPartnerLinksCreateCall struct {
	s                                      *Service
	parent                                 string
	googlecloudchannelv1channelpartnerlink *GoogleCloudChannelV1ChannelPartnerLink
	urlParams_                             gensupport.URLParams
	ctx_                                   context.Context
	header_                                http.Header
}

// Create: Initiates a channel partner link between a distributor and a
// reseller, or between resellers in an n-tier reseller channel. Invited
// partners need to follow the invite_link_uri provided in the response to
// accept. After accepting the invitation, a link is set up between the two
// parties. You must be a distributor to call this method. Possible error
// codes: * PERMISSION_DENIED: The reseller account making the request is
// different from the reseller account in the API request. * INVALID_ARGUMENT:
// Required request parameters are missing or invalid. * ALREADY_EXISTS: The
// ChannelPartnerLink sent in the request already exists. * NOT_FOUND: No Cloud
// Identity customer exists for provided domain. * INTERNAL: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// * UNKNOWN: Any non-user error related to a technical issue in the backend.
// Contact Cloud Channel support. Return value: The new ChannelPartnerLink
// resource.
//
//   - parent: Create a channel partner link for the provided reseller account's
//     resource name. Parent uses the format: accounts/{account_id}.
func (r *AccountsChannelPartnerLinksService) Create(parent string, googlecloudchannelv1channelpartnerlink *GoogleCloudChannelV1ChannelPartnerLink) *AccountsChannelPartnerLinksCreateCall {
	c := &AccountsChannelPartnerLinksCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1channelpartnerlink = googlecloudchannelv1channelpartnerlink
	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 *AccountsChannelPartnerLinksCreateCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksCreateCall) Context(ctx context.Context) *AccountsChannelPartnerLinksCreateCall {
	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 *AccountsChannelPartnerLinksCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1channelpartnerlink)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/channelPartnerLinks")
	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", "cloudchannel.accounts.channelPartnerLinks.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ChannelPartnerLink.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 *AccountsChannelPartnerLinksCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ChannelPartnerLink, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ChannelPartnerLink{
		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", "cloudchannel.accounts.channelPartnerLinks.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Returns the requested ChannelPartnerLink resource. You must be a
// distributor to call this method. Possible error codes: * PERMISSION_DENIED:
// The reseller account making the request is different from the reseller
// account in the API request. * INVALID_ARGUMENT: Required request parameters
// are missing or invalid. * NOT_FOUND: ChannelPartnerLink resource not found
// because of an invalid channel partner link name. Return value: The
// ChannelPartnerLink resource.
//
//   - name: The resource name of the channel partner link to retrieve. Name uses
//     the format: accounts/{account_id}/channelPartnerLinks/{id} where {id} is
//     the Cloud Identity ID of the partner.
func (r *AccountsChannelPartnerLinksService) Get(name string) *AccountsChannelPartnerLinksGetCall {
	c := &AccountsChannelPartnerLinksGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// View sets the optional parameter "view": The level of granularity the
// ChannelPartnerLink will display.
//
// Possible values:
//
//	"UNSPECIFIED" - The default / unset value. The API will default to the
//
// BASIC view.
//
//	"BASIC" - Includes all fields except the
//
// ChannelPartnerLink.channel_partner_cloud_identity_info.
//
//	"FULL" - Includes all fields.
func (c *AccountsChannelPartnerLinksGetCall) View(view string) *AccountsChannelPartnerLinksGetCall {
	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 *AccountsChannelPartnerLinksGetCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksGetCall {
	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 *AccountsChannelPartnerLinksGetCall) IfNoneMatch(entityTag string) *AccountsChannelPartnerLinksGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksGetCall) Context(ctx context.Context) *AccountsChannelPartnerLinksGetCall {
	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 *AccountsChannelPartnerLinksGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksGetCall) 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", "cloudchannel.accounts.channelPartnerLinks.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ChannelPartnerLink.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 *AccountsChannelPartnerLinksGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ChannelPartnerLink, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ChannelPartnerLink{
		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", "cloudchannel.accounts.channelPartnerLinks.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: List ChannelPartnerLinks belonging to a distributor. You must be a
// distributor to call this method. Possible error codes: * PERMISSION_DENIED:
// The reseller account making the request is different from the reseller
// account in the API request. * INVALID_ARGUMENT: Required request parameters
// are missing or invalid. Return value: The list of the distributor account's
// ChannelPartnerLink resources.
//
//   - parent: The resource name of the reseller account for listing channel
//     partner links. Parent uses the format: accounts/{account_id}.
func (r *AccountsChannelPartnerLinksService) List(parent string) *AccountsChannelPartnerLinksListCall {
	c := &AccountsChannelPartnerLinksListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size. Server
// might return fewer results than requested. If unspecified, server will pick
// a default size (25). The maximum value is 200; the server will coerce values
// above 200.
func (c *AccountsChannelPartnerLinksListCall) PageSize(pageSize int64) *AccountsChannelPartnerLinksListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token for a page of
// results other than the first page. Obtained using
// ListChannelPartnerLinksResponse.next_page_token of the previous
// CloudChannelService.ListChannelPartnerLinks call.
func (c *AccountsChannelPartnerLinksListCall) PageToken(pageToken string) *AccountsChannelPartnerLinksListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// View sets the optional parameter "view": The level of granularity the
// ChannelPartnerLink will display.
//
// Possible values:
//
//	"UNSPECIFIED" - The default / unset value. The API will default to the
//
// BASIC view.
//
//	"BASIC" - Includes all fields except the
//
// ChannelPartnerLink.channel_partner_cloud_identity_info.
//
//	"FULL" - Includes all fields.
func (c *AccountsChannelPartnerLinksListCall) View(view string) *AccountsChannelPartnerLinksListCall {
	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 *AccountsChannelPartnerLinksListCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksListCall {
	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 *AccountsChannelPartnerLinksListCall) IfNoneMatch(entityTag string) *AccountsChannelPartnerLinksListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksListCall) Context(ctx context.Context) *AccountsChannelPartnerLinksListCall {
	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 *AccountsChannelPartnerLinksListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksListCall) 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}/channelPartnerLinks")
	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", "cloudchannel.accounts.channelPartnerLinks.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListChannelPartnerLinksResponse.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 *AccountsChannelPartnerLinksListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListChannelPartnerLinksResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListChannelPartnerLinksResponse{
		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", "cloudchannel.accounts.channelPartnerLinks.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 *AccountsChannelPartnerLinksListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListChannelPartnerLinksResponse) 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 AccountsChannelPartnerLinksPatchCall struct {
	s                                                   *Service
	name                                                string
	googlecloudchannelv1updatechannelpartnerlinkrequest *GoogleCloudChannelV1UpdateChannelPartnerLinkRequest
	urlParams_                                          gensupport.URLParams
	ctx_                                                context.Context
	header_                                             http.Header
}

// Patch: Updates a channel partner link. Distributors call this method to
// change a link's status. For example, to suspend a partner link. You must be
// a distributor to call this method. Possible error codes: *
// PERMISSION_DENIED: The reseller account making the request is different from
// the reseller account in the API request. * INVALID_ARGUMENT: * Required
// request parameters are missing or invalid. * Link state cannot change from
// invited to active or suspended. * Cannot send reseller_cloud_identity_id,
// invite_url, or name in update mask. * NOT_FOUND: ChannelPartnerLink resource
// not found. * INTERNAL: Any non-user error related to a technical issue in
// the backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The updated ChannelPartnerLink resource.
//
//   - name: The resource name of the channel partner link to cancel. Name uses
//     the format: accounts/{account_id}/channelPartnerLinks/{id} where {id} is
//     the Cloud Identity ID of the partner.
func (r *AccountsChannelPartnerLinksService) Patch(name string, googlecloudchannelv1updatechannelpartnerlinkrequest *GoogleCloudChannelV1UpdateChannelPartnerLinkRequest) *AccountsChannelPartnerLinksPatchCall {
	c := &AccountsChannelPartnerLinksPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1updatechannelpartnerlinkrequest = googlecloudchannelv1updatechannelpartnerlinkrequest
	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 *AccountsChannelPartnerLinksPatchCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksPatchCall) Context(ctx context.Context) *AccountsChannelPartnerLinksPatchCall {
	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 *AccountsChannelPartnerLinksPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1updatechannelpartnerlinkrequest)
	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", "cloudchannel.accounts.channelPartnerLinks.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ChannelPartnerLink.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 *AccountsChannelPartnerLinksPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ChannelPartnerLink, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ChannelPartnerLink{
		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", "cloudchannel.accounts.channelPartnerLinks.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall struct {
	s                                                 *Service
	parent                                            string
	googlecloudchannelv1channelpartnerrepricingconfig *GoogleCloudChannelV1ChannelPartnerRepricingConfig
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// Create: Creates a ChannelPartnerRepricingConfig. Call this method to set
// modifications for a specific ChannelPartner's bill. You can only create
// configs if the RepricingConfig.effective_invoice_month is a future month. If
// needed, you can create a config for the current month, with some
// restrictions. When creating a config for a future month, make sure there are
// no existing configs for that RepricingConfig.effective_invoice_month. The
// following restrictions are for creating configs in the current month. * This
// functionality is reserved for recovering from an erroneous config, and
// should not be used for regular business cases. * The new config will not
// modify exports used with other configs. Changes to the config may be
// immediate, but may take up to 24 hours. * There is a limit of ten configs
// for any ChannelPartner or
// RepricingConfig.EntitlementGranularity.entitlement, for any
// RepricingConfig.effective_invoice_month. * The contained
// ChannelPartnerRepricingConfig.repricing_config value must be different from
// the value used in the current config for a ChannelPartner. Possible Error
// Codes: * PERMISSION_DENIED: If the account making the request and the
// account being queried are different. * INVALID_ARGUMENT: Missing or invalid
// required parameters in the request. Also displays if the updated config is
// for the current month or past months. * NOT_FOUND: The
// ChannelPartnerRepricingConfig specified does not exist or is not associated
// with the given account. * INTERNAL: Any non-user error related to technical
// issues in the backend. In this case, contact Cloud Channel support. Return
// Value: If successful, the updated ChannelPartnerRepricingConfig resource,
// otherwise returns an error.
//
//   - parent: The resource name of the ChannelPartner that will receive the
//     repricing config. Parent uses the format:
//     accounts/{account_id}/channelPartnerLinks/{channel_partner_id}.
func (r *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService) Create(parent string, googlecloudchannelv1channelpartnerrepricingconfig *GoogleCloudChannelV1ChannelPartnerRepricingConfig) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall {
	c := &AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1channelpartnerrepricingconfig = googlecloudchannelv1channelpartnerrepricingconfig
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall) Context(ctx context.Context) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall {
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1channelpartnerrepricingconfig)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/channelPartnerRepricingConfigs")
	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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ChannelPartnerRepricingConfig.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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ChannelPartnerRepricingConfig, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ChannelPartnerRepricingConfig{
		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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes the given ChannelPartnerRepricingConfig permanently. You can
// only delete configs if their RepricingConfig.effective_invoice_month is set
// to a date after the current month. Possible error codes: *
// PERMISSION_DENIED: The account making the request does not own this
// customer. * INVALID_ARGUMENT: Required request parameters are missing or
// invalid. * FAILED_PRECONDITION: The ChannelPartnerRepricingConfig is active
// or in the past. * NOT_FOUND: No ChannelPartnerRepricingConfig found for the
// name in the request.
//
//   - name: The resource name of the channel partner repricing config rule to
//     delete.
func (r *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService) Delete(name string) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall {
	c := &AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall{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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall) Context(ctx context.Context) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall {
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall) 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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Gets information about how a Distributor modifies their bill before
// sending it to a ChannelPartner. Possible Error Codes: * PERMISSION_DENIED:
// If the account making the request and the account being queried are
// different. * NOT_FOUND: The ChannelPartnerRepricingConfig was not found. *
// INTERNAL: Any non-user error related to technical issues in the backend. In
// this case, contact Cloud Channel support. Return Value: If successful, the
// ChannelPartnerRepricingConfig resource, otherwise returns an error.
//
//   - name: The resource name of the ChannelPartnerRepricingConfig Format:
//     accounts/{account_id}/channelPartnerLinks/{channel_partner_id}/channelPartn
//     erRepricingConfigs/{id}.
func (r *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService) Get(name string) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall {
	c := &AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall{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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall {
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall) IfNoneMatch(entityTag string) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall) Context(ctx context.Context) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall {
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall) 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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ChannelPartnerRepricingConfig.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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ChannelPartnerRepricingConfig, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ChannelPartnerRepricingConfig{
		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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists information about how a Reseller modifies their bill before
// sending it to a ChannelPartner. Possible Error Codes: * PERMISSION_DENIED:
// If the account making the request and the account being queried are
// different. * NOT_FOUND: The ChannelPartnerRepricingConfig specified does not
// exist or is not associated with the given account. * INTERNAL: Any non-user
// error related to technical issues in the backend. In this case, contact
// Cloud Channel support. Return Value: If successful, the
// ChannelPartnerRepricingConfig resources. The data for each resource is
// displayed in the ascending order of: * Channel Partner ID *
// RepricingConfig.effective_invoice_month *
// ChannelPartnerRepricingConfig.update_time If unsuccessful, returns an error.
//
//   - parent: The resource name of the account's ChannelPartnerLink. Parent uses
//     the format:
//     accounts/{account_id}/channelPartnerLinks/{channel_partner_id}. Supports
//     accounts/{account_id}/channelPartnerLinks/- to retrieve configs for all
//     channel partners.
func (r *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService) List(parent string) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall {
	c := &AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": A filter for
// [CloudChannelService.ListChannelPartnerRepricingConfigs] results
// (channel_partner_link only). You can use this filter when you support a
// BatchGet-like query. To use the filter, you must set
// `parent=accounts/{account_id}/channelPartnerLinks/-`. Example:
// `channel_partner_link = accounts/account_id/channelPartnerLinks/c1` OR
// `channel_partner_link = accounts/account_id/channelPartnerLinks/c2`.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) Filter(filter string) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// repricing configs to return. The service may return fewer than this value.
// If unspecified, returns a maximum of 50 rules. The maximum value is 100;
// values above 100 will be coerced to 100.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) PageSize(pageSize int64) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token identifying a
// page of results beyond the first page. Obtained through
// ListChannelPartnerRepricingConfigsResponse.next_page_token of the previous
// CloudChannelService.ListChannelPartnerRepricingConfigs call.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) PageToken(pageToken string) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall {
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall {
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) IfNoneMatch(entityTag string) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) Context(ctx context.Context) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall {
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) 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}/channelPartnerRepricingConfigs")
	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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListChannelPartnerRepricingConfigsResponse.ServerRespons
// e.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListChannelPartnerRepricingConfigsResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListChannelPartnerRepricingConfigsResponse{
		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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListChannelPartnerRepricingConfigsResponse) 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 AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall struct {
	s                                                 *Service
	name                                              string
	googlecloudchannelv1channelpartnerrepricingconfig *GoogleCloudChannelV1ChannelPartnerRepricingConfig
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// Patch: Updates a ChannelPartnerRepricingConfig. Call this method to set
// modifications for a specific ChannelPartner's bill. This method overwrites
// the existing CustomerRepricingConfig. You can only update configs if the
// RepricingConfig.effective_invoice_month is a future month. To make changes
// to configs for the current month, use CreateChannelPartnerRepricingConfig,
// taking note of its restrictions. You cannot update the
// RepricingConfig.effective_invoice_month. When updating a config in the
// future: * This config must already exist. Possible Error Codes: *
// PERMISSION_DENIED: If the account making the request and the account being
// queried are different. * INVALID_ARGUMENT: Missing or invalid required
// parameters in the request. Also displays if the updated config is for the
// current month or past months. * NOT_FOUND: The ChannelPartnerRepricingConfig
// specified does not exist or is not associated with the given account. *
// INTERNAL: Any non-user error related to technical issues in the backend. In
// this case, contact Cloud Channel support. Return Value: If successful, the
// updated ChannelPartnerRepricingConfig resource, otherwise returns an error.
//
//   - name: Output only. Resource name of the ChannelPartnerRepricingConfig.
//     Format:
//     accounts/{account_id}/channelPartnerLinks/{channel_partner_id}/channelPartn
//     erRepricingConfigs/{id}.
func (r *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsService) Patch(name string, googlecloudchannelv1channelpartnerrepricingconfig *GoogleCloudChannelV1ChannelPartnerRepricingConfig) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall {
	c := &AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1channelpartnerrepricingconfig = googlecloudchannelv1channelpartnerrepricingconfig
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall) Context(ctx context.Context) *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall {
	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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1channelpartnerrepricingconfig)
	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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ChannelPartnerRepricingConfig.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 *AccountsChannelPartnerLinksChannelPartnerRepricingConfigsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ChannelPartnerRepricingConfig, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ChannelPartnerRepricingConfig{
		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", "cloudchannel.accounts.channelPartnerLinks.channelPartnerRepricingConfigs.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsChannelPartnerLinksCustomersCreateCall struct {
	s                            *Service
	parent                       string
	googlecloudchannelv1customer *GoogleCloudChannelV1Customer
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Create: Creates a new Customer resource under the reseller or distributor
// account. Possible error codes: * PERMISSION_DENIED: * The reseller account
// making the request is different from the reseller account in the API
// request. * You are not authorized to create a customer. See
// https://support.google.com/channelservices/answer/9759265 *
// INVALID_ARGUMENT: * Required request parameters are missing or invalid. *
// Domain field value doesn't match the primary email domain. Return value: The
// newly created Customer resource.
//
//   - parent: The resource name of reseller account in which to create the
//     customer. Parent uses the format: accounts/{account_id}.
func (r *AccountsChannelPartnerLinksCustomersService) Create(parent string, googlecloudchannelv1customer *GoogleCloudChannelV1Customer) *AccountsChannelPartnerLinksCustomersCreateCall {
	c := &AccountsChannelPartnerLinksCustomersCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1customer = googlecloudchannelv1customer
	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 *AccountsChannelPartnerLinksCustomersCreateCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksCustomersCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksCustomersCreateCall) Context(ctx context.Context) *AccountsChannelPartnerLinksCustomersCreateCall {
	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 *AccountsChannelPartnerLinksCustomersCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksCustomersCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1customer)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/customers")
	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", "cloudchannel.accounts.channelPartnerLinks.customers.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.customers.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Customer.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 *AccountsChannelPartnerLinksCustomersCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Customer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Customer{
		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", "cloudchannel.accounts.channelPartnerLinks.customers.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes the given Customer permanently. Possible error codes: *
// PERMISSION_DENIED: The account making the request does not own this
// customer. * INVALID_ARGUMENT: Required request parameters are missing or
// invalid. * FAILED_PRECONDITION: The customer has existing entitlements. *
// NOT_FOUND: No Customer resource found for the name in the request.
//
// - name: The resource name of the customer to delete.
func (r *AccountsChannelPartnerLinksCustomersService) Delete(name string) *AccountsChannelPartnerLinksCustomersDeleteCall {
	c := &AccountsChannelPartnerLinksCustomersDeleteCall{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 *AccountsChannelPartnerLinksCustomersDeleteCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksCustomersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksCustomersDeleteCall) Context(ctx context.Context) *AccountsChannelPartnerLinksCustomersDeleteCall {
	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 *AccountsChannelPartnerLinksCustomersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksCustomersDeleteCall) 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", "cloudchannel.accounts.channelPartnerLinks.customers.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.customers.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *AccountsChannelPartnerLinksCustomersDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "cloudchannel.accounts.channelPartnerLinks.customers.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Returns the requested Customer resource. Possible error codes: *
// PERMISSION_DENIED: The reseller account making the request is different from
// the reseller account in the API request. * INVALID_ARGUMENT: Required
// request parameters are missing or invalid. * NOT_FOUND: The customer
// resource doesn't exist. Usually the result of an invalid name parameter.
// Return value: The Customer resource.
//
//   - name: The resource name of the customer to retrieve. Name uses the format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsChannelPartnerLinksCustomersService) Get(name string) *AccountsChannelPartnerLinksCustomersGetCall {
	c := &AccountsChannelPartnerLinksCustomersGetCall{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 *AccountsChannelPartnerLinksCustomersGetCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksCustomersGetCall {
	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 *AccountsChannelPartnerLinksCustomersGetCall) IfNoneMatch(entityTag string) *AccountsChannelPartnerLinksCustomersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksCustomersGetCall) Context(ctx context.Context) *AccountsChannelPartnerLinksCustomersGetCall {
	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 *AccountsChannelPartnerLinksCustomersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksCustomersGetCall) 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", "cloudchannel.accounts.channelPartnerLinks.customers.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.customers.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Customer.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 *AccountsChannelPartnerLinksCustomersGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Customer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Customer{
		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", "cloudchannel.accounts.channelPartnerLinks.customers.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsChannelPartnerLinksCustomersImportCall struct {
	s                                         *Service
	parent                                    string
	googlecloudchannelv1importcustomerrequest *GoogleCloudChannelV1ImportCustomerRequest
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// Import: Imports a Customer from the Cloud Identity associated with the
// provided Cloud Identity ID or domain before a TransferEntitlements call. If
// a linked Customer already exists and overwrite_if_exists is true, it will
// update that Customer's data. Possible error codes: * PERMISSION_DENIED: *
// The reseller account making the request is different from the reseller
// account in the API request. * You are not authorized to import the customer.
// See https://support.google.com/channelservices/answer/9759265 * NOT_FOUND:
// Cloud Identity doesn't exist or was deleted. * INVALID_ARGUMENT: Required
// parameters are missing, or the auth_token is expired or invalid. *
// ALREADY_EXISTS: A customer already exists and has conflicting critical
// fields. Requires an overwrite. Return value: The Customer.
//
//   - parent: The resource name of the reseller's account. Parent takes the
//     format: accounts/{account_id} or
//     accounts/{account_id}/channelPartnerLinks/{channel_partner_id}.
func (r *AccountsChannelPartnerLinksCustomersService) Import(parent string, googlecloudchannelv1importcustomerrequest *GoogleCloudChannelV1ImportCustomerRequest) *AccountsChannelPartnerLinksCustomersImportCall {
	c := &AccountsChannelPartnerLinksCustomersImportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1importcustomerrequest = googlecloudchannelv1importcustomerrequest
	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 *AccountsChannelPartnerLinksCustomersImportCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksCustomersImportCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksCustomersImportCall) Context(ctx context.Context) *AccountsChannelPartnerLinksCustomersImportCall {
	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 *AccountsChannelPartnerLinksCustomersImportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksCustomersImportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1importcustomerrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/customers: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", "cloudchannel.accounts.channelPartnerLinks.customers.import", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.customers.import" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Customer.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 *AccountsChannelPartnerLinksCustomersImportCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Customer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Customer{
		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", "cloudchannel.accounts.channelPartnerLinks.customers.import", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: List Customers. Possible error codes: * PERMISSION_DENIED: The
// reseller account making the request is different from the reseller account
// in the API request. * INVALID_ARGUMENT: Required request parameters are
// missing or invalid. Return value: List of Customers, or an empty list if
// there are no customers.
//
//   - parent: The resource name of the reseller account to list customers from.
//     Parent uses the format: accounts/{account_id}.
func (r *AccountsChannelPartnerLinksCustomersService) List(parent string) *AccountsChannelPartnerLinksCustomersListCall {
	c := &AccountsChannelPartnerLinksCustomersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filters applied to the
// [CloudChannelService.ListCustomers] results. See
// https://cloud.google.com/channel/docs/concepts/google-cloud/filter-customers
// for more information.
func (c *AccountsChannelPartnerLinksCustomersListCall) Filter(filter string) *AccountsChannelPartnerLinksCustomersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

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

// PageToken sets the optional parameter "pageToken": A token identifying a
// page of results other than the first page. Obtained through
// ListCustomersResponse.next_page_token of the previous
// CloudChannelService.ListCustomers call.
func (c *AccountsChannelPartnerLinksCustomersListCall) PageToken(pageToken string) *AccountsChannelPartnerLinksCustomersListCall {
	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 *AccountsChannelPartnerLinksCustomersListCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksCustomersListCall {
	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 *AccountsChannelPartnerLinksCustomersListCall) IfNoneMatch(entityTag string) *AccountsChannelPartnerLinksCustomersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksCustomersListCall) Context(ctx context.Context) *AccountsChannelPartnerLinksCustomersListCall {
	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 *AccountsChannelPartnerLinksCustomersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksCustomersListCall) 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}/customers")
	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", "cloudchannel.accounts.channelPartnerLinks.customers.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.customers.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListCustomersResponse.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 *AccountsChannelPartnerLinksCustomersListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListCustomersResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListCustomersResponse{
		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", "cloudchannel.accounts.channelPartnerLinks.customers.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 *AccountsChannelPartnerLinksCustomersListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListCustomersResponse) 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 AccountsChannelPartnerLinksCustomersPatchCall struct {
	s                            *Service
	name                         string
	googlecloudchannelv1customer *GoogleCloudChannelV1Customer
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Patch: Updates an existing Customer resource for the reseller or
// distributor. Possible error codes: * PERMISSION_DENIED: The reseller account
// making the request is different from the reseller account in the API
// request. * INVALID_ARGUMENT: Required request parameters are missing or
// invalid. * NOT_FOUND: No Customer resource found for the name in the
// request. Return value: The updated Customer resource.
//
//   - name: Output only. Resource name of the customer. Format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsChannelPartnerLinksCustomersService) Patch(name string, googlecloudchannelv1customer *GoogleCloudChannelV1Customer) *AccountsChannelPartnerLinksCustomersPatchCall {
	c := &AccountsChannelPartnerLinksCustomersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1customer = googlecloudchannelv1customer
	return c
}

// UpdateMask sets the optional parameter "updateMask": The update mask that
// applies to the resource.
func (c *AccountsChannelPartnerLinksCustomersPatchCall) UpdateMask(updateMask string) *AccountsChannelPartnerLinksCustomersPatchCall {
	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 *AccountsChannelPartnerLinksCustomersPatchCall) Fields(s ...googleapi.Field) *AccountsChannelPartnerLinksCustomersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsChannelPartnerLinksCustomersPatchCall) Context(ctx context.Context) *AccountsChannelPartnerLinksCustomersPatchCall {
	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 *AccountsChannelPartnerLinksCustomersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsChannelPartnerLinksCustomersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1customer)
	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", "cloudchannel.accounts.channelPartnerLinks.customers.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.channelPartnerLinks.customers.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Customer.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 *AccountsChannelPartnerLinksCustomersPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Customer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Customer{
		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", "cloudchannel.accounts.channelPartnerLinks.customers.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsCustomersCreateCall struct {
	s                            *Service
	parent                       string
	googlecloudchannelv1customer *GoogleCloudChannelV1Customer
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Create: Creates a new Customer resource under the reseller or distributor
// account. Possible error codes: * PERMISSION_DENIED: * The reseller account
// making the request is different from the reseller account in the API
// request. * You are not authorized to create a customer. See
// https://support.google.com/channelservices/answer/9759265 *
// INVALID_ARGUMENT: * Required request parameters are missing or invalid. *
// Domain field value doesn't match the primary email domain. Return value: The
// newly created Customer resource.
//
//   - parent: The resource name of reseller account in which to create the
//     customer. Parent uses the format: accounts/{account_id}.
func (r *AccountsCustomersService) Create(parent string, googlecloudchannelv1customer *GoogleCloudChannelV1Customer) *AccountsCustomersCreateCall {
	c := &AccountsCustomersCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1customer = googlecloudchannelv1customer
	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 *AccountsCustomersCreateCall) Fields(s ...googleapi.Field) *AccountsCustomersCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersCreateCall) Context(ctx context.Context) *AccountsCustomersCreateCall {
	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 *AccountsCustomersCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1customer)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/customers")
	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", "cloudchannel.accounts.customers.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Customer.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 *AccountsCustomersCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Customer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Customer{
		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", "cloudchannel.accounts.customers.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes the given Customer permanently. Possible error codes: *
// PERMISSION_DENIED: The account making the request does not own this
// customer. * INVALID_ARGUMENT: Required request parameters are missing or
// invalid. * FAILED_PRECONDITION: The customer has existing entitlements. *
// NOT_FOUND: No Customer resource found for the name in the request.
//
// - name: The resource name of the customer to delete.
func (r *AccountsCustomersService) Delete(name string) *AccountsCustomersDeleteCall {
	c := &AccountsCustomersDeleteCall{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 *AccountsCustomersDeleteCall) Fields(s ...googleapi.Field) *AccountsCustomersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersDeleteCall) Context(ctx context.Context) *AccountsCustomersDeleteCall {
	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 *AccountsCustomersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersDeleteCall) 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", "cloudchannel.accounts.customers.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *AccountsCustomersDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "cloudchannel.accounts.customers.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Returns the requested Customer resource. Possible error codes: *
// PERMISSION_DENIED: The reseller account making the request is different from
// the reseller account in the API request. * INVALID_ARGUMENT: Required
// request parameters are missing or invalid. * NOT_FOUND: The customer
// resource doesn't exist. Usually the result of an invalid name parameter.
// Return value: The Customer resource.
//
//   - name: The resource name of the customer to retrieve. Name uses the format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersService) Get(name string) *AccountsCustomersGetCall {
	c := &AccountsCustomersGetCall{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 *AccountsCustomersGetCall) Fields(s ...googleapi.Field) *AccountsCustomersGetCall {
	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 *AccountsCustomersGetCall) IfNoneMatch(entityTag string) *AccountsCustomersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersGetCall) Context(ctx context.Context) *AccountsCustomersGetCall {
	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 *AccountsCustomersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersGetCall) 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", "cloudchannel.accounts.customers.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Customer.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 *AccountsCustomersGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Customer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Customer{
		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", "cloudchannel.accounts.customers.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsCustomersImportCall struct {
	s                                         *Service
	parent                                    string
	googlecloudchannelv1importcustomerrequest *GoogleCloudChannelV1ImportCustomerRequest
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// Import: Imports a Customer from the Cloud Identity associated with the
// provided Cloud Identity ID or domain before a TransferEntitlements call. If
// a linked Customer already exists and overwrite_if_exists is true, it will
// update that Customer's data. Possible error codes: * PERMISSION_DENIED: *
// The reseller account making the request is different from the reseller
// account in the API request. * You are not authorized to import the customer.
// See https://support.google.com/channelservices/answer/9759265 * NOT_FOUND:
// Cloud Identity doesn't exist or was deleted. * INVALID_ARGUMENT: Required
// parameters are missing, or the auth_token is expired or invalid. *
// ALREADY_EXISTS: A customer already exists and has conflicting critical
// fields. Requires an overwrite. Return value: The Customer.
//
//   - parent: The resource name of the reseller's account. Parent takes the
//     format: accounts/{account_id} or
//     accounts/{account_id}/channelPartnerLinks/{channel_partner_id}.
func (r *AccountsCustomersService) Import(parent string, googlecloudchannelv1importcustomerrequest *GoogleCloudChannelV1ImportCustomerRequest) *AccountsCustomersImportCall {
	c := &AccountsCustomersImportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1importcustomerrequest = googlecloudchannelv1importcustomerrequest
	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 *AccountsCustomersImportCall) Fields(s ...googleapi.Field) *AccountsCustomersImportCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersImportCall) Context(ctx context.Context) *AccountsCustomersImportCall {
	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 *AccountsCustomersImportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersImportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1importcustomerrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/customers: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", "cloudchannel.accounts.customers.import", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.import" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Customer.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 *AccountsCustomersImportCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Customer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Customer{
		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", "cloudchannel.accounts.customers.import", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: List Customers. Possible error codes: * PERMISSION_DENIED: The
// reseller account making the request is different from the reseller account
// in the API request. * INVALID_ARGUMENT: Required request parameters are
// missing or invalid. Return value: List of Customers, or an empty list if
// there are no customers.
//
//   - parent: The resource name of the reseller account to list customers from.
//     Parent uses the format: accounts/{account_id}.
func (r *AccountsCustomersService) List(parent string) *AccountsCustomersListCall {
	c := &AccountsCustomersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filters applied to the
// [CloudChannelService.ListCustomers] results. See
// https://cloud.google.com/channel/docs/concepts/google-cloud/filter-customers
// for more information.
func (c *AccountsCustomersListCall) Filter(filter string) *AccountsCustomersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

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

// PageToken sets the optional parameter "pageToken": A token identifying a
// page of results other than the first page. Obtained through
// ListCustomersResponse.next_page_token of the previous
// CloudChannelService.ListCustomers call.
func (c *AccountsCustomersListCall) PageToken(pageToken string) *AccountsCustomersListCall {
	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 *AccountsCustomersListCall) Fields(s ...googleapi.Field) *AccountsCustomersListCall {
	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 *AccountsCustomersListCall) IfNoneMatch(entityTag string) *AccountsCustomersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersListCall) Context(ctx context.Context) *AccountsCustomersListCall {
	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 *AccountsCustomersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersListCall) 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}/customers")
	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", "cloudchannel.accounts.customers.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListCustomersResponse.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 *AccountsCustomersListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListCustomersResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListCustomersResponse{
		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", "cloudchannel.accounts.customers.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 *AccountsCustomersListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListCustomersResponse) 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 AccountsCustomersListPurchasableOffersCall struct {
	s            *Service
	customer     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListPurchasableOffers: Lists the following: * Offers that you can purchase
// for a customer. * Offers that you can change for an entitlement. Possible
// error codes: * PERMISSION_DENIED: * The customer doesn't belong to the
// reseller * The reseller is not authorized to transact on this Product. See
// https://support.google.com/channelservices/answer/9759265 *
// INVALID_ARGUMENT: Required request parameters are missing or invalid.
//
//   - customer: The resource name of the customer to list Offers for. Format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersService) ListPurchasableOffers(customer string) *AccountsCustomersListPurchasableOffersCall {
	c := &AccountsCustomersListPurchasableOffersCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customer = customer
	return c
}

// ChangeOfferPurchaseBillingAccount sets the optional parameter
// "changeOfferPurchase.billingAccount": Resource name of the new target
// Billing Account. Provide this Billing Account when setting up billing for a
// trial subscription. Format:
// accounts/{account_id}/billingAccounts/{billing_account_id}. This field is
// only relevant for multi-currency accounts. It should be left empty for
// single currency accounts.
func (c *AccountsCustomersListPurchasableOffersCall) ChangeOfferPurchaseBillingAccount(changeOfferPurchaseBillingAccount string) *AccountsCustomersListPurchasableOffersCall {
	c.urlParams_.Set("changeOfferPurchase.billingAccount", changeOfferPurchaseBillingAccount)
	return c
}

// ChangeOfferPurchaseEntitlement sets the optional parameter
// "changeOfferPurchase.entitlement": Required. Resource name of the
// entitlement. Format:
// accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}
func (c *AccountsCustomersListPurchasableOffersCall) ChangeOfferPurchaseEntitlement(changeOfferPurchaseEntitlement string) *AccountsCustomersListPurchasableOffersCall {
	c.urlParams_.Set("changeOfferPurchase.entitlement", changeOfferPurchaseEntitlement)
	return c
}

// ChangeOfferPurchaseNewSku sets the optional parameter
// "changeOfferPurchase.newSku": Resource name of the new target SKU. Provide
// this SKU when upgrading or downgrading an entitlement. Format:
// products/{product_id}/skus/{sku_id}
func (c *AccountsCustomersListPurchasableOffersCall) ChangeOfferPurchaseNewSku(changeOfferPurchaseNewSku string) *AccountsCustomersListPurchasableOffersCall {
	c.urlParams_.Set("changeOfferPurchase.newSku", changeOfferPurchaseNewSku)
	return c
}

// CreateEntitlementPurchaseBillingAccount sets the optional parameter
// "createEntitlementPurchase.billingAccount": Billing account that the result
// should be restricted to. Format:
// accounts/{account_id}/billingAccounts/{billing_account_id}.
func (c *AccountsCustomersListPurchasableOffersCall) CreateEntitlementPurchaseBillingAccount(createEntitlementPurchaseBillingAccount string) *AccountsCustomersListPurchasableOffersCall {
	c.urlParams_.Set("createEntitlementPurchase.billingAccount", createEntitlementPurchaseBillingAccount)
	return c
}

// CreateEntitlementPurchaseSku sets the optional parameter
// "createEntitlementPurchase.sku": Required. SKU that the result should be
// restricted to. Format: products/{product_id}/skus/{sku_id}.
func (c *AccountsCustomersListPurchasableOffersCall) CreateEntitlementPurchaseSku(createEntitlementPurchaseSku string) *AccountsCustomersListPurchasableOffersCall {
	c.urlParams_.Set("createEntitlementPurchase.sku", createEntitlementPurchaseSku)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47 language
// code. For example, "en-US". The response will localize in the corresponding
// language code, if specified. The default value is "en-US".
func (c *AccountsCustomersListPurchasableOffersCall) LanguageCode(languageCode string) *AccountsCustomersListPurchasableOffersCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size. Server
// might return fewer results than requested. If unspecified, returns at most
// 100 Offers. The maximum value is 1000; the server will coerce values above
// 1000.
func (c *AccountsCustomersListPurchasableOffersCall) PageSize(pageSize int64) *AccountsCustomersListPurchasableOffersCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token for a page of
// results other than the first page.
func (c *AccountsCustomersListPurchasableOffersCall) PageToken(pageToken string) *AccountsCustomersListPurchasableOffersCall {
	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 *AccountsCustomersListPurchasableOffersCall) Fields(s ...googleapi.Field) *AccountsCustomersListPurchasableOffersCall {
	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 *AccountsCustomersListPurchasableOffersCall) IfNoneMatch(entityTag string) *AccountsCustomersListPurchasableOffersCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersListPurchasableOffersCall) Context(ctx context.Context) *AccountsCustomersListPurchasableOffersCall {
	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 *AccountsCustomersListPurchasableOffersCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersListPurchasableOffersCall) 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/{+customer}:listPurchasableOffers")
	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{
		"customer": c.customer,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "cloudchannel.accounts.customers.listPurchasableOffers", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.listPurchasableOffers" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListPurchasableOffersResponse.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 *AccountsCustomersListPurchasableOffersCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListPurchasableOffersResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListPurchasableOffersResponse{
		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", "cloudchannel.accounts.customers.listPurchasableOffers", "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 *AccountsCustomersListPurchasableOffersCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListPurchasableOffersResponse) 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 AccountsCustomersListPurchasableSkusCall struct {
	s            *Service
	customer     string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListPurchasableSkus: Lists the following: * SKUs that you can purchase for a
// customer * SKUs that you can upgrade or downgrade for an entitlement.
// Possible error codes: * PERMISSION_DENIED: The customer doesn't belong to
// the reseller. * INVALID_ARGUMENT: Required request parameters are missing or
// invalid.
//
//   - customer: The resource name of the customer to list SKUs for. Format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersService) ListPurchasableSkus(customer string) *AccountsCustomersListPurchasableSkusCall {
	c := &AccountsCustomersListPurchasableSkusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customer = customer
	return c
}

// ChangeOfferPurchaseChangeType sets the optional parameter
// "changeOfferPurchase.changeType": Required. Change Type for the entitlement.
//
// Possible values:
//
//	"CHANGE_TYPE_UNSPECIFIED" - Not used.
//	"UPGRADE" - SKU is an upgrade on the current entitlement.
//	"DOWNGRADE" - SKU is a downgrade on the current entitlement.
func (c *AccountsCustomersListPurchasableSkusCall) ChangeOfferPurchaseChangeType(changeOfferPurchaseChangeType string) *AccountsCustomersListPurchasableSkusCall {
	c.urlParams_.Set("changeOfferPurchase.changeType", changeOfferPurchaseChangeType)
	return c
}

// ChangeOfferPurchaseEntitlement sets the optional parameter
// "changeOfferPurchase.entitlement": Required. Resource name of the
// entitlement. Format:
// accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}
func (c *AccountsCustomersListPurchasableSkusCall) ChangeOfferPurchaseEntitlement(changeOfferPurchaseEntitlement string) *AccountsCustomersListPurchasableSkusCall {
	c.urlParams_.Set("changeOfferPurchase.entitlement", changeOfferPurchaseEntitlement)
	return c
}

// CreateEntitlementPurchaseProduct sets the optional parameter
// "createEntitlementPurchase.product": Required. List SKUs belonging to this
// Product. Format: products/{product_id}. Supports products/- to retrieve SKUs
// for all products.
func (c *AccountsCustomersListPurchasableSkusCall) CreateEntitlementPurchaseProduct(createEntitlementPurchaseProduct string) *AccountsCustomersListPurchasableSkusCall {
	c.urlParams_.Set("createEntitlementPurchase.product", createEntitlementPurchaseProduct)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47 language
// code. For example, "en-US". The response will localize in the corresponding
// language code, if specified. The default value is "en-US".
func (c *AccountsCustomersListPurchasableSkusCall) LanguageCode(languageCode string) *AccountsCustomersListPurchasableSkusCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size. Server
// might return fewer results than requested. If unspecified, returns at most
// 100 SKUs. The maximum value is 1000; the server will coerce values above
// 1000.
func (c *AccountsCustomersListPurchasableSkusCall) PageSize(pageSize int64) *AccountsCustomersListPurchasableSkusCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token for a page of
// results other than the first page.
func (c *AccountsCustomersListPurchasableSkusCall) PageToken(pageToken string) *AccountsCustomersListPurchasableSkusCall {
	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 *AccountsCustomersListPurchasableSkusCall) Fields(s ...googleapi.Field) *AccountsCustomersListPurchasableSkusCall {
	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 *AccountsCustomersListPurchasableSkusCall) IfNoneMatch(entityTag string) *AccountsCustomersListPurchasableSkusCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersListPurchasableSkusCall) Context(ctx context.Context) *AccountsCustomersListPurchasableSkusCall {
	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 *AccountsCustomersListPurchasableSkusCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersListPurchasableSkusCall) 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/{+customer}:listPurchasableSkus")
	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{
		"customer": c.customer,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "cloudchannel.accounts.customers.listPurchasableSkus", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.listPurchasableSkus" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListPurchasableSkusResponse.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 *AccountsCustomersListPurchasableSkusCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListPurchasableSkusResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListPurchasableSkusResponse{
		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", "cloudchannel.accounts.customers.listPurchasableSkus", "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 *AccountsCustomersListPurchasableSkusCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListPurchasableSkusResponse) 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 AccountsCustomersPatchCall struct {
	s                            *Service
	name                         string
	googlecloudchannelv1customer *GoogleCloudChannelV1Customer
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Patch: Updates an existing Customer resource for the reseller or
// distributor. Possible error codes: * PERMISSION_DENIED: The reseller account
// making the request is different from the reseller account in the API
// request. * INVALID_ARGUMENT: Required request parameters are missing or
// invalid. * NOT_FOUND: No Customer resource found for the name in the
// request. Return value: The updated Customer resource.
//
//   - name: Output only. Resource name of the customer. Format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersService) Patch(name string, googlecloudchannelv1customer *GoogleCloudChannelV1Customer) *AccountsCustomersPatchCall {
	c := &AccountsCustomersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1customer = googlecloudchannelv1customer
	return c
}

// UpdateMask sets the optional parameter "updateMask": The update mask that
// applies to the resource.
func (c *AccountsCustomersPatchCall) UpdateMask(updateMask string) *AccountsCustomersPatchCall {
	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 *AccountsCustomersPatchCall) Fields(s ...googleapi.Field) *AccountsCustomersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersPatchCall) Context(ctx context.Context) *AccountsCustomersPatchCall {
	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 *AccountsCustomersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1customer)
	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", "cloudchannel.accounts.customers.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Customer.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 *AccountsCustomersPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Customer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Customer{
		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", "cloudchannel.accounts.customers.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsCustomersProvisionCloudIdentityCall struct {
	s                                                 *Service
	customer                                          string
	googlecloudchannelv1provisioncloudidentityrequest *GoogleCloudChannelV1ProvisionCloudIdentityRequest
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// ProvisionCloudIdentity: Creates a Cloud Identity for the given customer
// using the customer's information, or the information provided here. Possible
// error codes: * PERMISSION_DENIED: * The customer doesn't belong to the
// reseller. * You are not authorized to provision cloud identity id. See
// https://support.google.com/channelservices/answer/9759265 *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. *
// NOT_FOUND: The customer was not found. * ALREADY_EXISTS: The customer's
// primary email already exists. Retry after changing the customer's primary
// contact email. * INTERNAL: Any non-user error related to a technical issue
// in the backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The ID of a long-running operation. To get the results of the
// operation, call the GetOperation method of CloudChannelOperationsService.
// The Operation metadata contains an instance of OperationMetadata.
//
//   - customer: Resource name of the customer. Format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersService) ProvisionCloudIdentity(customer string, googlecloudchannelv1provisioncloudidentityrequest *GoogleCloudChannelV1ProvisionCloudIdentityRequest) *AccountsCustomersProvisionCloudIdentityCall {
	c := &AccountsCustomersProvisionCloudIdentityCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customer = customer
	c.googlecloudchannelv1provisioncloudidentityrequest = googlecloudchannelv1provisioncloudidentityrequest
	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 *AccountsCustomersProvisionCloudIdentityCall) Fields(s ...googleapi.Field) *AccountsCustomersProvisionCloudIdentityCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersProvisionCloudIdentityCall) Context(ctx context.Context) *AccountsCustomersProvisionCloudIdentityCall {
	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 *AccountsCustomersProvisionCloudIdentityCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "cloudchannel.accounts.customers.provisionCloudIdentity" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersProvisionCloudIdentityCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.provisionCloudIdentity", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// QueryEligibleBillingAccounts: Lists the billing accounts that are eligible
// to purchase particular SKUs for a given customer. Possible error codes: *
// PERMISSION_DENIED: The customer doesn't belong to the reseller. *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. Return
// value: Based on the provided list of SKUs, returns a list of SKU groups that
// must be purchased using the same billing account and the billing accounts
// eligible to purchase each SKU group.
//
//   - customer: The resource name of the customer to list eligible billing
//     accounts for. Format: accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersService) QueryEligibleBillingAccounts(customer string) *AccountsCustomersQueryEligibleBillingAccountsCall {
	c := &AccountsCustomersQueryEligibleBillingAccountsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customer = customer
	return c
}

// Skus sets the optional parameter "skus": Required. List of SKUs to list
// eligible billing accounts for. At least one SKU is required. Format:
// products/{product_id}/skus/{sku_id}.
func (c *AccountsCustomersQueryEligibleBillingAccountsCall) Skus(skus ...string) *AccountsCustomersQueryEligibleBillingAccountsCall {
	c.urlParams_.SetMulti("skus", append([]string{}, skus...))
	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 *AccountsCustomersQueryEligibleBillingAccountsCall) Fields(s ...googleapi.Field) *AccountsCustomersQueryEligibleBillingAccountsCall {
	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 *AccountsCustomersQueryEligibleBillingAccountsCall) IfNoneMatch(entityTag string) *AccountsCustomersQueryEligibleBillingAccountsCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersQueryEligibleBillingAccountsCall) Context(ctx context.Context) *AccountsCustomersQueryEligibleBillingAccountsCall {
	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 *AccountsCustomersQueryEligibleBillingAccountsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersQueryEligibleBillingAccountsCall) 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/{+customer}:queryEligibleBillingAccounts")
	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{
		"customer": c.customer,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "cloudchannel.accounts.customers.queryEligibleBillingAccounts", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.queryEligibleBillingAccounts" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1QueryEligibleBillingAccountsResponse.ServerResponse.Head
// er or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *AccountsCustomersQueryEligibleBillingAccountsCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1QueryEligibleBillingAccountsResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1QueryEligibleBillingAccountsResponse{
		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", "cloudchannel.accounts.customers.queryEligibleBillingAccounts", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsCustomersTransferEntitlementsCall struct {
	s                                               *Service
	parent                                          string
	googlecloudchannelv1transferentitlementsrequest *GoogleCloudChannelV1TransferEntitlementsRequest
	urlParams_                                      gensupport.URLParams
	ctx_                                            context.Context
	header_                                         http.Header
}

// TransferEntitlements: Transfers customer entitlements to new reseller.
// Possible error codes: * PERMISSION_DENIED: * The customer doesn't belong to
// the reseller. * The reseller is not authorized to transact on this Product.
// See https://support.google.com/channelservices/answer/9759265 *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. *
// NOT_FOUND: The customer or offer resource was not found. * ALREADY_EXISTS:
// The SKU was already transferred for the customer. * CONDITION_NOT_MET or
// FAILED_PRECONDITION: * The SKU requires domain verification to transfer, but
// the domain is not verified. * An Add-On SKU (example, Vault or Drive) is
// missing the pre-requisite SKU (example, G Suite Basic). * (Developer
// accounts only) Reseller and resold domain must meet the following naming
// requirements: * Domain names must start with goog-test. * Domain names must
// include the reseller domain. * Specify all transferring entitlements. *
// INTERNAL: Any non-user error related to a technical issue in the backend.
// Contact Cloud Channel support. * UNKNOWN: Any non-user error related to a
// technical issue in the backend. Contact Cloud Channel support. Return value:
// The ID of a long-running operation. To get the results of the operation,
// call the GetOperation method of CloudChannelOperationsService. The Operation
// metadata will contain an instance of OperationMetadata.
//
//   - parent: The resource name of the reseller's customer account that will
//     receive transferred entitlements. Parent uses the format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersService) TransferEntitlements(parent string, googlecloudchannelv1transferentitlementsrequest *GoogleCloudChannelV1TransferEntitlementsRequest) *AccountsCustomersTransferEntitlementsCall {
	c := &AccountsCustomersTransferEntitlementsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1transferentitlementsrequest = googlecloudchannelv1transferentitlementsrequest
	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 *AccountsCustomersTransferEntitlementsCall) Fields(s ...googleapi.Field) *AccountsCustomersTransferEntitlementsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersTransferEntitlementsCall) Context(ctx context.Context) *AccountsCustomersTransferEntitlementsCall {
	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 *AccountsCustomersTransferEntitlementsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersTransferEntitlementsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1transferentitlementsrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:transferEntitlements")
	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", "cloudchannel.accounts.customers.transferEntitlements", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.transferEntitlements" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersTransferEntitlementsCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.transferEntitlements", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsCustomersTransferEntitlementsToGoogleCall struct {
	s                                                       *Service
	parent                                                  string
	googlecloudchannelv1transferentitlementstogooglerequest *GoogleCloudChannelV1TransferEntitlementsToGoogleRequest
	urlParams_                                              gensupport.URLParams
	ctx_                                                    context.Context
	header_                                                 http.Header
}

// TransferEntitlementsToGoogle: Transfers customer entitlements from their
// current reseller to Google. Possible error codes: * PERMISSION_DENIED: The
// customer doesn't belong to the reseller. * INVALID_ARGUMENT: Required
// request parameters are missing or invalid. * NOT_FOUND: The customer or
// offer resource was not found. * ALREADY_EXISTS: The SKU was already
// transferred for the customer. * CONDITION_NOT_MET or FAILED_PRECONDITION: *
// The SKU requires domain verification to transfer, but the domain is not
// verified. * An Add-On SKU (example, Vault or Drive) is missing the
// pre-requisite SKU (example, G Suite Basic). * (Developer accounts only)
// Reseller and resold domain must meet the following naming requirements: *
// Domain names must start with goog-test. * Domain names must include the
// reseller domain. * INTERNAL: Any non-user error related to a technical issue
// in the backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The ID of a long-running operation. To get the results of the
// operation, call the GetOperation method of CloudChannelOperationsService.
// The response will contain google.protobuf.Empty on success. The Operation
// metadata will contain an instance of OperationMetadata.
//
//   - parent: The resource name of the reseller's customer account where the
//     entitlements transfer from. Parent uses the format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersService) TransferEntitlementsToGoogle(parent string, googlecloudchannelv1transferentitlementstogooglerequest *GoogleCloudChannelV1TransferEntitlementsToGoogleRequest) *AccountsCustomersTransferEntitlementsToGoogleCall {
	c := &AccountsCustomersTransferEntitlementsToGoogleCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1transferentitlementstogooglerequest = googlecloudchannelv1transferentitlementstogooglerequest
	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 *AccountsCustomersTransferEntitlementsToGoogleCall) Fields(s ...googleapi.Field) *AccountsCustomersTransferEntitlementsToGoogleCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersTransferEntitlementsToGoogleCall) Context(ctx context.Context) *AccountsCustomersTransferEntitlementsToGoogleCall {
	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 *AccountsCustomersTransferEntitlementsToGoogleCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersTransferEntitlementsToGoogleCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1transferentitlementstogooglerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}:transferEntitlementsToGoogle")
	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", "cloudchannel.accounts.customers.transferEntitlementsToGoogle", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.transferEntitlementsToGoogle" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersTransferEntitlementsToGoogleCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.transferEntitlementsToGoogle", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsCustomersCustomerRepricingConfigsCreateCall struct {
	s                                           *Service
	parent                                      string
	googlecloudchannelv1customerrepricingconfig *GoogleCloudChannelV1CustomerRepricingConfig
	urlParams_                                  gensupport.URLParams
	ctx_                                        context.Context
	header_                                     http.Header
}

// Create: Creates a CustomerRepricingConfig. Call this method to set
// modifications for a specific customer's bill. You can only create configs if
// the RepricingConfig.effective_invoice_month is a future month. If needed,
// you can create a config for the current month, with some restrictions. When
// creating a config for a future month, make sure there are no existing
// configs for that RepricingConfig.effective_invoice_month. The following
// restrictions are for creating configs in the current month. * This
// functionality is reserved for recovering from an erroneous config, and
// should not be used for regular business cases. * The new config will not
// modify exports used with other configs. Changes to the config may be
// immediate, but may take up to 24 hours. * There is a limit of ten configs
// for any RepricingConfig.EntitlementGranularity.entitlement, for any
// RepricingConfig.effective_invoice_month. * The contained
// CustomerRepricingConfig.repricing_config value must be different from the
// value used in the current config for a
// RepricingConfig.EntitlementGranularity.entitlement. Possible Error Codes: *
// PERMISSION_DENIED: If the account making the request and the account being
// queried are different. * INVALID_ARGUMENT: Missing or invalid required
// parameters in the request. Also displays if the updated config is for the
// current month or past months. * NOT_FOUND: The CustomerRepricingConfig
// specified does not exist or is not associated with the given account. *
// INTERNAL: Any non-user error related to technical issues in the backend. In
// this case, contact Cloud Channel support. Return Value: If successful, the
// updated CustomerRepricingConfig resource, otherwise returns an error.
//
//   - parent: The resource name of the customer that will receive this repricing
//     config. Parent uses the format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersCustomerRepricingConfigsService) Create(parent string, googlecloudchannelv1customerrepricingconfig *GoogleCloudChannelV1CustomerRepricingConfig) *AccountsCustomersCustomerRepricingConfigsCreateCall {
	c := &AccountsCustomersCustomerRepricingConfigsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1customerrepricingconfig = googlecloudchannelv1customerrepricingconfig
	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 *AccountsCustomersCustomerRepricingConfigsCreateCall) Fields(s ...googleapi.Field) *AccountsCustomersCustomerRepricingConfigsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersCustomerRepricingConfigsCreateCall) Context(ctx context.Context) *AccountsCustomersCustomerRepricingConfigsCreateCall {
	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 *AccountsCustomersCustomerRepricingConfigsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersCustomerRepricingConfigsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1customerrepricingconfig)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/customerRepricingConfigs")
	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", "cloudchannel.accounts.customers.customerRepricingConfigs.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.customerRepricingConfigs.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1CustomerRepricingConfig.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 *AccountsCustomersCustomerRepricingConfigsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1CustomerRepricingConfig, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1CustomerRepricingConfig{
		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", "cloudchannel.accounts.customers.customerRepricingConfigs.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Delete: Deletes the given CustomerRepricingConfig permanently. You can only
// delete configs if their RepricingConfig.effective_invoice_month is set to a
// date after the current month. Possible error codes: * PERMISSION_DENIED: The
// account making the request does not own this customer. * INVALID_ARGUMENT:
// Required request parameters are missing or invalid. * FAILED_PRECONDITION:
// The CustomerRepricingConfig is active or in the past. * NOT_FOUND: No
// CustomerRepricingConfig found for the name in the request.
//
//   - name: The resource name of the customer repricing config rule to delete.
//     Format:
//     accounts/{account_id}/customers/{customer_id}/customerRepricingConfigs/{id}
//     .
func (r *AccountsCustomersCustomerRepricingConfigsService) Delete(name string) *AccountsCustomersCustomerRepricingConfigsDeleteCall {
	c := &AccountsCustomersCustomerRepricingConfigsDeleteCall{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 *AccountsCustomersCustomerRepricingConfigsDeleteCall) Fields(s ...googleapi.Field) *AccountsCustomersCustomerRepricingConfigsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersCustomerRepricingConfigsDeleteCall) Context(ctx context.Context) *AccountsCustomersCustomerRepricingConfigsDeleteCall {
	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 *AccountsCustomersCustomerRepricingConfigsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersCustomerRepricingConfigsDeleteCall) 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", "cloudchannel.accounts.customers.customerRepricingConfigs.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.customerRepricingConfigs.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *AccountsCustomersCustomerRepricingConfigsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "cloudchannel.accounts.customers.customerRepricingConfigs.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Gets information about how a Reseller modifies their bill before
// sending it to a Customer. Possible Error Codes: * PERMISSION_DENIED: If the
// account making the request and the account being queried are different. *
// NOT_FOUND: The CustomerRepricingConfig was not found. * INTERNAL: Any
// non-user error related to technical issues in the backend. In this case,
// contact Cloud Channel support. Return Value: If successful, the
// CustomerRepricingConfig resource, otherwise returns an error.
//
//   - name: The resource name of the CustomerRepricingConfig. Format:
//     accounts/{account_id}/customers/{customer_id}/customerRepricingConfigs/{id}
//     .
func (r *AccountsCustomersCustomerRepricingConfigsService) Get(name string) *AccountsCustomersCustomerRepricingConfigsGetCall {
	c := &AccountsCustomersCustomerRepricingConfigsGetCall{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 *AccountsCustomersCustomerRepricingConfigsGetCall) Fields(s ...googleapi.Field) *AccountsCustomersCustomerRepricingConfigsGetCall {
	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 *AccountsCustomersCustomerRepricingConfigsGetCall) IfNoneMatch(entityTag string) *AccountsCustomersCustomerRepricingConfigsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersCustomerRepricingConfigsGetCall) Context(ctx context.Context) *AccountsCustomersCustomerRepricingConfigsGetCall {
	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 *AccountsCustomersCustomerRepricingConfigsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersCustomerRepricingConfigsGetCall) 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", "cloudchannel.accounts.customers.customerRepricingConfigs.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.customerRepricingConfigs.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1CustomerRepricingConfig.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 *AccountsCustomersCustomerRepricingConfigsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1CustomerRepricingConfig, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1CustomerRepricingConfig{
		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", "cloudchannel.accounts.customers.customerRepricingConfigs.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists information about how a Reseller modifies their bill before
// sending it to a Customer. Possible Error Codes: * PERMISSION_DENIED: If the
// account making the request and the account being queried are different. *
// NOT_FOUND: The CustomerRepricingConfig specified does not exist or is not
// associated with the given account. * INTERNAL: Any non-user error related to
// technical issues in the backend. In this case, contact Cloud Channel
// support. Return Value: If successful, the CustomerRepricingConfig resources.
// The data for each resource is displayed in the ascending order of: *
// Customer ID * RepricingConfig.EntitlementGranularity.entitlement *
// RepricingConfig.effective_invoice_month *
// CustomerRepricingConfig.update_time If unsuccessful, returns an error.
//
//   - parent: The resource name of the customer. Parent uses the format:
//     accounts/{account_id}/customers/{customer_id}. Supports
//     accounts/{account_id}/customers/- to retrieve configs for all customers.
func (r *AccountsCustomersCustomerRepricingConfigsService) List(parent string) *AccountsCustomersCustomerRepricingConfigsListCall {
	c := &AccountsCustomersCustomerRepricingConfigsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": A filter for
// [CloudChannelService.ListCustomerRepricingConfigs] results (customer only).
// You can use this filter when you support a BatchGet-like query. To use the
// filter, you must set `parent=accounts/{account_id}/customers/-`. Example:
// customer = accounts/account_id/customers/c1 OR customer =
// accounts/account_id/customers/c2.
func (c *AccountsCustomersCustomerRepricingConfigsListCall) Filter(filter string) *AccountsCustomersCustomerRepricingConfigsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// repricing configs to return. The service may return fewer than this value.
// If unspecified, returns a maximum of 50 rules. The maximum value is 100;
// values above 100 will be coerced to 100.
func (c *AccountsCustomersCustomerRepricingConfigsListCall) PageSize(pageSize int64) *AccountsCustomersCustomerRepricingConfigsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token identifying a
// page of results beyond the first page. Obtained through
// ListCustomerRepricingConfigsResponse.next_page_token of the previous
// CloudChannelService.ListCustomerRepricingConfigs call.
func (c *AccountsCustomersCustomerRepricingConfigsListCall) PageToken(pageToken string) *AccountsCustomersCustomerRepricingConfigsListCall {
	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 *AccountsCustomersCustomerRepricingConfigsListCall) Fields(s ...googleapi.Field) *AccountsCustomersCustomerRepricingConfigsListCall {
	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 *AccountsCustomersCustomerRepricingConfigsListCall) IfNoneMatch(entityTag string) *AccountsCustomersCustomerRepricingConfigsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersCustomerRepricingConfigsListCall) Context(ctx context.Context) *AccountsCustomersCustomerRepricingConfigsListCall {
	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 *AccountsCustomersCustomerRepricingConfigsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersCustomerRepricingConfigsListCall) 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}/customerRepricingConfigs")
	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", "cloudchannel.accounts.customers.customerRepricingConfigs.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.customerRepricingConfigs.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListCustomerRepricingConfigsResponse.ServerResponse.Head
// er or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *AccountsCustomersCustomerRepricingConfigsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListCustomerRepricingConfigsResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListCustomerRepricingConfigsResponse{
		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", "cloudchannel.accounts.customers.customerRepricingConfigs.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 *AccountsCustomersCustomerRepricingConfigsListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListCustomerRepricingConfigsResponse) 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 AccountsCustomersCustomerRepricingConfigsPatchCall struct {
	s                                           *Service
	name                                        string
	googlecloudchannelv1customerrepricingconfig *GoogleCloudChannelV1CustomerRepricingConfig
	urlParams_                                  gensupport.URLParams
	ctx_                                        context.Context
	header_                                     http.Header
}

// Patch: Updates a CustomerRepricingConfig. Call this method to set
// modifications for a specific customer's bill. This method overwrites the
// existing CustomerRepricingConfig. You can only update configs if the
// RepricingConfig.effective_invoice_month is a future month. To make changes
// to configs for the current month, use CreateCustomerRepricingConfig, taking
// note of its restrictions. You cannot update the
// RepricingConfig.effective_invoice_month. When updating a config in the
// future: * This config must already exist. Possible Error Codes: *
// PERMISSION_DENIED: If the account making the request and the account being
// queried are different. * INVALID_ARGUMENT: Missing or invalid required
// parameters in the request. Also displays if the updated config is for the
// current month or past months. * NOT_FOUND: The CustomerRepricingConfig
// specified does not exist or is not associated with the given account. *
// INTERNAL: Any non-user error related to technical issues in the backend. In
// this case, contact Cloud Channel support. Return Value: If successful, the
// updated CustomerRepricingConfig resource, otherwise returns an error.
//
//   - name: Output only. Resource name of the CustomerRepricingConfig. Format:
//     accounts/{account_id}/customers/{customer_id}/customerRepricingConfigs/{id}
//     .
func (r *AccountsCustomersCustomerRepricingConfigsService) Patch(name string, googlecloudchannelv1customerrepricingconfig *GoogleCloudChannelV1CustomerRepricingConfig) *AccountsCustomersCustomerRepricingConfigsPatchCall {
	c := &AccountsCustomersCustomerRepricingConfigsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1customerrepricingconfig = googlecloudchannelv1customerrepricingconfig
	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 *AccountsCustomersCustomerRepricingConfigsPatchCall) Fields(s ...googleapi.Field) *AccountsCustomersCustomerRepricingConfigsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersCustomerRepricingConfigsPatchCall) Context(ctx context.Context) *AccountsCustomersCustomerRepricingConfigsPatchCall {
	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 *AccountsCustomersCustomerRepricingConfigsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersCustomerRepricingConfigsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1customerrepricingconfig)
	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", "cloudchannel.accounts.customers.customerRepricingConfigs.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.customerRepricingConfigs.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1CustomerRepricingConfig.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 *AccountsCustomersCustomerRepricingConfigsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1CustomerRepricingConfig, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1CustomerRepricingConfig{
		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", "cloudchannel.accounts.customers.customerRepricingConfigs.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Activate: Activates a previously suspended entitlement. Entitlements
// suspended for pending ToS acceptance can't be activated using this method.
// An entitlement activation is a long-running operation and it updates the
// state of the customer entitlement. Possible error codes: *
// PERMISSION_DENIED: The reseller account making the request is different from
// the reseller account in the API request. * INVALID_ARGUMENT: Required
// request parameters are missing or invalid. * NOT_FOUND: Entitlement resource
// not found. * SUSPENSION_NOT_RESELLER_INITIATED: Can only activate
// reseller-initiated suspensions and entitlements that have accepted the TOS.
// * NOT_SUSPENDED: Can only activate suspended entitlements not in an ACTIVE
// state. * INTERNAL: Any non-user error related to a technical issue in the
// backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The ID of a long-running operation. To get the results of the
// operation, call the GetOperation method of CloudChannelOperationsService.
// The Operation metadata will contain an instance of OperationMetadata.
//
//   - name: The resource name of the entitlement to activate. Name uses the
//     format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) Activate(name string, googlecloudchannelv1activateentitlementrequest *GoogleCloudChannelV1ActivateEntitlementRequest) *AccountsCustomersEntitlementsActivateCall {
	c := &AccountsCustomersEntitlementsActivateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1activateentitlementrequest = googlecloudchannelv1activateentitlementrequest
	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 *AccountsCustomersEntitlementsActivateCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsActivateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsActivateCall) Context(ctx context.Context) *AccountsCustomersEntitlementsActivateCall {
	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 *AccountsCustomersEntitlementsActivateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsActivateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1activateentitlementrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:activate")
	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", "cloudchannel.accounts.customers.entitlements.activate", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.activate" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersEntitlementsActivateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.entitlements.activate", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Cancel: Cancels a previously fulfilled entitlement. An entitlement
// cancellation is a long-running operation. Possible error codes: *
// PERMISSION_DENIED: The reseller account making the request is different from
// the reseller account in the API request. * FAILED_PRECONDITION: There are
// Google Cloud projects linked to the Google Cloud entitlement's Cloud Billing
// subaccount. * INVALID_ARGUMENT: Required request parameters are missing or
// invalid. * NOT_FOUND: Entitlement resource not found. *
// DELETION_TYPE_NOT_ALLOWED: Cancel is only allowed for Google Workspace
// add-ons, or entitlements for Google Cloud's development platform. *
// INTERNAL: Any non-user error related to a technical issue in the backend.
// Contact Cloud Channel support. * UNKNOWN: Any non-user error related to a
// technical issue in the backend. Contact Cloud Channel support. Return value:
// The ID of a long-running operation. To get the results of the operation,
// call the GetOperation method of CloudChannelOperationsService. The response
// will contain google.protobuf.Empty on success. The Operation metadata will
// contain an instance of OperationMetadata.
//
//   - name: The resource name of the entitlement to cancel. Name uses the
//     format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) Cancel(name string, googlecloudchannelv1cancelentitlementrequest *GoogleCloudChannelV1CancelEntitlementRequest) *AccountsCustomersEntitlementsCancelCall {
	c := &AccountsCustomersEntitlementsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1cancelentitlementrequest = googlecloudchannelv1cancelentitlementrequest
	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 *AccountsCustomersEntitlementsCancelCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsCancelCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsCancelCall) Context(ctx context.Context) *AccountsCustomersEntitlementsCancelCall {
	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 *AccountsCustomersEntitlementsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1cancelentitlementrequest)
	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", "cloudchannel.accounts.customers.entitlements.cancel", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.cancel" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersEntitlementsCancelCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.entitlements.cancel", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// ChangeOffer: Updates the Offer for an existing customer entitlement. An
// entitlement update is a long-running operation and it updates the
// entitlement as a result of fulfillment. Possible error codes: *
// PERMISSION_DENIED: The customer doesn't belong to the reseller. *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. *
// NOT_FOUND: Offer or Entitlement resource not found. * INTERNAL: Any non-user
// error related to a technical issue in the backend. Contact Cloud Channel
// support. * UNKNOWN: Any non-user error related to a technical issue in the
// backend. Contact Cloud Channel support. Return value: The ID of a
// long-running operation. To get the results of the operation, call the
// GetOperation method of CloudChannelOperationsService. The Operation metadata
// will contain an instance of OperationMetadata.
//
//   - name: The resource name of the entitlement to update. Name uses the
//     format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) ChangeOffer(name string, googlecloudchannelv1changeofferrequest *GoogleCloudChannelV1ChangeOfferRequest) *AccountsCustomersEntitlementsChangeOfferCall {
	c := &AccountsCustomersEntitlementsChangeOfferCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1changeofferrequest = googlecloudchannelv1changeofferrequest
	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 *AccountsCustomersEntitlementsChangeOfferCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsChangeOfferCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsChangeOfferCall) Context(ctx context.Context) *AccountsCustomersEntitlementsChangeOfferCall {
	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 *AccountsCustomersEntitlementsChangeOfferCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsChangeOfferCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1changeofferrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:changeOffer")
	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", "cloudchannel.accounts.customers.entitlements.changeOffer", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.changeOffer" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersEntitlementsChangeOfferCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.entitlements.changeOffer", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// ChangeParameters: Change parameters of the entitlement. An entitlement
// update is a long-running operation and it updates the entitlement as a
// result of fulfillment. Possible error codes: * PERMISSION_DENIED: The
// customer doesn't belong to the reseller. * INVALID_ARGUMENT: Required
// request parameters are missing or invalid. For example, the number of seats
// being changed is greater than the allowed number of max seats, or decreasing
// seats for a commitment based plan. * NOT_FOUND: Entitlement resource not
// found. * INTERNAL: Any non-user error related to a technical issue in the
// backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The ID of a long-running operation. To get the results of the
// operation, call the GetOperation method of CloudChannelOperationsService.
// The Operation metadata will contain an instance of OperationMetadata.
//
//   - name: The name of the entitlement to update. Name uses the format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) ChangeParameters(name string, googlecloudchannelv1changeparametersrequest *GoogleCloudChannelV1ChangeParametersRequest) *AccountsCustomersEntitlementsChangeParametersCall {
	c := &AccountsCustomersEntitlementsChangeParametersCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1changeparametersrequest = googlecloudchannelv1changeparametersrequest
	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 *AccountsCustomersEntitlementsChangeParametersCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsChangeParametersCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsChangeParametersCall) Context(ctx context.Context) *AccountsCustomersEntitlementsChangeParametersCall {
	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 *AccountsCustomersEntitlementsChangeParametersCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsChangeParametersCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1changeparametersrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:changeParameters")
	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", "cloudchannel.accounts.customers.entitlements.changeParameters", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.changeParameters" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersEntitlementsChangeParametersCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.entitlements.changeParameters", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// ChangeRenewalSettings: Updates the renewal settings for an existing customer
// entitlement. An entitlement update is a long-running operation and it
// updates the entitlement as a result of fulfillment. Possible error codes: *
// PERMISSION_DENIED: The customer doesn't belong to the reseller. *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. *
// NOT_FOUND: Entitlement resource not found. * NOT_COMMITMENT_PLAN: Renewal
// Settings are only applicable for a commitment plan. Can't enable or disable
// renewals for non-commitment plans. * INTERNAL: Any non-user error related to
// a technical issue in the backend. Contact Cloud Channel support. * UNKNOWN:
// Any non-user error related to a technical issue in the backend. Contact
// Cloud Channel support. Return value: The ID of a long-running operation. To
// get the results of the operation, call the GetOperation method of
// CloudChannelOperationsService. The Operation metadata will contain an
// instance of OperationMetadata.
//
//   - name: The name of the entitlement to update. Name uses the format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) ChangeRenewalSettings(name string, googlecloudchannelv1changerenewalsettingsrequest *GoogleCloudChannelV1ChangeRenewalSettingsRequest) *AccountsCustomersEntitlementsChangeRenewalSettingsCall {
	c := &AccountsCustomersEntitlementsChangeRenewalSettingsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1changerenewalsettingsrequest = googlecloudchannelv1changerenewalsettingsrequest
	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 *AccountsCustomersEntitlementsChangeRenewalSettingsCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsChangeRenewalSettingsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsChangeRenewalSettingsCall) Context(ctx context.Context) *AccountsCustomersEntitlementsChangeRenewalSettingsCall {
	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 *AccountsCustomersEntitlementsChangeRenewalSettingsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsChangeRenewalSettingsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1changerenewalsettingsrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:changeRenewalSettings")
	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", "cloudchannel.accounts.customers.entitlements.changeRenewalSettings", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.changeRenewalSettings" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersEntitlementsChangeRenewalSettingsCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.entitlements.changeRenewalSettings", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type AccountsCustomersEntitlementsCreateCall struct {
	s                                            *Service
	parent                                       string
	googlecloudchannelv1createentitlementrequest *GoogleCloudChannelV1CreateEntitlementRequest
	urlParams_                                   gensupport.URLParams
	ctx_                                         context.Context
	header_                                      http.Header
}

// Create: Creates an entitlement for a customer. Possible error codes: *
// PERMISSION_DENIED: * The customer doesn't belong to the reseller. * The
// reseller is not authorized to transact on this Product. See
// https://support.google.com/channelservices/answer/9759265 *
// INVALID_ARGUMENT: * Required request parameters are missing or invalid. *
// There is already a customer entitlement for a SKU from the same product
// family. * INVALID_VALUE: Make sure the OfferId is valid. If it is, contact
// Google Channel support for further troubleshooting. * NOT_FOUND: The
// customer or offer resource was not found. * ALREADY_EXISTS: * The SKU was
// already purchased for the customer. * The customer's primary email already
// exists. Retry after changing the customer's primary contact email. *
// CONDITION_NOT_MET or FAILED_PRECONDITION: * The domain required for
// purchasing a SKU has not been verified. * A pre-requisite SKU required to
// purchase an Add-On SKU is missing. For example, Google Workspace Business
// Starter is required to purchase Vault or Drive. * (Developer accounts only)
// Reseller and resold domain must meet the following naming requirements: *
// Domain names must start with goog-test. * Domain names must include the
// reseller domain. * INTERNAL: Any non-user error related to a technical issue
// in the backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The ID of a long-running operation. To get the results of the
// operation, call the GetOperation method of CloudChannelOperationsService.
// The Operation metadata will contain an instance of OperationMetadata.
//
//   - parent: The resource name of the reseller's customer account in which to
//     create the entitlement. Parent uses the format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersEntitlementsService) Create(parent string, googlecloudchannelv1createentitlementrequest *GoogleCloudChannelV1CreateEntitlementRequest) *AccountsCustomersEntitlementsCreateCall {
	c := &AccountsCustomersEntitlementsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudchannelv1createentitlementrequest = googlecloudchannelv1createentitlementrequest
	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 *AccountsCustomersEntitlementsCreateCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsCreateCall) Context(ctx context.Context) *AccountsCustomersEntitlementsCreateCall {
	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 *AccountsCustomersEntitlementsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1createentitlementrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/entitlements")
	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", "cloudchannel.accounts.customers.entitlements.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersEntitlementsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.entitlements.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Returns the requested Entitlement resource. Possible error codes: *
// PERMISSION_DENIED: The customer doesn't belong to the reseller. *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. *
// NOT_FOUND: The customer entitlement was not found. Return value: The
// requested Entitlement resource.
//
//   - name: The resource name of the entitlement to retrieve. Name uses the
//     format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) Get(name string) *AccountsCustomersEntitlementsGetCall {
	c := &AccountsCustomersEntitlementsGetCall{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 *AccountsCustomersEntitlementsGetCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsGetCall {
	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 *AccountsCustomersEntitlementsGetCall) IfNoneMatch(entityTag string) *AccountsCustomersEntitlementsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsGetCall) Context(ctx context.Context) *AccountsCustomersEntitlementsGetCall {
	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 *AccountsCustomersEntitlementsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsGetCall) 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", "cloudchannel.accounts.customers.entitlements.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Entitlement.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 *AccountsCustomersEntitlementsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Entitlement, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Entitlement{
		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", "cloudchannel.accounts.customers.entitlements.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists Entitlements belonging to a customer. Possible error codes: *
// PERMISSION_DENIED: The customer doesn't belong to the reseller. *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. Return
// value: A list of the customer's Entitlements.
//
//   - parent: The resource name of the reseller's customer account to list
//     entitlements for. Parent uses the format:
//     accounts/{account_id}/customers/{customer_id}.
func (r *AccountsCustomersEntitlementsService) List(parent string) *AccountsCustomersEntitlementsListCall {
	c := &AccountsCustomersEntitlementsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size. Server
// might return fewer results than requested. If unspecified, return at most 50
// entitlements. The maximum value is 100; the server will coerce values above
// 100.
func (c *AccountsCustomersEntitlementsListCall) PageSize(pageSize int64) *AccountsCustomersEntitlementsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token for a page of
// results other than the first page. Obtained using
// ListEntitlementsResponse.next_page_token of the previous
// CloudChannelService.ListEntitlements call.
func (c *AccountsCustomersEntitlementsListCall) PageToken(pageToken string) *AccountsCustomersEntitlementsListCall {
	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 *AccountsCustomersEntitlementsListCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsListCall {
	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 *AccountsCustomersEntitlementsListCall) IfNoneMatch(entityTag string) *AccountsCustomersEntitlementsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsListCall) Context(ctx context.Context) *AccountsCustomersEntitlementsListCall {
	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 *AccountsCustomersEntitlementsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsListCall) 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}/entitlements")
	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", "cloudchannel.accounts.customers.entitlements.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListEntitlementsResponse.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 *AccountsCustomersEntitlementsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListEntitlementsResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListEntitlementsResponse{
		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", "cloudchannel.accounts.customers.entitlements.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 *AccountsCustomersEntitlementsListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListEntitlementsResponse) 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 AccountsCustomersEntitlementsListEntitlementChangesCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListEntitlementChanges: List entitlement history. Possible error codes: *
// PERMISSION_DENIED: The reseller account making the request and the provided
// reseller account are different. * INVALID_ARGUMENT: Missing or invalid
// required fields in the request. * NOT_FOUND: The parent resource doesn't
// exist. Usually the result of an invalid name parameter. * INTERNAL: Any
// non-user error related to a technical issue in the backend. In this case,
// contact CloudChannel support. * UNKNOWN: Any non-user error related to a
// technical issue in the backend. In this case, contact Cloud Channel support.
// Return value: List of EntitlementChanges.
//
//   - parent: The resource name of the entitlement for which to list entitlement
//     changes. The `-` wildcard may be used to match entitlements across a
//     customer. Formats: *
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}
//   - accounts/{account_id}/customers/{customer_id}/entitlements/-.
func (r *AccountsCustomersEntitlementsService) ListEntitlementChanges(parent string) *AccountsCustomersEntitlementsListEntitlementChangesCall {
	c := &AccountsCustomersEntitlementsListEntitlementChangesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Filters applied to the list
// results.
func (c *AccountsCustomersEntitlementsListEntitlementChangesCall) Filter(filter string) *AccountsCustomersEntitlementsListEntitlementChangesCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// entitlement changes to return. The service may return fewer than this value.
// If unspecified, returns at most 10 entitlement changes. The maximum value is
// 50; the server will coerce values above 50.
func (c *AccountsCustomersEntitlementsListEntitlementChangesCall) PageSize(pageSize int64) *AccountsCustomersEntitlementsListEntitlementChangesCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token, received
// from a previous CloudChannelService.ListEntitlementChanges call. Provide
// this to retrieve the subsequent page. When paginating, all other parameters
// provided to CloudChannelService.ListEntitlementChanges must match the call
// that provided the page token.
func (c *AccountsCustomersEntitlementsListEntitlementChangesCall) PageToken(pageToken string) *AccountsCustomersEntitlementsListEntitlementChangesCall {
	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 *AccountsCustomersEntitlementsListEntitlementChangesCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsListEntitlementChangesCall {
	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 *AccountsCustomersEntitlementsListEntitlementChangesCall) IfNoneMatch(entityTag string) *AccountsCustomersEntitlementsListEntitlementChangesCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsListEntitlementChangesCall) Context(ctx context.Context) *AccountsCustomersEntitlementsListEntitlementChangesCall {
	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 *AccountsCustomersEntitlementsListEntitlementChangesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsListEntitlementChangesCall) 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}:listEntitlementChanges")
	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", "cloudchannel.accounts.customers.entitlements.listEntitlementChanges", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.listEntitlementChanges" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListEntitlementChangesResponse.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 *AccountsCustomersEntitlementsListEntitlementChangesCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListEntitlementChangesResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListEntitlementChangesResponse{
		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", "cloudchannel.accounts.customers.entitlements.listEntitlementChanges", "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 *AccountsCustomersEntitlementsListEntitlementChangesCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListEntitlementChangesResponse) 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 AccountsCustomersEntitlementsLookupOfferCall struct {
	s            *Service
	entitlement  string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// LookupOffer: Returns the requested Offer resource. Possible error codes: *
// PERMISSION_DENIED: The entitlement doesn't belong to the reseller. *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. *
// NOT_FOUND: Entitlement or offer was not found. Return value: The Offer
// resource.
//
//   - entitlement: The resource name of the entitlement to retrieve the Offer.
//     Entitlement uses the format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) LookupOffer(entitlement string) *AccountsCustomersEntitlementsLookupOfferCall {
	c := &AccountsCustomersEntitlementsLookupOfferCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.entitlement = entitlement
	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 *AccountsCustomersEntitlementsLookupOfferCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsLookupOfferCall {
	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 *AccountsCustomersEntitlementsLookupOfferCall) IfNoneMatch(entityTag string) *AccountsCustomersEntitlementsLookupOfferCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsLookupOfferCall) Context(ctx context.Context) *AccountsCustomersEntitlementsLookupOfferCall {
	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 *AccountsCustomersEntitlementsLookupOfferCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsLookupOfferCall) 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/{+entitlement}:lookupOffer")
	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{
		"entitlement": c.entitlement,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "cloudchannel.accounts.customers.entitlements.lookupOffer", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.lookupOffer" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1Offer.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 *AccountsCustomersEntitlementsLookupOfferCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1Offer, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1Offer{
		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", "cloudchannel.accounts.customers.entitlements.lookupOffer", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// StartPaidService: Starts paid service for a trial entitlement. Starts paid
// service for a trial entitlement immediately. This method is only applicable
// if a plan is set up for a trial entitlement but has some trial days
// remaining. Possible error codes: * PERMISSION_DENIED: The customer doesn't
// belong to the reseller. * INVALID_ARGUMENT: Required request parameters are
// missing or invalid. * NOT_FOUND: Entitlement resource not found. *
// FAILED_PRECONDITION/NOT_IN_TRIAL: This method only works for entitlement on
// trial plans. * INTERNAL: Any non-user error related to a technical issue in
// the backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The ID of a long-running operation. To get the results of the
// operation, call the GetOperation method of CloudChannelOperationsService.
// The Operation metadata will contain an instance of OperationMetadata.
//
//   - name: The name of the entitlement to start a paid service for. Name uses
//     the format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) StartPaidService(name string, googlecloudchannelv1startpaidservicerequest *GoogleCloudChannelV1StartPaidServiceRequest) *AccountsCustomersEntitlementsStartPaidServiceCall {
	c := &AccountsCustomersEntitlementsStartPaidServiceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1startpaidservicerequest = googlecloudchannelv1startpaidservicerequest
	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 *AccountsCustomersEntitlementsStartPaidServiceCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsStartPaidServiceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsStartPaidServiceCall) Context(ctx context.Context) *AccountsCustomersEntitlementsStartPaidServiceCall {
	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 *AccountsCustomersEntitlementsStartPaidServiceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsStartPaidServiceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1startpaidservicerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:startPaidService")
	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", "cloudchannel.accounts.customers.entitlements.startPaidService", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.startPaidService" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersEntitlementsStartPaidServiceCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.entitlements.startPaidService", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Suspend: Suspends a previously fulfilled entitlement. An entitlement
// suspension is a long-running operation. Possible error codes: *
// PERMISSION_DENIED: The customer doesn't belong to the reseller. *
// INVALID_ARGUMENT: Required request parameters are missing or invalid. *
// NOT_FOUND: Entitlement resource not found. * NOT_ACTIVE: Entitlement is not
// active. * INTERNAL: Any non-user error related to a technical issue in the
// backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The ID of a long-running operation. To get the results of the
// operation, call the GetOperation method of CloudChannelOperationsService.
// The Operation metadata will contain an instance of OperationMetadata.
//
//   - name: The resource name of the entitlement to suspend. Name uses the
//     format:
//     accounts/{account_id}/customers/{customer_id}/entitlements/{entitlement_id}.
func (r *AccountsCustomersEntitlementsService) Suspend(name string, googlecloudchannelv1suspendentitlementrequest *GoogleCloudChannelV1SuspendEntitlementRequest) *AccountsCustomersEntitlementsSuspendCall {
	c := &AccountsCustomersEntitlementsSuspendCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudchannelv1suspendentitlementrequest = googlecloudchannelv1suspendentitlementrequest
	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 *AccountsCustomersEntitlementsSuspendCall) Fields(s ...googleapi.Field) *AccountsCustomersEntitlementsSuspendCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsCustomersEntitlementsSuspendCall) Context(ctx context.Context) *AccountsCustomersEntitlementsSuspendCall {
	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 *AccountsCustomersEntitlementsSuspendCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsCustomersEntitlementsSuspendCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlecloudchannelv1suspendentitlementrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:suspend")
	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", "cloudchannel.accounts.customers.entitlements.suspend", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.customers.entitlements.suspend" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsCustomersEntitlementsSuspendCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.customers.entitlements.suspend", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists the Offers the reseller can sell. Possible error codes: *
// INVALID_ARGUMENT: Required request parameters are missing or invalid.
//
//   - parent: The resource name of the reseller account from which to list
//     Offers. Parent uses the format: accounts/{account_id}.
func (r *AccountsOffersService) List(parent string) *AccountsOffersListCall {
	c := &AccountsOffersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": The expression to filter
// results by name (name of the Offer), sku.name (name of the SKU), or
// sku.product.name (name of the Product). Example 1:
// sku.product.name=products/p1 AND sku.name!=products/p1/skus/s1 Example 2:
// name=accounts/a1/offers/o1
func (c *AccountsOffersListCall) Filter(filter string) *AccountsOffersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47 language
// code. For example, "en-US". The response will localize in the corresponding
// language code, if specified. The default value is "en-US".
func (c *AccountsOffersListCall) LanguageCode(languageCode string) *AccountsOffersListCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size. Server
// might return fewer results than requested. If unspecified, returns at most
// 500 Offers. The maximum value is 1000; the server will coerce values above
// 1000.
func (c *AccountsOffersListCall) PageSize(pageSize int64) *AccountsOffersListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token for a page of
// results other than the first page.
func (c *AccountsOffersListCall) PageToken(pageToken string) *AccountsOffersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ShowFutureOffers sets the optional parameter "showFutureOffers": A boolean
// flag that determines if a response returns future offers 30 days from now.
// If the show_future_offers is true, the response will only contain offers
// that are scheduled to be available 30 days from now.
func (c *AccountsOffersListCall) ShowFutureOffers(showFutureOffers bool) *AccountsOffersListCall {
	c.urlParams_.Set("showFutureOffers", fmt.Sprint(showFutureOffers))
	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 *AccountsOffersListCall) Fields(s ...googleapi.Field) *AccountsOffersListCall {
	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 *AccountsOffersListCall) IfNoneMatch(entityTag string) *AccountsOffersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsOffersListCall) Context(ctx context.Context) *AccountsOffersListCall {
	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 *AccountsOffersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsOffersListCall) 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}/offers")
	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", "cloudchannel.accounts.offers.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.offers.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListOffersResponse.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 *AccountsOffersListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListOffersResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListOffersResponse{
		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", "cloudchannel.accounts.offers.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 *AccountsOffersListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListOffersResponse) 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 AccountsReportJobsFetchReportResultsCall struct {
	s                                             *Service
	reportJob                                     string
	googlecloudchannelv1fetchreportresultsrequest *GoogleCloudChannelV1FetchReportResultsRequest
	urlParams_                                    gensupport.URLParams
	ctx_                                          context.Context
	header_                                       http.Header
}

// FetchReportResults: Retrieves data generated by
// CloudChannelReportsService.RunReportJob. Deprecated: Please use Export
// Channel Services data to BigQuery
// (https://cloud.google.com/channel/docs/rebilling/export-data-to-bigquery)
// instead.
//
//   - reportJob: The report job created by
//     CloudChannelReportsService.RunReportJob. Report_job uses the format:
//     accounts/{account_id}/reportJobs/{report_job_id}.
func (r *AccountsReportJobsService) FetchReportResults(reportJob string, googlecloudchannelv1fetchreportresultsrequest *GoogleCloudChannelV1FetchReportResultsRequest) *AccountsReportJobsFetchReportResultsCall {
	c := &AccountsReportJobsFetchReportResultsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.reportJob = reportJob
	c.googlecloudchannelv1fetchreportresultsrequest = googlecloudchannelv1fetchreportresultsrequest
	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 *AccountsReportJobsFetchReportResultsCall) Fields(s ...googleapi.Field) *AccountsReportJobsFetchReportResultsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsReportJobsFetchReportResultsCall) Context(ctx context.Context) *AccountsReportJobsFetchReportResultsCall {
	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 *AccountsReportJobsFetchReportResultsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "cloudchannel.accounts.reportJobs.fetchReportResults" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1FetchReportResultsResponse.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 *AccountsReportJobsFetchReportResultsCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1FetchReportResultsResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1FetchReportResultsResponse{
		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", "cloudchannel.accounts.reportJobs.fetchReportResults", "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 *AccountsReportJobsFetchReportResultsCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1FetchReportResultsResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.googlecloudchannelv1fetchreportresultsrequest.PageToken = pt }(c.googlecloudchannelv1fetchreportresultsrequest.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.googlecloudchannelv1fetchreportresultsrequest.PageToken = x.NextPageToken
	}
}

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

// List: Lists the reports that RunReportJob can run. These reports include an
// ID, a description, and the list of columns that will be in the result.
// Deprecated: Please use Export Channel Services data to BigQuery
// (https://cloud.google.com/channel/docs/rebilling/export-data-to-bigquery)
// instead.
//
//   - parent: The resource name of the partner account to list available reports
//     for. Parent uses the format: accounts/{account_id}.
func (r *AccountsReportsService) List(parent string) *AccountsReportsListCall {
	c := &AccountsReportsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47 language
// code, such as "en-US". If specified, the response is localized to the
// corresponding language code if the original data sources support it. Default
// is "en-US".
func (c *AccountsReportsListCall) LanguageCode(languageCode string) *AccountsReportsListCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size of the
// report. The server might return fewer results than requested. If
// unspecified, returns 20 reports. The maximum value is 100.
func (c *AccountsReportsListCall) PageSize(pageSize int64) *AccountsReportsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token that specifies a
// page of results beyond the first page. Obtained through
// ListReportsResponse.next_page_token of the previous
// CloudChannelReportsService.ListReports call.
func (c *AccountsReportsListCall) PageToken(pageToken string) *AccountsReportsListCall {
	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 *AccountsReportsListCall) Fields(s ...googleapi.Field) *AccountsReportsListCall {
	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 *AccountsReportsListCall) IfNoneMatch(entityTag string) *AccountsReportsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsReportsListCall) Context(ctx context.Context) *AccountsReportsListCall {
	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 *AccountsReportsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsReportsListCall) 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}/reports")
	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", "cloudchannel.accounts.reports.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.reports.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListReportsResponse.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 *AccountsReportsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListReportsResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListReportsResponse{
		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", "cloudchannel.accounts.reports.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 *AccountsReportsListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListReportsResponse) 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 AccountsReportsRunCall struct {
	s                                       *Service
	nameid                                  string
	googlecloudchannelv1runreportjobrequest *GoogleCloudChannelV1RunReportJobRequest
	urlParams_                              gensupport.URLParams
	ctx_                                    context.Context
	header_                                 http.Header
}

// Run: Begins generation of data for a given report. The report identifier is
// a UID (for example, `613bf59q`). Possible error codes: * PERMISSION_DENIED:
// The user doesn't have access to this report. * INVALID_ARGUMENT: Required
// request parameters are missing or invalid. * NOT_FOUND: The report
// identifier was not found. * INTERNAL: Any non-user error related to a
// technical issue in the backend. Contact Cloud Channel support. * UNKNOWN:
// Any non-user error related to a technical issue in the backend. Contact
// Cloud Channel support. Return value: The ID of a long-running operation. To
// get the results of the operation, call the GetOperation method of
// CloudChannelOperationsService. The Operation metadata contains an instance
// of OperationMetadata. To get the results of report generation, call
// CloudChannelReportsService.FetchReportResults with the
// RunReportJobResponse.report_job. Deprecated: Please use Export Channel
// Services data to BigQuery
// (https://cloud.google.com/channel/docs/rebilling/export-data-to-bigquery)
// instead.
//
//   - name: The report's resource name. Specifies the account and report used to
//     generate report data. The report_id identifier is a UID (for example,
//     `613bf59q`). Name uses the format:
//     accounts/{account_id}/reports/{report_id}.
func (r *AccountsReportsService) Run(nameid string, googlecloudchannelv1runreportjobrequest *GoogleCloudChannelV1RunReportJobRequest) *AccountsReportsRunCall {
	c := &AccountsReportsRunCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.googlecloudchannelv1runreportjobrequest = googlecloudchannelv1runreportjobrequest
	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 *AccountsReportsRunCall) Fields(s ...googleapi.Field) *AccountsReportsRunCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsReportsRunCall) Context(ctx context.Context) *AccountsReportsRunCall {
	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 *AccountsReportsRunCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "cloudchannel.accounts.reports.run" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *AccountsReportsRunCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.accounts.reports.run", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists the Rebilling supported SKU groups the account is authorized to
// sell. Reference: https://cloud.google.com/skus/sku-groups Possible Error
// Codes: * PERMISSION_DENIED: If the account making the request and the
// account being queried are different, or the account doesn't exist. *
// INTERNAL: Any non-user error related to technical issues in the backend. In
// this case, contact Cloud Channel support. Return Value: If successful, the
// SkuGroup resources. The data for each resource is displayed in the
// alphabetical order of SKU group display name. The data for each resource is
// displayed in the ascending order of SkuGroup.display_name If unsuccessful,
// returns an error.
//
//   - parent: The resource name of the account from which to list SKU groups.
//     Parent uses the format: accounts/{account}.
func (r *AccountsSkuGroupsService) List(parent string) *AccountsSkuGroupsListCall {
	c := &AccountsSkuGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of SKU
// groups to return. The service may return fewer than this value. If
// unspecified, returns a maximum of 1000 SKU groups. The maximum value is
// 1000; values above 1000 will be coerced to 1000.
func (c *AccountsSkuGroupsListCall) PageSize(pageSize int64) *AccountsSkuGroupsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token identifying a
// page of results beyond the first page. Obtained through
// ListSkuGroupsResponse.next_page_token of the previous
// CloudChannelService.ListSkuGroups call.
func (c *AccountsSkuGroupsListCall) PageToken(pageToken string) *AccountsSkuGroupsListCall {
	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 *AccountsSkuGroupsListCall) Fields(s ...googleapi.Field) *AccountsSkuGroupsListCall {
	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 *AccountsSkuGroupsListCall) IfNoneMatch(entityTag string) *AccountsSkuGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsSkuGroupsListCall) Context(ctx context.Context) *AccountsSkuGroupsListCall {
	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 *AccountsSkuGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsSkuGroupsListCall) 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}/skuGroups")
	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", "cloudchannel.accounts.skuGroups.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.skuGroups.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListSkuGroupsResponse.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 *AccountsSkuGroupsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListSkuGroupsResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListSkuGroupsResponse{
		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", "cloudchannel.accounts.skuGroups.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 *AccountsSkuGroupsListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListSkuGroupsResponse) 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 AccountsSkuGroupsBillableSkusListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists the Billable SKUs in a given SKU group. Possible error codes:
// PERMISSION_DENIED: If the account making the request and the account being
// queried for are different, or the account doesn't exist. INVALID_ARGUMENT:
// Missing or invalid required parameters in the request. INTERNAL: Any
// non-user error related to technical issue in the backend. In this case,
// contact cloud channel support. Return Value: If successful, the BillableSku
// resources. The data for each resource is displayed in the ascending order
// of: * BillableSku.service_display_name * BillableSku.sku_display_name If
// unsuccessful, returns an error.
//
//   - parent: Resource name of the SKU group. Format:
//     accounts/{account}/skuGroups/{sku_group}.
func (r *AccountsSkuGroupsBillableSkusService) List(parent string) *AccountsSkuGroupsBillableSkusListCall {
	c := &AccountsSkuGroupsBillableSkusListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of SKUs
// to return. The service may return fewer than this value. If unspecified,
// returns a maximum of 100000 SKUs. The maximum value is 100000; values above
// 100000 will be coerced to 100000.
func (c *AccountsSkuGroupsBillableSkusListCall) PageSize(pageSize int64) *AccountsSkuGroupsBillableSkusListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token identifying a
// page of results beyond the first page. Obtained through
// ListSkuGroupBillableSkusResponse.next_page_token of the previous
// CloudChannelService.ListSkuGroupBillableSkus call.
func (c *AccountsSkuGroupsBillableSkusListCall) PageToken(pageToken string) *AccountsSkuGroupsBillableSkusListCall {
	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 *AccountsSkuGroupsBillableSkusListCall) Fields(s ...googleapi.Field) *AccountsSkuGroupsBillableSkusListCall {
	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 *AccountsSkuGroupsBillableSkusListCall) IfNoneMatch(entityTag string) *AccountsSkuGroupsBillableSkusListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *AccountsSkuGroupsBillableSkusListCall) Context(ctx context.Context) *AccountsSkuGroupsBillableSkusListCall {
	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 *AccountsSkuGroupsBillableSkusListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsSkuGroupsBillableSkusListCall) 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}/billableSkus")
	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", "cloudchannel.accounts.skuGroups.billableSkus.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.accounts.skuGroups.billableSkus.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListSkuGroupBillableSkusResponse.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 *AccountsSkuGroupsBillableSkusListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListSkuGroupBillableSkusResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListSkuGroupBillableSkusResponse{
		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", "cloudchannel.accounts.skuGroups.billableSkus.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 *AccountsSkuGroupsBillableSkusListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListSkuGroupBillableSkusResponse) 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 IntegratorsListSubscribersCall struct {
	s            *Service
	integrator   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListSubscribers: Lists service accounts with subscriber privileges on the
// Pub/Sub topic created for this Channel Services account or integrator.
// Possible error codes: * PERMISSION_DENIED: The reseller account making the
// request and the provided reseller account are different, or the impersonated
// user is not a super admin. * INVALID_ARGUMENT: Required request parameters
// are missing or invalid. * NOT_FOUND: The topic resource doesn't exist. *
// INTERNAL: Any non-user error related to a technical issue in the backend.
// Contact Cloud Channel support. * UNKNOWN: Any non-user error related to a
// technical issue in the backend. Contact Cloud Channel support. Return value:
// A list of service email addresses.
//
//   - integrator: Optional. Resource name of the integrator. Required if account
//     is not provided. Otherwise, leave this field empty/unset.
func (r *IntegratorsService) ListSubscribers(integrator string) *IntegratorsListSubscribersCall {
	c := &IntegratorsListSubscribersCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.integrator = integrator
	return c
}

// Account sets the optional parameter "account": Resource name of the account.
// Required if integrator is not provided. Otherwise, leave this field
// empty/unset.
func (c *IntegratorsListSubscribersCall) Account(account string) *IntegratorsListSubscribersCall {
	c.urlParams_.Set("account", account)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// service accounts to return. The service may return fewer than this value. If
// unspecified, returns at most 100 service accounts. The maximum value is
// 1000; the server will coerce values above 1000.
func (c *IntegratorsListSubscribersCall) PageSize(pageSize int64) *IntegratorsListSubscribersCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

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

// Context sets the context to be used in this call's Do method.
func (c *IntegratorsListSubscribersCall) Context(ctx context.Context) *IntegratorsListSubscribersCall {
	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 *IntegratorsListSubscribersCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *IntegratorsListSubscribersCall) 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/{+integrator}:listSubscribers")
	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{
		"integrator": c.integrator,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "cloudchannel.integrators.listSubscribers", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.integrators.listSubscribers" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListSubscribersResponse.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 *IntegratorsListSubscribersCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListSubscribersResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListSubscribersResponse{
		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", "cloudchannel.integrators.listSubscribers", "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 *IntegratorsListSubscribersCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListSubscribersResponse) 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 IntegratorsRegisterSubscriberCall struct {
	s                                             *Service
	integrator                                    string
	googlecloudchannelv1registersubscriberrequest *GoogleCloudChannelV1RegisterSubscriberRequest
	urlParams_                                    gensupport.URLParams
	ctx_                                          context.Context
	header_                                       http.Header
}

// RegisterSubscriber: Registers a service account with subscriber privileges
// on the Pub/Sub topic for this Channel Services account or integrator. After
// you create a subscriber, you get the events through SubscriberEvent Possible
// error codes: * PERMISSION_DENIED: The reseller account making the request
// and the provided reseller account are different, or the impersonated user is
// not a super admin. * INVALID_ARGUMENT: Required request parameters are
// missing or invalid. * INTERNAL: Any non-user error related to a technical
// issue in the backend. Contact Cloud Channel support. * UNKNOWN: Any non-user
// error related to a technical issue in the backend. Contact Cloud Channel
// support. Return value: The topic name with the registered service email
// address.
//
//   - integrator: Optional. Resource name of the integrator. Required if account
//     is not provided. Otherwise, leave this field empty/unset.
func (r *IntegratorsService) RegisterSubscriber(integrator string, googlecloudchannelv1registersubscriberrequest *GoogleCloudChannelV1RegisterSubscriberRequest) *IntegratorsRegisterSubscriberCall {
	c := &IntegratorsRegisterSubscriberCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.integrator = integrator
	c.googlecloudchannelv1registersubscriberrequest = googlecloudchannelv1registersubscriberrequest
	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 *IntegratorsRegisterSubscriberCall) Fields(s ...googleapi.Field) *IntegratorsRegisterSubscriberCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *IntegratorsRegisterSubscriberCall) Context(ctx context.Context) *IntegratorsRegisterSubscriberCall {
	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 *IntegratorsRegisterSubscriberCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "cloudchannel.integrators.registerSubscriber" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1RegisterSubscriberResponse.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 *IntegratorsRegisterSubscriberCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1RegisterSubscriberResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1RegisterSubscriberResponse{
		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", "cloudchannel.integrators.registerSubscriber", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type IntegratorsUnregisterSubscriberCall struct {
	s                                               *Service
	integrator                                      string
	googlecloudchannelv1unregistersubscriberrequest *GoogleCloudChannelV1UnregisterSubscriberRequest
	urlParams_                                      gensupport.URLParams
	ctx_                                            context.Context
	header_                                         http.Header
}

// UnregisterSubscriber: Unregisters a service account with subscriber
// privileges on the Pub/Sub topic created for this Channel Services account or
// integrator. If there are no service accounts left with subscriber
// privileges, this deletes the topic. You can call ListSubscribers to check
// for these accounts. Possible error codes: * PERMISSION_DENIED: The reseller
// account making the request and the provided reseller account are different,
// or the impersonated user is not a super admin. * INVALID_ARGUMENT: Required
// request parameters are missing or invalid. * NOT_FOUND: The topic resource
// doesn't exist. * INTERNAL: Any non-user error related to a technical issue
// in the backend. Contact Cloud Channel support. * UNKNOWN: Any non-user error
// related to a technical issue in the backend. Contact Cloud Channel support.
// Return value: The topic name that unregistered the service email address.
// Returns a success response if the service email address wasn't registered
// with the topic.
//
//   - integrator: Optional. Resource name of the integrator. Required if account
//     is not provided. Otherwise, leave this field empty/unset.
func (r *IntegratorsService) UnregisterSubscriber(integrator string, googlecloudchannelv1unregistersubscriberrequest *GoogleCloudChannelV1UnregisterSubscriberRequest) *IntegratorsUnregisterSubscriberCall {
	c := &IntegratorsUnregisterSubscriberCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.integrator = integrator
	c.googlecloudchannelv1unregistersubscriberrequest = googlecloudchannelv1unregistersubscriberrequest
	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 *IntegratorsUnregisterSubscriberCall) Fields(s ...googleapi.Field) *IntegratorsUnregisterSubscriberCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *IntegratorsUnregisterSubscriberCall) Context(ctx context.Context) *IntegratorsUnregisterSubscriberCall {
	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 *IntegratorsUnregisterSubscriberCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "cloudchannel.integrators.unregisterSubscriber" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1UnregisterSubscriberResponse.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 *IntegratorsUnregisterSubscriberCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1UnregisterSubscriberResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1UnregisterSubscriberResponse{
		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", "cloudchannel.integrators.unregisterSubscriber", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type OperationsCancelCall struct {
	s                                       *Service
	name                                    string
	googlelongrunningcanceloperationrequest *GoogleLongrunningCancelOperationRequest
	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 *OperationsService) Cancel(name string, googlelongrunningcanceloperationrequest *GoogleLongrunningCancelOperationRequest) *OperationsCancelCall {
	c := &OperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlelongrunningcanceloperationrequest = googlelongrunningcanceloperationrequest
	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 *OperationsCancelCall) Fields(s ...googleapi.Field) *OperationsCancelCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *OperationsCancelCall) Context(ctx context.Context) *OperationsCancelCall {
	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 *OperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.googlelongrunningcanceloperationrequest)
	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", "cloudchannel.operations.cancel", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.operations.cancel" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *OperationsCancelCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "cloudchannel.operations.cancel", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type OperationsDeleteCall 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 *OperationsService) Delete(name string) *OperationsDeleteCall {
	c := &OperationsDeleteCall{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 *OperationsDeleteCall) Fields(s ...googleapi.Field) *OperationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *OperationsDeleteCall) Context(ctx context.Context) *OperationsDeleteCall {
	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 *OperationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsDeleteCall) 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", "cloudchannel.operations.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.operations.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *OperationsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &GoogleProtobufEmpty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "cloudchannel.operations.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// Get: Gets the latest state of a long-running operation. Clients can use this
// method to poll the operation result at intervals as recommended by the API
// service.
//
// - name: The name of the operation resource.
func (r *OperationsService) Get(name string) *OperationsGetCall {
	c := &OperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *OperationsGetCall) Fields(s ...googleapi.Field) *OperationsGetCall {
	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 *OperationsGetCall) IfNoneMatch(entityTag string) *OperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *OperationsGetCall) Context(ctx context.Context) *OperationsGetCall {
	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 *OperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := 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", "cloudchannel.operations.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.operations.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *OperationsGetCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningOperation{
		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", "cloudchannel.operations.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

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

// List: Lists operations that match the specified filter in the request. If
// the server doesn't support this method, it returns `UNIMPLEMENTED`.
//
// - name: The name of the operation's parent resource.
func (r *OperationsService) List(name string) *OperationsListCall {
	c := &OperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list filter.
func (c *OperationsListCall) Filter(filter string) *OperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list page
// size.
func (c *OperationsListCall) PageSize(pageSize int64) *OperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list page
// token.
func (c *OperationsListCall) PageToken(pageToken string) *OperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// 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 *OperationsListCall) ReturnPartialSuccess(returnPartialSuccess bool) *OperationsListCall {
	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 *OperationsListCall) Fields(s ...googleapi.Field) *OperationsListCall {
	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 *OperationsListCall) IfNoneMatch(entityTag string) *OperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *OperationsListCall) Context(ctx context.Context) *OperationsListCall {
	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 *OperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := 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", "cloudchannel.operations.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.operations.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningListOperationsResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *OperationsListCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningListOperationsResponse, error) {
	gensupport.SetOptions(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 := &GoogleLongrunningListOperationsResponse{
		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", "cloudchannel.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 *OperationsListCall) Pages(ctx context.Context, f func(*GoogleLongrunningListOperationsResponse) 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 ProductsListCall struct {
	s            *Service
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists the Products the reseller is authorized to sell. Possible error
// codes: * INVALID_ARGUMENT: Required request parameters are missing or
// invalid.
func (r *ProductsService) List() *ProductsListCall {
	c := &ProductsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Account sets the optional parameter "account": Required. The resource name
// of the reseller account. Format: accounts/{account_id}.
func (c *ProductsListCall) Account(account string) *ProductsListCall {
	c.urlParams_.Set("account", account)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47 language
// code. For example, "en-US". The response will localize in the corresponding
// language code, if specified. The default value is "en-US".
func (c *ProductsListCall) LanguageCode(languageCode string) *ProductsListCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size. Server
// might return fewer results than requested. If unspecified, returns at most
// 100 Products. The maximum value is 1000; the server will coerce values above
// 1000.
func (c *ProductsListCall) PageSize(pageSize int64) *ProductsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token for a page of
// results other than the first page.
func (c *ProductsListCall) PageToken(pageToken string) *ProductsListCall {
	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 *ProductsListCall) Fields(s ...googleapi.Field) *ProductsListCall {
	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 *ProductsListCall) IfNoneMatch(entityTag string) *ProductsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProductsListCall) Context(ctx context.Context) *ProductsListCall {
	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 *ProductsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProductsListCall) 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/products")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "cloudchannel.products.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.products.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListProductsResponse.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 *ProductsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListProductsResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListProductsResponse{
		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", "cloudchannel.products.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 *ProductsListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListProductsResponse) 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 ProductsSkusListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists the SKUs for a product the reseller is authorized to sell.
// Possible error codes: * INVALID_ARGUMENT: Required request parameters are
// missing or invalid.
//
//   - parent: The resource name of the Product to list SKUs for. Parent uses the
//     format: products/{product_id}. Supports products/- to retrieve SKUs for
//     all products.
func (r *ProductsSkusService) List(parent string) *ProductsSkusListCall {
	c := &ProductsSkusListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Account sets the optional parameter "account": Required. Resource name of
// the reseller. Format: accounts/{account_id}.
func (c *ProductsSkusListCall) Account(account string) *ProductsSkusListCall {
	c.urlParams_.Set("account", account)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The BCP-47 language
// code. For example, "en-US". The response will localize in the corresponding
// language code, if specified. The default value is "en-US".
func (c *ProductsSkusListCall) LanguageCode(languageCode string) *ProductsSkusListCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size. Server
// might return fewer results than requested. If unspecified, returns at most
// 100 SKUs. The maximum value is 1000; the server will coerce values above
// 1000.
func (c *ProductsSkusListCall) PageSize(pageSize int64) *ProductsSkusListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token for a page of
// results other than the first page. Optional.
func (c *ProductsSkusListCall) PageToken(pageToken string) *ProductsSkusListCall {
	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 *ProductsSkusListCall) Fields(s ...googleapi.Field) *ProductsSkusListCall {
	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 *ProductsSkusListCall) IfNoneMatch(entityTag string) *ProductsSkusListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProductsSkusListCall) Context(ctx context.Context) *ProductsSkusListCall {
	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 *ProductsSkusListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProductsSkusListCall) 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}/skus")
	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", "cloudchannel.products.skus.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudchannel.products.skus.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleCloudChannelV1ListSkusResponse.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 *ProductsSkusListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudChannelV1ListSkusResponse, error) {
	gensupport.SetOptions(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 := &GoogleCloudChannelV1ListSkusResponse{
		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", "cloudchannel.products.skus.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 *ProductsSkusListCall) Pages(ctx context.Context, f func(*GoogleCloudChannelV1ListSkusResponse) 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)
	}
}
