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

// 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: Output only. 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 {
	// ChinaPolicyCompliance: The policy compliance of this creative in
	// China. When approved or disapproved, this 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.
	ChinaPolicyCompliance *PolicyCompliance `json:"chinaPolicyCompliance,omitempty"`

	// DealsPolicyCompliance: Policy compliance of this creative when
	// bidding on Programmatic Guaranteed and Preferred Deals (outside of
	// Russia and China).
	DealsPolicyCompliance *PolicyCompliance `json:"dealsPolicyCompliance,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"`

	// NetworkPolicyCompliance: Policy compliance of this creative when
	// bidding in open auction, private auction, or auction packages
	// (outside of Russia and China).
	NetworkPolicyCompliance *PolicyCompliance `json:"networkPolicyCompliance,omitempty"`

	// PlatformPolicyCompliance: Policy compliance of this creative when
	// bidding in Open Bidding (outside of Russia and China). For the list
	// of platform policies, see:
	// https://support.google.com/platformspolicy/answer/3013851.
	PlatformPolicyCompliance *PolicyCompliance `json:"platformPolicyCompliance,omitempty"`

	// RussiaPolicyCompliance: The policy compliance of this creative in
	// Russia. When approved or disapproved, this 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.
	RussiaPolicyCompliance *PolicyCompliance `json:"russiaPolicyCompliance,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ChinaPolicyCompliance") 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. "ChinaPolicyCompliance") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field 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, such as a
// birthday. The time of day and time zone are either specified
// elsewhere or are insignificant. The date is relative to the Gregorian
// Calendar. This can represent one of the following: * A full date,
// with non-zero year, month, and day values * A month and day value,
// with a zero year, such as an anniversary * A year on its own, with
// zero month and day values * A year and month value, with a zero day,
// such as a credit card expiration date Related types are
// google.type.TimeOfDay and `google.protobuf.Timestamp`.
type Date struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and
	// month, or 0 to specify a year by itself or a year and month where the
	// day isn't significant.
	Day int64 `json:"day,omitempty"`

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

	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a
	// date without a year.
	Year int64 `json:"year,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Day") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 {
}

// PolicyCompliance: Policy compliance of the creative for a transaction
// type or a region.
type PolicyCompliance 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: Topics related to the policy compliance 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 *PolicyCompliance) MarshalJSON() ([]byte, error) {
	type NoMethod PolicyCompliance
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// 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/20201002")
	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/20201002")
	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/20201002")
	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/20201002")
	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/20201002")
	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/20201002")
	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/20201002")
	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": "Output only. 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/20201002")
	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/20201002")
	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/20201002")
	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/20201002")
	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/20201002")
	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/20201002")
	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/20201002")
	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"
	//   ]
	// }

}
