// Copyright 2020 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 realtimebidding provides access to the Real-time Bidding API.
//
// For product documentation, see: https://developers.google.com/authorized-buyers/apis/realtimebidding/reference/rest/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/realtimebidding/v1"
//   ...
//   ctx := context.Background()
//   realtimebiddingService, err := realtimebidding.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   realtimebiddingService, err := realtimebidding.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   realtimebiddingService, err := realtimebidding.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package realtimebidding // import "google.golang.org/api/realtimebidding/v1"

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

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	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

const apiId = "realtimebidding:v1"
const apiName = "realtimebidding"
const apiVersion = "v1"
const basePath = "https://realtimebidding.googleapis.com/"
const mtlsBasePath = "https://realtimebidding.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See, create, edit, and delete your Authorized Buyers and Open Bidding
	// account entities
	RealtimeBiddingScope = "https://www.googleapis.com/auth/realtime-bidding"
)

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

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

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

	Bidders *BiddersService

	Buyers *BuyersService
}

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

func NewBiddersService(s *Service) *BiddersService {
	rs := &BiddersService{s: s}
	rs.Creatives = NewBiddersCreativesService(s)
	return rs
}

type BiddersService struct {
	s *Service

	Creatives *BiddersCreativesService
}

func NewBiddersCreativesService(s *Service) *BiddersCreativesService {
	rs := &BiddersCreativesService{s: s}
	return rs
}

type BiddersCreativesService struct {
	s *Service
}

func NewBuyersService(s *Service) *BuyersService {
	rs := &BuyersService{s: s}
	rs.Creatives = NewBuyersCreativesService(s)
	rs.UserLists = NewBuyersUserListsService(s)
	return rs
}

type BuyersService struct {
	s *Service

	Creatives *BuyersCreativesService

	UserLists *BuyersUserListsService
}

func NewBuyersCreativesService(s *Service) *BuyersCreativesService {
	rs := &BuyersCreativesService{s: s}
	return rs
}

type BuyersCreativesService struct {
	s *Service
}

func NewBuyersUserListsService(s *Service) *BuyersUserListsService {
	rs := &BuyersUserListsService{s: s}
	return rs
}

type BuyersUserListsService struct {
	s *Service
}

// AdTechnologyProviders: Detected ad technology provider information.
type AdTechnologyProviders struct {
	// DetectedProviderIds: The detected ad technology provider IDs for this
	// creative. See
	// https://storage.googleapis.com/adx-rtb-dictionaries/providers.csv for
	// mapping of provider ID to provided name, a privacy policy URL, and a
	// list of domains which can be attributed to the provider. If the
	// creative contains provider IDs that are outside of those listed in
	// the
	// `BidRequest.adslot.consented_providers_settings.consented_providers`
	// field on the [Google bid
	// protocol](https://developers.google.com/authorized-buyers/rtb/download
	// s/realtime-bidding-proto) and the
	// `BidRequest.user.ext.consented_providers_settings.consented_providers`
	//  field on the [OpenRTB
	// protocol](https://developers.google.com/authorized-buyers/rtb/download
	// s/openrtb-adx-proto), and a bid is submitted with that creative for
	// an impression that will serve to an EEA user, the bid will be
	// filtered before the auction.
	DetectedProviderIds googleapi.Int64s `json:"detectedProviderIds,omitempty"`

	// HasUnidentifiedProvider: Whether the creative contains an
	// unidentified ad technology provider. If true for a given creative,
	// any bid submitted with that creative for an impression that will
	// serve to an EEA user will be filtered before the auction.
	HasUnidentifiedProvider bool `json:"hasUnidentifiedProvider,omitempty"`

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

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

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

// AdvertiserAndBrand: Detected advertiser and brand information.
type AdvertiserAndBrand struct {
	// AdvertiserId: See
	// https://storage.googleapis.com/adx-rtb-dictionaries/advertisers.txt
	// for the list of possible values. Can be used to filter the response
	// of the creatives.list method.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserName: Advertiser name. Can be used to filter the response
	// of the creatives.list method.
	AdvertiserName string `json:"advertiserName,omitempty"`

	// BrandId: Detected brand ID or zero if no brand has been detected. See
	// https://storage.googleapis.com/adx-rtb-dictionaries/brands.txt for
	// the list of possible values. Can be used to filter the response of
	// the creatives.list method.
	BrandId int64 `json:"brandId,omitempty,string"`

	// BrandName: Brand name. Can be used to filter the response of the
	// creatives.list method.
	BrandName string `json:"brandName,omitempty"`

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

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

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

// CloseUserListRequest: A request to close a specified user list.
type CloseUserListRequest struct {
}

// Creative: A creative and its classification data.
type Creative struct {
	// AccountId: Output only. ID of the buyer account that this creative is
	// owned by. Can be used to filter the response of the creatives.list
	// method with equality and inequality check.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdChoicesDestinationUrl: The link to AdChoices destination page. This
	// is only supported for native ads.
	AdChoicesDestinationUrl string `json:"adChoicesDestinationUrl,omitempty"`

	// AdvertiserName: The name of the company being advertised in the
	// creative. Can be used to filter the response of the creatives.list
	// method.
	AdvertiserName string `json:"advertiserName,omitempty"`

	// AgencyId: The agency ID for this creative.
	AgencyId int64 `json:"agencyId,omitempty,string"`

	// ApiUpdateTime: Output only. The last update timestamp of the creative
	// via API.
	ApiUpdateTime string `json:"apiUpdateTime,omitempty"`

	// CreativeFormat: Output only. The format of this creative. Can be used
	// to filter the response of the creatives.list method.
	//
	// Possible values:
	//   "CREATIVE_FORMAT_UNSPECIFIED" - The format is unknown.
	//   "HTML" - HTML creative.
	//   "VIDEO" - Video creative.
	//   "NATIVE" - Native creative.
	CreativeFormat string `json:"creativeFormat,omitempty"`

	// CreativeId: Buyer-specific creative ID that references this creative
	// in bid responses. This field is Ignored in update operations. Can be
	// used to filter the response of the creatives.list method. The maximum
	// length of the creative ID is 128 bytes.
	CreativeId string `json:"creativeId,omitempty"`

	// CreativeServingDecision: Output only. Top level status and detected
	// attributes of a creative (for example domain, language, advertiser,
	// product category, etc.) that affect whether (status) and where
	// (context) a creative will be allowed to serve.
	CreativeServingDecision *CreativeServingDecision `json:"creativeServingDecision,omitempty"`

	// DealIds: Output only. IDs of all of the deals with which this
	// creative has been used in bidding. Can be used to filter the response
	// of the creatives.list method.
	DealIds []string `json:"dealIds,omitempty"`

	// DeclaredAttributes: All declared attributes for the ads that may be
	// shown from this creative. Can be used to filter the response of the
	// creatives.list method. If the `excluded_attribute` field of a [bid
	// request](https://developers.google.com/authorized-buyers/rtb/downloads
	// /realtime-bidding-proto") contains one of the attributes that were
	// declared or detected for a given creative, and a bid is submitted
	// with that creative, the bid will be filtered before the auction.
	//
	// Possible values:
	//   "ATTRIBUTE_UNSPECIFIED" - Do not use. This is a placeholder value
	// only.
	//   "IMAGE_RICH_MEDIA" - The creative is of type image/rich media. For
	// pretargeting.
	//   "ADOBE_FLASH_FLV" - The creative is of video type Adobe Flash FLV.
	// For pretargeting.
	//   "IS_TAGGED" - The creative is tagged.
	//   "IS_COOKIE_TARGETED" - The creative is cookie targeted.
	//   "IS_USER_INTEREST_TARGETED" - The creative is user interest
	// targeted.
	//   "EXPANDING_DIRECTION_NONE" - The creative does not expand.
	//   "EXPANDING_DIRECTION_UP" - The creative expands up.
	//   "EXPANDING_DIRECTION_DOWN" - The creative expands down.
	//   "EXPANDING_DIRECTION_LEFT" - The creative expands left.
	//   "EXPANDING_DIRECTION_RIGHT" - The creative expands right.
	//   "EXPANDING_DIRECTION_UP_LEFT" - The creative expands up and left.
	//   "EXPANDING_DIRECTION_UP_RIGHT" - The creative expands up and right.
	//   "EXPANDING_DIRECTION_DOWN_LEFT" - The creative expands down and
	// left.
	//   "EXPANDING_DIRECTION_DOWN_RIGHT" - The creative expands down and
	// right.
	//   "CREATIVE_TYPE_HTML" - The creative type is HTML.
	//   "CREATIVE_TYPE_VAST_VIDEO" - The creative type is VAST video.
	//   "EXPANDING_DIRECTION_UP_OR_DOWN" - The creative expands up or down.
	//   "EXPANDING_DIRECTION_LEFT_OR_RIGHT" - The creative expands left or
	// right.
	//   "EXPANDING_DIRECTION_ANY_DIAGONAL" - The creative expands on any
	// diagonal.
	//   "EXPANDING_ACTION_ROLLOVER_TO_EXPAND" - The creative expands when
	// rolled over.
	//   "INSTREAM_VAST_VIDEO_TYPE_VPAID_FLASH" - The instream vast video
	// type is vpaid flash.
	//   "RICH_MEDIA_CAPABILITY_TYPE_MRAID" - The creative is MRAID.
	//   "RICH_MEDIA_CAPABILITY_TYPE_FLASH" - The creative is Flash.
	//   "RICH_MEDIA_CAPABILITY_TYPE_HTML5" - The creative is HTML5.
	//   "SKIPPABLE_INSTREAM_VIDEO" - The creative has an instream VAST
	// video type of skippable instream video. For pretargeting.
	//   "RICH_MEDIA_CAPABILITY_TYPE_SSL" - The creative is SSL.
	//   "RICH_MEDIA_CAPABILITY_TYPE_NON_SSL" - The creative is non-SSL.
	//   "RICH_MEDIA_CAPABILITY_TYPE_INTERSTITIAL" - The creative is an
	// interstitial.
	//   "NON_SKIPPABLE_INSTREAM_VIDEO" - The creative has an instream VAST
	// video type of non-skippable instream video. For pretargeting.
	//   "NATIVE_ELIGIBILITY_ELIGIBLE" - The creative is eligible for
	// native.
	//   "NON_VPAID" - The creative has an instream VAST video type of
	// non-VPAID. For pretargeting.
	//   "NATIVE_ELIGIBILITY_NOT_ELIGIBLE" - The creative is not eligible
	// for native.
	//   "ANY_INTERSTITIAL" - The creative has an interstitial size of any
	// interstitial. For pretargeting.
	//   "NON_INTERSTITIAL" - The creative has an interstitial size of non
	// interstitial. For pretargeting.
	//   "IN_BANNER_VIDEO" - The video type is in-banner video.
	//   "RENDERING_SIZELESS_ADX" - The creative can dynamically resize to
	// fill a variety of slot sizes.
	//   "OMSDK_1_0" - The open measurement SDK is supported.
	DeclaredAttributes []string `json:"declaredAttributes,omitempty"`

	// DeclaredClickThroughUrls: The set of declared destination URLs for
	// the creative. Can be used to filter the response of the
	// creatives.list method.
	DeclaredClickThroughUrls []string `json:"declaredClickThroughUrls,omitempty"`

	// DeclaredRestrictedCategories: All declared restricted categories for
	// the ads that may be shown from this creative. Can be used to filter
	// the response of the creatives.list method.
	//
	// Possible values:
	//   "RESTRICTED_CATEGORY_UNSPECIFIED" - Default value that should never
	// be used.
	//   "ALCOHOL" - The alcohol restricted category.
	DeclaredRestrictedCategories []string `json:"declaredRestrictedCategories,omitempty"`

	// DeclaredVendorIds: IDs for the declared ad technology vendors that
	// may be used by this creative. See
	// https://storage.googleapis.com/adx-rtb-dictionaries/vendors.txt for
	// possible values. Can be used to filter the response of the
	// creatives.list method.
	DeclaredVendorIds []int64 `json:"declaredVendorIds,omitempty"`

	// Html: An HTML creative.
	Html *HtmlContent `json:"html,omitempty"`

	// ImpressionTrackingUrls: The set of URLs to be called to record an
	// impression.
	ImpressionTrackingUrls []string `json:"impressionTrackingUrls,omitempty"`

	// Name: Name of the creative. Follows the pattern
	// `buyers/{buyer}/creatives/{creative}`, where `{buyer}` represents the
	// account ID of the buyer who owns the creative, and `{creative}` is
	// the buyer-specific creative ID that references this creative in the
	// bid response.
	Name string `json:"name,omitempty"`

	// Native: A native creative.
	Native *NativeContent `json:"native,omitempty"`

	// RestrictedCategories: All restricted categories for the ads that may
	// be shown from this creative.
	//
	// Possible values:
	//   "RESTRICTED_CATEGORY_UNSPECIFIED" - Default value that should never
	// be used.
	//   "ALCOHOL" - The alcohol restricted category.
	RestrictedCategories []string `json:"restrictedCategories,omitempty"`

	// Version: Output only. The version of this creative. Version for a new
	// creative is 1 and it increments during subsequent creative updates.
	Version int64 `json:"version,omitempty"`

	// Video: A video creative.
	Video *VideoContent `json:"video,omitempty"`

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

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

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

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

// CreativeServingDecision: Top level status and detected attributes of
// a creative.
type CreativeServingDecision struct {
	// AdTechnologyProviders: The detected ad technology providers.
	AdTechnologyProviders *AdTechnologyProviders `json:"adTechnologyProviders,omitempty"`

	// ChinaServingStatus: The serving status of this creative in China.
	// When approved or disapproved, this status applies to both deals and
	// open auction in China. When pending review, this creative is allowed
	// to serve for deals but not for open auction.
	ChinaServingStatus *ServingStatus `json:"chinaServingStatus,omitempty"`

	// DealsServingStatus: Status of this creative when bidding on PG and PD
	// deals (outside of Russia and China).
	DealsServingStatus *ServingStatus `json:"dealsServingStatus,omitempty"`

	// DetectedAdvertisers: Detected advertisers and brands.
	DetectedAdvertisers []*AdvertiserAndBrand `json:"detectedAdvertisers,omitempty"`

	// DetectedAttributes: Publisher-excludable attributes that were
	// detected for this creative. Can be used to filter the response of the
	// creatives.list method. If the `excluded_attribute` field of a [bid
	// request](https://developers.google.com/authorized-buyers/rtb/downloads
	// /realtime-bidding-proto) contains one of the attributes that were
	// declared or detected for a given creative, and a bid is submitted
	// with that creative, the bid will be filtered before the auction.
	//
	// Possible values:
	//   "ATTRIBUTE_UNSPECIFIED" - Do not use. This is a placeholder value
	// only.
	//   "IMAGE_RICH_MEDIA" - The creative is of type image/rich media. For
	// pretargeting.
	//   "ADOBE_FLASH_FLV" - The creative is of video type Adobe Flash FLV.
	// For pretargeting.
	//   "IS_TAGGED" - The creative is tagged.
	//   "IS_COOKIE_TARGETED" - The creative is cookie targeted.
	//   "IS_USER_INTEREST_TARGETED" - The creative is user interest
	// targeted.
	//   "EXPANDING_DIRECTION_NONE" - The creative does not expand.
	//   "EXPANDING_DIRECTION_UP" - The creative expands up.
	//   "EXPANDING_DIRECTION_DOWN" - The creative expands down.
	//   "EXPANDING_DIRECTION_LEFT" - The creative expands left.
	//   "EXPANDING_DIRECTION_RIGHT" - The creative expands right.
	//   "EXPANDING_DIRECTION_UP_LEFT" - The creative expands up and left.
	//   "EXPANDING_DIRECTION_UP_RIGHT" - The creative expands up and right.
	//   "EXPANDING_DIRECTION_DOWN_LEFT" - The creative expands down and
	// left.
	//   "EXPANDING_DIRECTION_DOWN_RIGHT" - The creative expands down and
	// right.
	//   "CREATIVE_TYPE_HTML" - The creative type is HTML.
	//   "CREATIVE_TYPE_VAST_VIDEO" - The creative type is VAST video.
	//   "EXPANDING_DIRECTION_UP_OR_DOWN" - The creative expands up or down.
	//   "EXPANDING_DIRECTION_LEFT_OR_RIGHT" - The creative expands left or
	// right.
	//   "EXPANDING_DIRECTION_ANY_DIAGONAL" - The creative expands on any
	// diagonal.
	//   "EXPANDING_ACTION_ROLLOVER_TO_EXPAND" - The creative expands when
	// rolled over.
	//   "INSTREAM_VAST_VIDEO_TYPE_VPAID_FLASH" - The instream vast video
	// type is vpaid flash.
	//   "RICH_MEDIA_CAPABILITY_TYPE_MRAID" - The creative is MRAID.
	//   "RICH_MEDIA_CAPABILITY_TYPE_FLASH" - The creative is Flash.
	//   "RICH_MEDIA_CAPABILITY_TYPE_HTML5" - The creative is HTML5.
	//   "SKIPPABLE_INSTREAM_VIDEO" - The creative has an instream VAST
	// video type of skippable instream video. For pretargeting.
	//   "RICH_MEDIA_CAPABILITY_TYPE_SSL" - The creative is SSL.
	//   "RICH_MEDIA_CAPABILITY_TYPE_NON_SSL" - The creative is non-SSL.
	//   "RICH_MEDIA_CAPABILITY_TYPE_INTERSTITIAL" - The creative is an
	// interstitial.
	//   "NON_SKIPPABLE_INSTREAM_VIDEO" - The creative has an instream VAST
	// video type of non-skippable instream video. For pretargeting.
	//   "NATIVE_ELIGIBILITY_ELIGIBLE" - The creative is eligible for
	// native.
	//   "NON_VPAID" - The creative has an instream VAST video type of
	// non-VPAID. For pretargeting.
	//   "NATIVE_ELIGIBILITY_NOT_ELIGIBLE" - The creative is not eligible
	// for native.
	//   "ANY_INTERSTITIAL" - The creative has an interstitial size of any
	// interstitial. For pretargeting.
	//   "NON_INTERSTITIAL" - The creative has an interstitial size of non
	// interstitial. For pretargeting.
	//   "IN_BANNER_VIDEO" - The video type is in-banner video.
	//   "RENDERING_SIZELESS_ADX" - The creative can dynamically resize to
	// fill a variety of slot sizes.
	//   "OMSDK_1_0" - The open measurement SDK is supported.
	DetectedAttributes []string `json:"detectedAttributes,omitempty"`

	// DetectedClickThroughUrls: The set of detected destination URLs for
	// the creative. Can be used to filter the response of the
	// creatives.list method.
	DetectedClickThroughUrls []string `json:"detectedClickThroughUrls,omitempty"`

	// DetectedDomains: The detected domains for this creative.
	DetectedDomains []string `json:"detectedDomains,omitempty"`

	// DetectedLanguages: The detected languages for this creative. The
	// order is arbitrary. The codes are 2 or 5 characters and are
	// documented at
	// https://developers.google.com/adwords/api/docs/appendix/languagecodes. Can be used to filter the response of the creatives.list
	// method.
	DetectedLanguages []string `json:"detectedLanguages,omitempty"`

	// DetectedProductCategories: Detected product categories, if any. See
	// the ad-product-categories.txt file in the technical documentation for
	// a list of IDs. Can be used to filter the response of the
	// creatives.list method.
	DetectedProductCategories []int64 `json:"detectedProductCategories,omitempty"`

	// DetectedSensitiveCategories: Detected sensitive categories, if any.
	// Can be used to filter the response of the creatives.list method. See
	// the ad-sensitive-categories.txt file in the technical documentation
	// for a list of IDs. You should use these IDs along with the
	// excluded-sensitive-category field in the bid request to filter your
	// bids.
	DetectedSensitiveCategories []int64 `json:"detectedSensitiveCategories,omitempty"`

	// DetectedVendorIds: IDs of the ad technology vendors that were
	// detected to be used by this creative. See
	// https://storage.googleapis.com/adx-rtb-dictionaries/vendors.txt for
	// possible values. Can be used to filter the response of the
	// creatives.list method. If the `allowed_vendor_type` field of a [bid
	// request](https://developers.google.com/authorized-buyers/rtb/downloads
	// /realtime-bidding-proto) does not contain one of the vendor type IDs
	// that were declared or detected for a given creative, and a bid is
	// submitted with that creative, the bid will be filtered before the
	// auction.
	DetectedVendorIds []int64 `json:"detectedVendorIds,omitempty"`

	// LastStatusUpdate: The last time the creative status was updated. Can
	// be used to filter the response of the creatives.list method.
	LastStatusUpdate string `json:"lastStatusUpdate,omitempty"`

	// OpenAuctionServingStatus: Status of this creative when bidding in
	// open auction, private auction, or auction packages (outside of Russia
	// and China).
	OpenAuctionServingStatus *ServingStatus `json:"openAuctionServingStatus,omitempty"`

	// RussiaServingStatus: The serving status of this creative in Russia.
	// When approved or disapproved, this status applies to both deals and
	// open auction in Russia. When pending review, this creative is allowed
	// to serve for deals but not for open auction.
	RussiaServingStatus *ServingStatus `json:"russiaServingStatus,omitempty"`

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

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

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

// Date: Represents a whole or partial calendar date, e.g. a birthday.
// The time of day and time zone are either specified elsewhere or are
// not significant. The date is relative to the Proleptic Gregorian
// Calendar. This can represent: * A full date, with non-zero year,
// month and day values * A month and day value, with a zero year, e.g.
// an anniversary * A year on its own, with zero month and day values *
// A year and month value, with a zero day, e.g. a credit card
// expiration date Related types are google.type.TimeOfDay and
// `google.protobuf.Timestamp`.
type Date struct {
	// Day: Day of month. Must be from 1 to 31 and valid for the year and
	// month, or 0 if specifying a year by itself or a year and month where
	// the day is not significant.
	Day int64 `json:"day,omitempty"`

	// Month: Month of year. Must be from 1 to 12, or 0 if specifying a year
	// without a month and day.
	Month int64 `json:"month,omitempty"`

	// Year: Year of date. Must be from 1 to 9999, or 0 if specifying 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	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. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// DestinationNotCrawlableEvidence: Evidence that the creative's
// destination URL was not crawlable by Google.
type DestinationNotCrawlableEvidence struct {
	// CrawlTime: Approximate time of the crawl.
	CrawlTime string `json:"crawlTime,omitempty"`

	// CrawledUrl: Destination URL that was attempted to be crawled.
	CrawledUrl string `json:"crawledUrl,omitempty"`

	// Reason: Reason of destination not crawlable.
	//
	// Possible values:
	//   "REASON_UNSPECIFIED" - Default value that should never be used.
	//   "UNREACHABLE_ROBOTS" - Site's robots exclusion file (e.g.,
	// robots.txt) was unreachable.
	//   "TIMEOUT_ROBOTS" - Timed out reading site's robots exclusion file
	// (e.g., robots.txt).
	//   "ROBOTED_DENIED" - Crawler was disallowed by the site's robots
	// exclusion file (e.g., robots.txt).
	//   "UNKNOWN" - Unknown reason.
	Reason string `json:"reason,omitempty"`

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

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

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

// DestinationNotWorkingEvidence: Evidence of the creative's destination
// URL not functioning properly or having been incorrectly set up.
type DestinationNotWorkingEvidence struct {
	// DnsError: DNS lookup errors.
	//
	// Possible values:
	//   "DNS_ERROR_UNSPECIFIED" - Default value that should never be used.
	//   "ERROR_DNS" - DNS name was not found.
	//   "GOOGLE_CRAWLER_DNS_ISSUE" - An internal issue occurred when
	// Google's crawler tried to resolve the DNS entry. This is a
	// Google-internal issue and may not be the result of an issue with the
	// landing page.
	DnsError string `json:"dnsError,omitempty"`

	// ExpandedUrl: The full non-working URL.
	ExpandedUrl string `json:"expandedUrl,omitempty"`

	// HttpError: HTTP error code (e.g. 404 or 5xx)
	HttpError int64 `json:"httpError,omitempty"`

	// InvalidPage: Page was crawled successfully, but was detected as
	// either a page with no content or an error page.
	//
	// Possible values:
	//   "INVALID_PAGE_UNSPECIFIED" - Default value that should never be
	// used.
	//   "EMPTY_OR_ERROR_PAGE" - Page was empty or had an error.
	InvalidPage string `json:"invalidPage,omitempty"`

	// LastCheckTime: Approximate time when the ad destination was last
	// checked.
	LastCheckTime string `json:"lastCheckTime,omitempty"`

	// Platform: Platform of the non-working URL.
	//
	// Possible values:
	//   "PLATFORM_UNSPECIFIED" - Default value that should never be used.
	//   "PERSONAL_COMPUTER" - The personal computer platform.
	//   "ANDROID" - The Android platform.
	//   "IOS" - The iOS platform.
	Platform string `json:"platform,omitempty"`

	// RedirectionError: HTTP redirect chain error.
	//
	// Possible values:
	//   "REDIRECTION_ERROR_UNSPECIFIED" - Default value that should never
	// be used.
	//   "TOO_MANY_REDIRECTS" - Too many redirect hops.
	//   "INVALID_REDIRECT" - Got a redirect but it was invalid.
	//   "EMPTY_REDIRECT" - Got a redirect but it was empty.
	//   "REDIRECT_ERROR_UNKNOWN" - Unknown redirect error.
	RedirectionError string `json:"redirectionError,omitempty"`

	// UrlRejected: Rejected because of malformed URLs or invalid requests.
	//
	// Possible values:
	//   "URL_REJECTED_UNSPECIFIED" - Default value that should never be
	// used.
	//   "BAD_REQUEST" - URL rejected because of a malformed request.
	//   "MALFORMED_URL" - URL rejected because of a malformed URL.
	//   "URL_REJECTED_UNKNOWN" - URL rejected because of unknown reason.
	UrlRejected string `json:"urlRejected,omitempty"`

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

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

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

// DestinationUrlEvidence: The full landing page URL of the destination.
type DestinationUrlEvidence struct {
	// DestinationUrl: The full landing page URL of the destination.
	DestinationUrl string `json:"destinationUrl,omitempty"`

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

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

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

// DomainCallEvidence: Number of HTTP calls made by a creative, broken
// down by domain.
type DomainCallEvidence struct {
	// TopHttpCallDomains: Breakdown of the most frequent domains called via
	// HTTP by the creative.
	TopHttpCallDomains []*DomainCalls `json:"topHttpCallDomains,omitempty"`

	// TotalHttpCallCount: The total number of HTTP calls made by the
	// creative, including but not limited to the number of calls in the
	// top_http_call_domains.
	TotalHttpCallCount int64 `json:"totalHttpCallCount,omitempty"`

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

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

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

// DomainCalls: The number of HTTP calls made to the given domain.
type DomainCalls struct {
	// Domain: The domain name.
	Domain string `json:"domain,omitempty"`

	// HttpCallCount: Number of HTTP calls made to the domain.
	HttpCallCount int64 `json:"httpCallCount,omitempty"`

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

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

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

// DownloadSizeEvidence: Total download size and URL-level download size
// breakdown for resources in a creative.
type DownloadSizeEvidence struct {
	// TopUrlDownloadSizeBreakdowns: Download size broken down by URLs with
	// the top download size.
	TopUrlDownloadSizeBreakdowns []*UrlDownloadSize `json:"topUrlDownloadSizeBreakdowns,omitempty"`

	// TotalDownloadSizeKb: Total download size (in kilobytes) for all the
	// resources in the creative.
	TotalDownloadSizeKb int64 `json:"totalDownloadSizeKb,omitempty"`

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

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

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

// GetRemarketingTagResponse: Response for a request to get remarketing
// tag.
type GetRemarketingTagResponse struct {
	// Snippet: A HTML tag that can be placed on the advertiser's page to
	// add users to a user list. For more information and code samples on
	// using snippet on your website refer to [Tag your site for
	// remarketing]( https://support.google.com/google-ads/answer/2476688).
	Snippet string `json:"snippet,omitempty"`

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

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

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

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

// HtmlContent: HTML content for a creative.
type HtmlContent struct {
	// Height: The height of the HTML snippet in pixels. Can be used to
	// filter the response of the creatives.list method.
	Height int64 `json:"height,omitempty"`

	// Snippet: The HTML snippet that displays the ad when inserted in the
	// web page.
	Snippet string `json:"snippet,omitempty"`

	// Width: The width of the HTML snippet in pixels. Can be used to filter
	// the response of the creatives.list method.
	Width int64 `json:"width,omitempty"`

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

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

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

// HttpCallEvidence: HTTP calls made by a creative that resulted in
// policy violations.
type HttpCallEvidence struct {
	// Urls: URLs of HTTP calls made by the creative.
	Urls []string `json:"urls,omitempty"`

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

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

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

// HttpCookieEvidence: Evidence for HTTP cookie-related policy
// violations.
type HttpCookieEvidence struct {
	// CookieNames: Names of cookies that violate Google policies. For
	// TOO_MANY_COOKIES policy, this will be the cookie names of top domains
	// with the largest number of cookies. For other policies, this will be
	// all the cookie names that violate the policy.
	CookieNames []string `json:"cookieNames,omitempty"`

	// MaxCookieCount: The largest number of cookies set by a creative. If
	// this field is set, cookie_names above will be set to the cookie names
	// of top domains with the largest number of cookies. This field will
	// only be set for TOO_MANY_COOKIES policy.
	MaxCookieCount int64 `json:"maxCookieCount,omitempty"`

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

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

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

// Image: An image resource. You may provide a larger image than was
// requested, so long as the aspect ratio is preserved.
type Image struct {
	// Height: Image height in pixels.
	Height int64 `json:"height,omitempty"`

	// Url: The URL of the image.
	Url string `json:"url,omitempty"`

	// Width: Image width in pixels.
	Width int64 `json:"width,omitempty"`

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

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

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

// ListCreativesResponse: A response for listing creatives.
type ListCreativesResponse struct {
	// Creatives: The list of creatives.
	Creatives []*Creative `json:"creatives,omitempty"`

	// NextPageToken: A token to retrieve the next page of results. Pass
	// this value in the ListCreativesRequest.pageToken field in the
	// subsequent call to the `ListCreatives` method to retrieve the next
	// page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// ListUserListsResponse: The list user list response.
type ListUserListsResponse struct {
	// NextPageToken: The continuation page token to send back to the server
	// in a subsequent request. Due to a currently known issue, it is
	// recommended that the caller keep invoking the list method till the
	// time a next page token is not returned (even if the result set is
	// empty).
	NextPageToken string `json:"nextPageToken,omitempty"`

	// UserLists: List of user lists from the search.
	UserLists []*UserList `json:"userLists,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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// MediaFile: Information about each media file in the VAST.
type MediaFile struct {
	// Bitrate: Bitrate of the video file, in Kbps. Can be used to filter
	// the response of the creatives.list method.
	Bitrate int64 `json:"bitrate,omitempty,string"`

	// MimeType: The MIME type of this media file. Can be used to filter the
	// response of the creatives.list method.
	//
	// Possible values:
	//   "VIDEO_MIME_TYPE_UNSPECIFIED" - Default value that should never be
	// used.
	//   "MIME_VIDEO_XFLV" - Flash container.
	//   "MIME_VIDEO_WEBM" - WebM container assuming VP9 codec.
	//   "MIME_VIDEO_MP4" - MPEG-4 container typically with H.264 codec.
	//   "MIME_VIDEO_OGG" - Ogg container assuming Theora codec.
	//   "MIME_VIDEO_YT_HOSTED" - Video files hosted on YouTube.
	//   "MIME_VIDEO_X_MS_WMV" - Windows Media Video Codec.
	//   "MIME_VIDEO_3GPP" - 3GPP container format used on 3G phones.
	//   "MIME_VIDEO_MOV" - Quicktime container format.
	//   "MIME_APPLICATION_SWF" - Shockwave Flash (used for VPAID ads).
	//   "MIME_APPLICATION_SURVEY" - Properties of VAST served by consumer
	// survey.
	//   "MIME_APPLICATION_JAVASCRIPT" - JavaScript (used for VPAID ads).
	//   "MIME_APPLICATION_SILVERLIGHT" - Silverlight (used for VPAID ads).
	//   "MIME_APPLICATION_MPEGURL" - HLS/M3U8.
	//   "MIME_APPLICATION_MPEGDASH" - DASH.
	//   "MIME_AUDIO_MP4A" - MPEG-4 audio format.
	//   "MIME_AUDIO_MP3" - MPEG-3 audio format.
	//   "MIME_AUDIO_OGG" - Ogg audio format
	MimeType string `json:"mimeType,omitempty"`

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

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

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

// NativeContent: Native content for a creative.
type NativeContent struct {
	// AdvertiserName: The name of the advertiser or sponsor, to be
	// displayed in the ad creative.
	AdvertiserName string `json:"advertiserName,omitempty"`

	// AppIcon: The app icon, for app download ads.
	AppIcon *Image `json:"appIcon,omitempty"`

	// Body: A long description of the ad.
	Body string `json:"body,omitempty"`

	// CallToAction: A label for the button that the user is supposed to
	// click.
	CallToAction string `json:"callToAction,omitempty"`

	// ClickLinkUrl: The URL that the browser/SDK will load when the user
	// clicks the ad.
	ClickLinkUrl string `json:"clickLinkUrl,omitempty"`

	// ClickTrackingUrl: The URL to use for click tracking.
	ClickTrackingUrl string `json:"clickTrackingUrl,omitempty"`

	// Headline: A short title for the ad.
	Headline string `json:"headline,omitempty"`

	// Image: A large image.
	Image *Image `json:"image,omitempty"`

	// Logo: A smaller image, for the advertiser's logo.
	Logo *Image `json:"logo,omitempty"`

	// PriceDisplayText: The price of the promoted app including currency
	// info.
	PriceDisplayText string `json:"priceDisplayText,omitempty"`

	// StarRating: The app rating in the app store. Must be in the range
	// [0-5].
	StarRating float64 `json:"starRating,omitempty"`

	// VideoUrl: The URL to fetch a native video ad.
	VideoUrl string `json:"videoUrl,omitempty"`

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

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

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

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

// OpenUserListRequest: A request to open a specified user list.
type OpenUserListRequest struct {
}

// PolicyTopicEntry: Each policy topic entry will represent a violation
// of a policy topic for a creative, with the policy topic information
// and optional evidence for the policy violation.
type PolicyTopicEntry struct {
	// Evidences: Pieces of evidence associated with this policy topic
	// entry.
	Evidences []*PolicyTopicEvidence `json:"evidences,omitempty"`

	// HelpCenterUrl: URL of the help center article describing this policy
	// topic.
	HelpCenterUrl string `json:"helpCenterUrl,omitempty"`

	// PolicyTopic: Policy topic this entry refers to. For example,
	// "ALCOHOL", "TRADEMARKS_IN_AD_TEXT", or "DESTINATION_NOT_WORKING". The
	// set of possible policy topics is not fixed for a particular API
	// version and may change at any time. Can be used to filter the
	// response of the creatives.list method
	PolicyTopic string `json:"policyTopic,omitempty"`

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

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

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

// PolicyTopicEvidence: Evidence associated with a policy topic entry.
type PolicyTopicEvidence struct {
	// DestinationNotCrawlable: The creative's destination URL was not
	// crawlable by Google.
	DestinationNotCrawlable *DestinationNotCrawlableEvidence `json:"destinationNotCrawlable,omitempty"`

	// DestinationNotWorking: The creative's destination URL did not
	// function properly or was incorrectly set up.
	DestinationNotWorking *DestinationNotWorkingEvidence `json:"destinationNotWorking,omitempty"`

	// DestinationUrl: URL of the actual landing page.
	DestinationUrl *DestinationUrlEvidence `json:"destinationUrl,omitempty"`

	// DomainCall: Number of HTTP calls made by the creative, broken down by
	// domain.
	DomainCall *DomainCallEvidence `json:"domainCall,omitempty"`

	// DownloadSize: Total download size and URL-level download size
	// breakdown for resources in a creative.
	DownloadSize *DownloadSizeEvidence `json:"downloadSize,omitempty"`

	// HttpCall: HTTP calls made by the creative that resulted in policy
	// violations.
	HttpCall *HttpCallEvidence `json:"httpCall,omitempty"`

	// HttpCookie: Evidence for HTTP cookie-related policy violations.
	HttpCookie *HttpCookieEvidence `json:"httpCookie,omitempty"`

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

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

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

// ServingStatus: Serving status of the creative for a transaction type
// or a region.
type ServingStatus struct {
	// Status: Serving status for the given transaction type (e.g., open
	// auction, deals) or region (e.g., China, Russia). Can be used to
	// filter the response of the creatives.list method.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Default value that should never be used.
	//   "PENDING_REVIEW" - Creative is pending review.
	//   "DISAPPROVED" - Creative cannot serve.
	//   "APPROVED" - Creative is approved.
	Status string `json:"status,omitempty"`

	// Topics: Policy topics related to the serving decision for this
	// transaction type (e.g., open auction, deals) or region (e.g., China,
	// Russia). Topics may be present only if status is DISAPPROVED.
	Topics []*PolicyTopicEntry `json:"topics,omitempty"`

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

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

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

// UrlDownloadSize: The URL-level breakdown for the download size.
type UrlDownloadSize struct {
	// DownloadSizeKb: Download size of the URL in kilobytes.
	DownloadSizeKb int64 `json:"downloadSizeKb,omitempty"`

	// NormalizedUrl: The normalized URL with query parameters and fragment
	// removed.
	NormalizedUrl string `json:"normalizedUrl,omitempty"`

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

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

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

// UrlRestriction: Represents the URL restriction (for the URL captured
// by the pixel callback) for a user list.
type UrlRestriction struct {
	// EndDate: End date (if specified) of the URL restriction. End date
	// should be later than the start date for the date range to be valid.
	EndDate *Date `json:"endDate,omitempty"`

	// RestrictionType: The restriction type for the specified URL.
	//
	// Possible values:
	//   "RESTRICTION_TYPE_UNSPECIFIED" - Default value that should never be
	// used.
	//   "CONTAINS" - The tag URL (as recorded by the pixel callback)
	// contains the specified URL.
	//   "EQUALS" - The tag URL (as recorded by the pixel callback) exactly
	// matches the specified URL.
	//   "STARTS_WITH" - The tag URL (as recorded by the pixel callback)
	// starts with the specified URL.
	//   "ENDS_WITH" - The tag URL (as recorded by the pixel callback) ends
	// with the specified URL.
	//   "DOES_NOT_EQUAL" - The tag URL (as recorded by the pixel callback)
	// does not equal the specified URL.
	//   "DOES_NOT_CONTAIN" - The tag URL (as recorded by the pixel
	// callback) does not contain the specified URL.
	//   "DOES_NOT_START_WITH" - The tag URL (as recorded by the pixel
	// callback) does not start with the specified URL.
	//   "DOES_NOT_END_WITH" - The tag URL (as recorded by the pixel
	// callback) does not end with the specified URL.
	RestrictionType string `json:"restrictionType,omitempty"`

	// StartDate: Start date (if specified) of the URL restriction.
	StartDate *Date `json:"startDate,omitempty"`

	// Url: Required. The URL to use for applying the restriction on the
	// user list.
	Url string `json:"url,omitempty"`

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

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

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

// UserList: Represents an Authorized Buyers user list. Authorized
// Buyers can create/update/list user lists. Once a user list is created
// in the system, Authorized Buyers can add users to the user list using
// the bulk uploader API. Alternatively, users can be added by hosting a
// tag on the advertiser's page.
type UserList struct {
	// Description: The description for the user list.
	Description string `json:"description,omitempty"`

	// DisplayName: Required. Display name of the user list. This must be
	// unique across all user lists for a given account.
	DisplayName string `json:"displayName,omitempty"`

	// MembershipDurationDays: Required. The number of days a user's cookie
	// stays on the user list. The field must be between 0 and 540
	// inclusive.
	MembershipDurationDays int64 `json:"membershipDurationDays,omitempty,string"`

	// Name: Output only. Name of the user list that must follow the pattern
	// `buyers/{buyer}/userLists/{user_list}`, where `{buyer}` represents
	// the account ID of the buyer who owns the user list. For a bidder
	// accessing user lists on behalf of a child seat buyer, `{buyer}`
	// represents the account ID of the child seat buyer. `{user_list}` is
	// an int64 identifier assigned by Google to uniquely identify a user
	// list.
	Name string `json:"name,omitempty"`

	// Status: Output only. The status of the user list. A new user list
	// starts out as open.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Default value that should never be used.
	//   "OPEN" - New users can be added to the user list.
	//   "CLOSED" - New users cannot be added to the user list.
	Status string `json:"status,omitempty"`

	// UrlRestriction: Required. The URL restriction for the user list.
	UrlRestriction *UrlRestriction `json:"urlRestriction,omitempty"`

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

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

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

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

// VideoContent: Video content for a creative.
type VideoContent struct {
	// VideoMetadata: Output only. Video metadata.
	VideoMetadata *VideoMetadata `json:"videoMetadata,omitempty"`

	// VideoUrl: The URL to fetch a video ad.
	VideoUrl string `json:"videoUrl,omitempty"`

	// VideoVastXml: The contents of a VAST document for a video ad. This
	// document should conform to the VAST 2.0 or 3.0 standard.
	VideoVastXml string `json:"videoVastXml,omitempty"`

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

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

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

// VideoMetadata: Video metadata for a creative.
type VideoMetadata struct {
	// Duration: The duration of the ad. Can be used to filter the response
	// of the creatives.list method.
	Duration string `json:"duration,omitempty"`

	// IsValidVast: Is this a valid VAST ad? Can be used to filter the
	// response of the creatives.list method.
	IsValidVast bool `json:"isValidVast,omitempty"`

	// IsVpaid: Is this a VPAID ad? Can be used to filter the response of
	// the creatives.list method.
	IsVpaid bool `json:"isVpaid,omitempty"`

	// MediaFiles: The list of all media files declared in the VAST. If
	// there are multiple VASTs in a wrapper chain, this includes the media
	// files from the deepest one in the chain.
	MediaFiles []*MediaFile `json:"mediaFiles,omitempty"`

	// SkipOffset: The minimum duration that the user has to watch before
	// being able to skip this ad. If the field is not set, the ad is not
	// skippable. If the field is set, the ad is skippable. Can be used to
	// filter the response of the creatives.list method.
	SkipOffset string `json:"skipOffset,omitempty"`

	// VastVersion: The maximum VAST version across all wrapped VAST
	// documents. Can be used to filter the response of the creatives.list
	// method.
	//
	// Possible values:
	//   "VAST_VERSION_UNSPECIFIED" - Default value that should never be
	// used.
	//   "VAST_VERSION_1_0" - VAST 1.0
	//   "VAST_VERSION_2_0" - VAST 2.0
	//   "VAST_VERSION_3_0" - VAST 3.0
	//   "VAST_VERSION_4_0" - VAST 4.0
	VastVersion string `json:"vastVersion,omitempty"`

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

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

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

// WatchCreativesRequest: A request to receive push notifications when
// any of the creatives belonging to the bidder changes status.
type WatchCreativesRequest struct {
}

// WatchCreativesResponse: A response for the request to receive push
// notification when a bidder's creatives change status.
type WatchCreativesResponse struct {
	// Subscription: The Pub/Sub subscription that can be used to pull
	// creative status notifications. This would be of the format
	// `projects/{project_id}/subscriptions/{subscription_id}`. Subscription
	// is created with pull delivery. All service accounts belonging to the
	// bidder will have read access to this subscription. Subscriptions that
	// are inactive for more than 90 days will be disabled. Please use
	// watchCreatives to re-enable the subscription.
	Subscription string `json:"subscription,omitempty"`

	// Topic: The Pub/Sub topic that will be used to publish creative
	// serving status notifications. This would be of the format
	// `projects/{project_id}/topics/{topic_id}`.
	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. "Subscription") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// method id "realtimebidding.bidders.creatives.list":

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

// List: Lists creatives.
func (r *BiddersCreativesService) List(parent string) *BiddersCreativesListCall {
	c := &BiddersCreativesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Query string to filter
// creatives. If no filter is specified, all active creatives will be
// returned. Example: 'accountId=12345 AND (dealsStatus:DISAPPROVED AND
// disapprovalReason:UNACCEPTABLE_CONTENT) OR
// declaredAttributes:IS_COOKIE_TARGETED'
func (c *BiddersCreativesListCall) Filter(filter string) *BiddersCreativesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// The server may return fewer creatives than requested (due to timeout
// constraint) even if more are available via another call. If
// unspecified, server will pick an appropriate default. Acceptable
// values are 1 to 1000, inclusive.
func (c *BiddersCreativesListCall) PageSize(pageSize int64) *BiddersCreativesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results the server should return. Typically,
// this is the value of ListCreativesResponse.nextPageToken returned
// from the previous call to the 'ListCreatives' method.
func (c *BiddersCreativesListCall) PageToken(pageToken string) *BiddersCreativesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// View sets the optional parameter "view": Controls the amount of
// information included in the response. By default only
// creativeServingDecision is included. To retrieve the entire creative
// resource (including the declared fields and the creative content)
// specify the view as "FULL".
//
// Possible values:
//   "CREATIVE_VIEW_UNSPECIFIED" - Not specified, equivalent to
// SERVING_DECISION_ONLY.
//   "SERVING_DECISION_ONLY" - Only creativeServingDecision is included
// in the response.
//   "FULL" - The entire creative resource (including the declared
// fields and the creative content) is included in the response.
func (c *BiddersCreativesListCall) View(view string) *BiddersCreativesListCall {
	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 information.
func (c *BiddersCreativesListCall) Fields(s ...googleapi.Field) *BiddersCreativesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BiddersCreativesListCall) IfNoneMatch(entityTag string) *BiddersCreativesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BiddersCreativesListCall) Context(ctx context.Context) *BiddersCreativesListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.bidders.creatives.list" call.
// Exactly one of *ListCreativesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListCreativesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BiddersCreativesListCall) Do(opts ...googleapi.CallOption) (*ListCreativesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListCreativesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists creatives.",
	//   "flatPath": "v1/bidders/{biddersId}/creatives",
	//   "httpMethod": "GET",
	//   "id": "realtimebidding.bidders.creatives.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Query string to filter creatives. If no filter is specified, all active creatives will be returned. Example: 'accountId=12345 AND (dealsStatus:DISAPPROVED AND disapprovalReason:UNACCEPTABLE_CONTENT) OR declaredAttributes:IS_COOKIE_TARGETED'",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. The server may return fewer creatives than requested (due to timeout constraint) even if more are available via another call. If unspecified, server will pick an appropriate default. Acceptable values are 1 to 1000, inclusive.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results the server should return. Typically, this is the value of ListCreativesResponse.nextPageToken returned from the previous call to the 'ListCreatives' method.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the parent buyer that owns the creatives. The pattern for this resource is either `buyers/{buyerAccountId}` or `bidders/{bidderAccountId}`. For `buyers/{buyerAccountId}`, the `buyerAccountId` can be one of the following: 1. The ID of the buyer that is accessing their own creatives. 2. The ID of the child seat buyer under a bidder account. So for listing creatives pertaining to the child seat buyer (`456`) under bidder account (`123`), you would use the pattern: `buyers/456`. 3. The ID of the bidder itself. So for listing creatives pertaining to bidder (`123`), you would use `buyers/123`. If you want to access all creatives pertaining to both the bidder and all of its child seat accounts, you would use `bidders/{bidderAccountId}`, e.g., for all creatives pertaining to bidder (`123`), use `bidders/123`.",
	//       "location": "path",
	//       "pattern": "^bidders/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Controls the amount of information included in the response. By default only creativeServingDecision is included. To retrieve the entire creative resource (including the declared fields and the creative content) specify the view as \"FULL\".",
	//       "enum": [
	//         "CREATIVE_VIEW_UNSPECIFIED",
	//         "SERVING_DECISION_ONLY",
	//         "FULL"
	//       ],
	//       "enumDescriptions": [
	//         "Not specified, equivalent to SERVING_DECISION_ONLY.",
	//         "Only creativeServingDecision is included in the response.",
	//         "The entire creative resource (including the declared fields and the creative content) is included in the response."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/creatives",
	//   "response": {
	//     "$ref": "ListCreativesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// 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 *BiddersCreativesListCall) Pages(ctx context.Context, f func(*ListCreativesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "realtimebidding.bidders.creatives.watch":

type BiddersCreativesWatchCall struct {
	s                     *Service
	parent                string
	watchcreativesrequest *WatchCreativesRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Watch: Watches all creatives pertaining to a bidder. It is sufficient
// to invoke this endpoint once per bidder. A Pub/Sub topic will be
// created and notifications will be pushed to the topic when any of the
// bidder's creatives change status. All of the bidder's service
// accounts will have access to read from the topic. Subsequent
// invocations of this method will return the existing Pub/Sub
// configuration.
func (r *BiddersCreativesService) Watch(parent string, watchcreativesrequest *WatchCreativesRequest) *BiddersCreativesWatchCall {
	c := &BiddersCreativesWatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.watchcreativesrequest = watchcreativesrequest
	return c
}

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

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BiddersCreativesWatchCall) Context(ctx context.Context) *BiddersCreativesWatchCall {
	c.ctx_ = ctx
	return c
}

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

func (c *BiddersCreativesWatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.watchcreativesrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/creatives:watch")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "realtimebidding.bidders.creatives.watch" call.
// Exactly one of *WatchCreativesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *WatchCreativesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BiddersCreativesWatchCall) Do(opts ...googleapi.CallOption) (*WatchCreativesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &WatchCreativesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Watches all creatives pertaining to a bidder. It is sufficient to invoke this endpoint once per bidder. A Pub/Sub topic will be created and notifications will be pushed to the topic when any of the bidder's creatives change status. All of the bidder's service accounts will have access to read from the topic. Subsequent invocations of this method will return the existing Pub/Sub configuration.",
	//   "flatPath": "v1/bidders/{biddersId}/creatives:watch",
	//   "httpMethod": "POST",
	//   "id": "realtimebidding.bidders.creatives.watch",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. To watch all creatives pertaining to the bidder and all its child seat accounts, the bidder must follow the pattern `bidders/{bidderAccountId}`.",
	//       "location": "path",
	//       "pattern": "^bidders/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/creatives:watch",
	//   "request": {
	//     "$ref": "WatchCreativesRequest"
	//   },
	//   "response": {
	//     "$ref": "WatchCreativesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.getRemarketingTag":

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

// GetRemarketingTag: Gets remarketing tag for a buyer. A remarketing
// tag is a piece of JavaScript code that can be placed on a web page.
// When a user visits a page containing a remarketing tag, Google adds
// the user to a user list.
func (r *BuyersService) GetRemarketingTag(name string) *BuyersGetRemarketingTagCall {
	c := &BuyersGetRemarketingTagCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BuyersGetRemarketingTagCall) IfNoneMatch(entityTag string) *BuyersGetRemarketingTagCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersGetRemarketingTagCall) Context(ctx context.Context) *BuyersGetRemarketingTagCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.getRemarketingTag" call.
// Exactly one of *GetRemarketingTagResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GetRemarketingTagResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BuyersGetRemarketingTagCall) Do(opts ...googleapi.CallOption) (*GetRemarketingTagResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetRemarketingTagResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets remarketing tag for a buyer. A remarketing tag is a piece of JavaScript code that can be placed on a web page. When a user visits a page containing a remarketing tag, Google adds the user to a user list.",
	//   "flatPath": "v1/buyers/{buyersId}:getRemarketingTag",
	//   "httpMethod": "GET",
	//   "id": "realtimebidding.buyers.getRemarketingTag",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. To fetch remarketing tag for an account, name must follow the pattern `buyers/{accountId}` where `{accountId}` represents ID of a buyer that owns the remarketing tag. For a bidder accessing remarketing tag on behalf of a child seat buyer, `{accountId}` should represent the ID of the child seat buyer. To fetch remarketing tag for a specific user list, name must follow the pattern `buyers/{accountId}/userLists/{userListId}`. See UserList.name.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:getRemarketingTag",
	//   "response": {
	//     "$ref": "GetRemarketingTagResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.creatives.create":

type BuyersCreativesCreateCall struct {
	s          *Service
	parent     string
	creative   *Creative
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a creative.
func (r *BuyersCreativesService) Create(parent string, creative *Creative) *BuyersCreativesCreateCall {
	c := &BuyersCreativesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.creative = creative
	return c
}

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

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersCreativesCreateCall) Context(ctx context.Context) *BuyersCreativesCreateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *BuyersCreativesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creative)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/creatives")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "realtimebidding.buyers.creatives.create" call.
// Exactly one of *Creative or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Creative.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersCreativesCreateCall) Do(opts ...googleapi.CallOption) (*Creative, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Creative{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a creative.",
	//   "flatPath": "v1/buyers/{buyersId}/creatives",
	//   "httpMethod": "POST",
	//   "id": "realtimebidding.buyers.creatives.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the parent buyer that the new creative belongs to that must follow the pattern `buyers/{buyerAccountId}`, where `{buyerAccountId}` represents the account ID of the buyer who owns a creative. For a bidder accessing creatives on behalf of a child seat buyer, `{buyerAccountId}` should represent the account ID of the child seat buyer.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/creatives",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.creatives.get":

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

// Get: Gets a creative.
func (r *BuyersCreativesService) Get(name string) *BuyersCreativesGetCall {
	c := &BuyersCreativesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// View sets the optional parameter "view": Controls the amount of
// information included in the response. By default only
// creativeServingDecision is included. To retrieve the entire creative
// resource (including the declared fields and the creative content)
// specify the view as "FULL".
//
// Possible values:
//   "CREATIVE_VIEW_UNSPECIFIED" - Not specified, equivalent to
// SERVING_DECISION_ONLY.
//   "SERVING_DECISION_ONLY" - Only creativeServingDecision is included
// in the response.
//   "FULL" - The entire creative resource (including the declared
// fields and the creative content) is included in the response.
func (c *BuyersCreativesGetCall) View(view string) *BuyersCreativesGetCall {
	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 information.
func (c *BuyersCreativesGetCall) Fields(s ...googleapi.Field) *BuyersCreativesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BuyersCreativesGetCall) IfNoneMatch(entityTag string) *BuyersCreativesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersCreativesGetCall) Context(ctx context.Context) *BuyersCreativesGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.creatives.get" call.
// Exactly one of *Creative or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Creative.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersCreativesGetCall) Do(opts ...googleapi.CallOption) (*Creative, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Creative{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a creative.",
	//   "flatPath": "v1/buyers/{buyersId}/creatives/{creativesId}",
	//   "httpMethod": "GET",
	//   "id": "realtimebidding.buyers.creatives.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the creative to retrieve. See creative.name.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/creatives/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Controls the amount of information included in the response. By default only creativeServingDecision is included. To retrieve the entire creative resource (including the declared fields and the creative content) specify the view as \"FULL\".",
	//       "enum": [
	//         "CREATIVE_VIEW_UNSPECIFIED",
	//         "SERVING_DECISION_ONLY",
	//         "FULL"
	//       ],
	//       "enumDescriptions": [
	//         "Not specified, equivalent to SERVING_DECISION_ONLY.",
	//         "Only creativeServingDecision is included in the response.",
	//         "The entire creative resource (including the declared fields and the creative content) is included in the response."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.creatives.list":

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

// List: Lists creatives.
func (r *BuyersCreativesService) List(parent string) *BuyersCreativesListCall {
	c := &BuyersCreativesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// Filter sets the optional parameter "filter": Query string to filter
// creatives. If no filter is specified, all active creatives will be
// returned. Example: 'accountId=12345 AND (dealsStatus:DISAPPROVED AND
// disapprovalReason:UNACCEPTABLE_CONTENT) OR
// declaredAttributes:IS_COOKIE_TARGETED'
func (c *BuyersCreativesListCall) Filter(filter string) *BuyersCreativesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// The server may return fewer creatives than requested (due to timeout
// constraint) even if more are available via another call. If
// unspecified, server will pick an appropriate default. Acceptable
// values are 1 to 1000, inclusive.
func (c *BuyersCreativesListCall) PageSize(pageSize int64) *BuyersCreativesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results the server should return. Typically,
// this is the value of ListCreativesResponse.nextPageToken returned
// from the previous call to the 'ListCreatives' method.
func (c *BuyersCreativesListCall) PageToken(pageToken string) *BuyersCreativesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// View sets the optional parameter "view": Controls the amount of
// information included in the response. By default only
// creativeServingDecision is included. To retrieve the entire creative
// resource (including the declared fields and the creative content)
// specify the view as "FULL".
//
// Possible values:
//   "CREATIVE_VIEW_UNSPECIFIED" - Not specified, equivalent to
// SERVING_DECISION_ONLY.
//   "SERVING_DECISION_ONLY" - Only creativeServingDecision is included
// in the response.
//   "FULL" - The entire creative resource (including the declared
// fields and the creative content) is included in the response.
func (c *BuyersCreativesListCall) View(view string) *BuyersCreativesListCall {
	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 information.
func (c *BuyersCreativesListCall) Fields(s ...googleapi.Field) *BuyersCreativesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BuyersCreativesListCall) IfNoneMatch(entityTag string) *BuyersCreativesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersCreativesListCall) Context(ctx context.Context) *BuyersCreativesListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.creatives.list" call.
// Exactly one of *ListCreativesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListCreativesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BuyersCreativesListCall) Do(opts ...googleapi.CallOption) (*ListCreativesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListCreativesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists creatives.",
	//   "flatPath": "v1/buyers/{buyersId}/creatives",
	//   "httpMethod": "GET",
	//   "id": "realtimebidding.buyers.creatives.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "Query string to filter creatives. If no filter is specified, all active creatives will be returned. Example: 'accountId=12345 AND (dealsStatus:DISAPPROVED AND disapprovalReason:UNACCEPTABLE_CONTENT) OR declaredAttributes:IS_COOKIE_TARGETED'",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. The server may return fewer creatives than requested (due to timeout constraint) even if more are available via another call. If unspecified, server will pick an appropriate default. Acceptable values are 1 to 1000, inclusive.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results the server should return. Typically, this is the value of ListCreativesResponse.nextPageToken returned from the previous call to the 'ListCreatives' method.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the parent buyer that owns the creatives. The pattern for this resource is either `buyers/{buyerAccountId}` or `bidders/{bidderAccountId}`. For `buyers/{buyerAccountId}`, the `buyerAccountId` can be one of the following: 1. The ID of the buyer that is accessing their own creatives. 2. The ID of the child seat buyer under a bidder account. So for listing creatives pertaining to the child seat buyer (`456`) under bidder account (`123`), you would use the pattern: `buyers/456`. 3. The ID of the bidder itself. So for listing creatives pertaining to bidder (`123`), you would use `buyers/123`. If you want to access all creatives pertaining to both the bidder and all of its child seat accounts, you would use `bidders/{bidderAccountId}`, e.g., for all creatives pertaining to bidder (`123`), use `bidders/123`.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Controls the amount of information included in the response. By default only creativeServingDecision is included. To retrieve the entire creative resource (including the declared fields and the creative content) specify the view as \"FULL\".",
	//       "enum": [
	//         "CREATIVE_VIEW_UNSPECIFIED",
	//         "SERVING_DECISION_ONLY",
	//         "FULL"
	//       ],
	//       "enumDescriptions": [
	//         "Not specified, equivalent to SERVING_DECISION_ONLY.",
	//         "Only creativeServingDecision is included in the response.",
	//         "The entire creative resource (including the declared fields and the creative content) is included in the response."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/creatives",
	//   "response": {
	//     "$ref": "ListCreativesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// 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 *BuyersCreativesListCall) Pages(ctx context.Context, f func(*ListCreativesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "realtimebidding.buyers.creatives.patch":

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

// Patch: Updates a creative.
func (r *BuyersCreativesService) Patch(name string, creative *Creative) *BuyersCreativesPatchCall {
	c := &BuyersCreativesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.creative = creative
	return c
}

// UpdateMask sets the optional parameter "updateMask": Field mask to
// use for partial in-place updates.
func (c *BuyersCreativesPatchCall) UpdateMask(updateMask string) *BuyersCreativesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersCreativesPatchCall) Context(ctx context.Context) *BuyersCreativesPatchCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.creatives.patch" call.
// Exactly one of *Creative or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Creative.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersCreativesPatchCall) Do(opts ...googleapi.CallOption) (*Creative, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Creative{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a creative.",
	//   "flatPath": "v1/buyers/{buyersId}/creatives/{creativesId}",
	//   "httpMethod": "PATCH",
	//   "id": "realtimebidding.buyers.creatives.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the creative. Follows the pattern `buyers/{buyer}/creatives/{creative}`, where `{buyer}` represents the account ID of the buyer who owns the creative, and `{creative}` is the buyer-specific creative ID that references this creative in the bid response.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/creatives/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Field mask to use for partial in-place updates.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.userLists.close":

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

// Close: Change the status of a user list to CLOSED. This prevents new
// users from being added to the user list.
func (r *BuyersUserListsService) Close(name string, closeuserlistrequest *CloseUserListRequest) *BuyersUserListsCloseCall {
	c := &BuyersUserListsCloseCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.closeuserlistrequest = closeuserlistrequest
	return c
}

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

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersUserListsCloseCall) Context(ctx context.Context) *BuyersUserListsCloseCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.userLists.close" call.
// Exactly one of *UserList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersUserListsCloseCall) Do(opts ...googleapi.CallOption) (*UserList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Change the status of a user list to CLOSED. This prevents new users from being added to the user list.",
	//   "flatPath": "v1/buyers/{buyersId}/userLists/{userListsId}:close",
	//   "httpMethod": "POST",
	//   "id": "realtimebidding.buyers.userLists.close",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the user list to close. See UserList.name",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/userLists/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:close",
	//   "request": {
	//     "$ref": "CloseUserListRequest"
	//   },
	//   "response": {
	//     "$ref": "UserList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.userLists.create":

type BuyersUserListsCreateCall struct {
	s          *Service
	parent     string
	userlist   *UserList
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Create a new user list.
func (r *BuyersUserListsService) Create(parent string, userlist *UserList) *BuyersUserListsCreateCall {
	c := &BuyersUserListsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.userlist = userlist
	return c
}

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

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersUserListsCreateCall) Context(ctx context.Context) *BuyersUserListsCreateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *BuyersUserListsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200926")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.userlist)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/userLists")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "realtimebidding.buyers.userLists.create" call.
// Exactly one of *UserList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersUserListsCreateCall) Do(opts ...googleapi.CallOption) (*UserList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Create a new user list.",
	//   "flatPath": "v1/buyers/{buyersId}/userLists",
	//   "httpMethod": "POST",
	//   "id": "realtimebidding.buyers.userLists.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the parent buyer of the user list to be retrieved that must follow the pattern `buyers/{buyerAccountId}`, where `{buyerAccountId}` represents the account ID of the buyer who owns user lists. For a bidder accessing user lists on behalf of a child seat buyer , `{buyerAccountId}` should represent the account ID of the child seat buyer.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/userLists",
	//   "request": {
	//     "$ref": "UserList"
	//   },
	//   "response": {
	//     "$ref": "UserList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.userLists.get":

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

// Get: Gets a user list by its name.
func (r *BuyersUserListsService) Get(name string) *BuyersUserListsGetCall {
	c := &BuyersUserListsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BuyersUserListsGetCall) IfNoneMatch(entityTag string) *BuyersUserListsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersUserListsGetCall) Context(ctx context.Context) *BuyersUserListsGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.userLists.get" call.
// Exactly one of *UserList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersUserListsGetCall) Do(opts ...googleapi.CallOption) (*UserList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a user list by its name.",
	//   "flatPath": "v1/buyers/{buyersId}/userLists/{userListsId}",
	//   "httpMethod": "GET",
	//   "id": "realtimebidding.buyers.userLists.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the user list to be retrieved. See UserList.name.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/userLists/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "UserList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.userLists.getRemarketingTag":

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

// GetRemarketingTag: Gets remarketing tag for a buyer. A remarketing
// tag is a piece of JavaScript code that can be placed on a web page.
// When a user visits a page containing a remarketing tag, Google adds
// the user to a user list.
func (r *BuyersUserListsService) GetRemarketingTag(name string) *BuyersUserListsGetRemarketingTagCall {
	c := &BuyersUserListsGetRemarketingTagCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BuyersUserListsGetRemarketingTagCall) IfNoneMatch(entityTag string) *BuyersUserListsGetRemarketingTagCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersUserListsGetRemarketingTagCall) Context(ctx context.Context) *BuyersUserListsGetRemarketingTagCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.userLists.getRemarketingTag" call.
// Exactly one of *GetRemarketingTagResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GetRemarketingTagResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BuyersUserListsGetRemarketingTagCall) Do(opts ...googleapi.CallOption) (*GetRemarketingTagResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetRemarketingTagResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets remarketing tag for a buyer. A remarketing tag is a piece of JavaScript code that can be placed on a web page. When a user visits a page containing a remarketing tag, Google adds the user to a user list.",
	//   "flatPath": "v1/buyers/{buyersId}/userLists/{userListsId}:getRemarketingTag",
	//   "httpMethod": "GET",
	//   "id": "realtimebidding.buyers.userLists.getRemarketingTag",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. To fetch remarketing tag for an account, name must follow the pattern `buyers/{accountId}` where `{accountId}` represents ID of a buyer that owns the remarketing tag. For a bidder accessing remarketing tag on behalf of a child seat buyer, `{accountId}` should represent the ID of the child seat buyer. To fetch remarketing tag for a specific user list, name must follow the pattern `buyers/{accountId}/userLists/{userListId}`. See UserList.name.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/userLists/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:getRemarketingTag",
	//   "response": {
	//     "$ref": "GetRemarketingTagResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.userLists.list":

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

// List: Lists the user lists visible to the current user.
func (r *BuyersUserListsService) List(parent string) *BuyersUserListsListCall {
	c := &BuyersUserListsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

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

// PageToken sets the optional parameter "pageToken": Continuation page
// token (as received from a previous response).
func (c *BuyersUserListsListCall) PageToken(pageToken string) *BuyersUserListsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BuyersUserListsListCall) IfNoneMatch(entityTag string) *BuyersUserListsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersUserListsListCall) Context(ctx context.Context) *BuyersUserListsListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.userLists.list" call.
// Exactly one of *ListUserListsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListUserListsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BuyersUserListsListCall) Do(opts ...googleapi.CallOption) (*ListUserListsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListUserListsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists the user lists visible to the current user.",
	//   "flatPath": "v1/buyers/{buyersId}/userLists",
	//   "httpMethod": "GET",
	//   "id": "realtimebidding.buyers.userLists.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "The number of results to return per page.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Continuation page token (as received from a previous response).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The name of the parent buyer for the user lists to be returned that must follow the pattern `buyers/{buyerAccountId}`, where `{buyerAccountId}` represents the account ID of the buyer who owns user lists. For a bidder accessing user lists on behalf of a child seat buyer , `{buyerAccountId}` should represent the account ID of the child seat buyer.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/userLists",
	//   "response": {
	//     "$ref": "ListUserListsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// 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 *BuyersUserListsListCall) Pages(ctx context.Context, f func(*ListUserListsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "realtimebidding.buyers.userLists.open":

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

// Open: Change the status of a user list to OPEN. This allows new users
// to be added to the user list.
func (r *BuyersUserListsService) Open(name string, openuserlistrequest *OpenUserListRequest) *BuyersUserListsOpenCall {
	c := &BuyersUserListsOpenCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.openuserlistrequest = openuserlistrequest
	return c
}

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

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersUserListsOpenCall) Context(ctx context.Context) *BuyersUserListsOpenCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.userLists.open" call.
// Exactly one of *UserList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersUserListsOpenCall) Do(opts ...googleapi.CallOption) (*UserList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Change the status of a user list to OPEN. This allows new users to be added to the user list.",
	//   "flatPath": "v1/buyers/{buyersId}/userLists/{userListsId}:open",
	//   "httpMethod": "POST",
	//   "id": "realtimebidding.buyers.userLists.open",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the user list to open. See UserList.name",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/userLists/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:open",
	//   "request": {
	//     "$ref": "OpenUserListRequest"
	//   },
	//   "response": {
	//     "$ref": "UserList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}

// method id "realtimebidding.buyers.userLists.update":

type BuyersUserListsUpdateCall struct {
	s          *Service
	nameid     string
	userlist   *UserList
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Update the given user list. Only user lists with
// URLRestrictions can be updated.
func (r *BuyersUserListsService) Update(nameid string, userlist *UserList) *BuyersUserListsUpdateCall {
	c := &BuyersUserListsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.userlist = userlist
	return c
}

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

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BuyersUserListsUpdateCall) Context(ctx context.Context) *BuyersUserListsUpdateCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "realtimebidding.buyers.userLists.update" call.
// Exactly one of *UserList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersUserListsUpdateCall) Do(opts ...googleapi.CallOption) (*UserList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Update the given user list. Only user lists with URLRestrictions can be updated.",
	//   "flatPath": "v1/buyers/{buyersId}/userLists/{userListsId}",
	//   "httpMethod": "PUT",
	//   "id": "realtimebidding.buyers.userLists.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Output only. Name of the user list that must follow the pattern `buyers/{buyer}/userLists/{user_list}`, where `{buyer}` represents the account ID of the buyer who owns the user list. For a bidder accessing user lists on behalf of a child seat buyer, `{buyer}` represents the account ID of the child seat buyer. `{user_list}` is an int64 identifier assigned by Google to uniquely identify a user list.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/userLists/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "UserList"
	//   },
	//   "response": {
	//     "$ref": "UserList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}
