// 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
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   realtimebiddingService, err := realtimebidding.NewService(ctx, option.WithScopes(realtimebidding.RealtimeBiddingScope))
//
// 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 (
	// Manage your Ad Exchange buyer account configuration
	AdexchangeBuyerScope = "https://www.googleapis.com/auth/adexchange.buyer"

	// 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/adexchange.buyer",
		"https://www.googleapis.com/auth/realtime-bidding",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

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

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

	Bidders *BiddersService

	Buyers *BuyersService
}

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

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

type BiddersService struct {
	s *Service

	Creatives *BiddersCreativesService
}

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

type BiddersCreativesService struct {
	s *Service
}

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

type BuyersService struct {
	s *Service

	Creatives *BuyersCreativesService

	UserLists *BuyersUserListsService
}

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

type BuyersCreativesService struct {
	s *Service
}

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

type BuyersUserListsService struct {
	s *Service
}

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

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

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

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

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

// AdvertiserAndBrand: Detected advertiser and brand information.
type AdvertiserAndBrand struct {
	// AdvertiserId: See
	// https://storage.googleapis.com/adx-rtb-dictionaries/advertisers.txt
	// fo
	// r 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/down
	// loads/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 {
	// AdTechnologyProviders: The detected ad technology providers.
	AdTechnologyProviders *AdTechnologyProviders `json:"adTechnologyProviders,omitempty"`

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

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

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

	// DetectedAttributes: Publisher-excludable attributes that were
	// detected for this creative.
	// Can be used to filter the response of the
	// creatives.list
	// method.
	//
	// If the `excluded_attribute` field of a
	// [bid
	// request](https://developers.google.com/authorized-buyers/rtb/down
	// loads/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/languagecod
	// es.
	// 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/down
	// loads/realtime-bidding-proto)
	// does not contain one of the vendor type IDs that were declared
	// or
	// detected for a given creative, and a bid is submitted with that
	// creative,
	// the bid will be filtered before the auction.
	DetectedVendorIds []int64 `json:"detectedVendorIds,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// RedirectionError: HTTP redirect chain error.
	//
	// Possible values:
	//   "REDIRECTION_ERROR_UNSPECIFIED" - Default value that should never
	// be used.
	//   "TOO_MANY_REDIRECTS" - Too many redirect hops.
	//   "INVALID_REDIRECT" - Got a redirect but it was invalid.
	//   "EMPTY_REDIRECT" - Got a redirect but it was empty.
	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.
	UrlRejected string `json:"urlRejected,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// UserLists: List of user lists from the search.
	UserLists []*UserList `json:"userLists,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// WatchCreativesResponse: A response for the request to receive push
// notification when a bidder's
// creatives change status.
type WatchCreativesResponse struct {
	// Subscription: The Pub/Sub subscription that can be used to pull
	// creative status
	// notifications. This would be of the
	// format
	// `projects/{project_id}/subscriptions/{subscription_id}`.
	// Subscr
	// iption 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"
//   "SERVING_DECISION_ONLY"
//   "FULL"
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/20200710")
	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,\nall active creatives will be returned.\n\nExample: 'accountId=12345 AND (dealsStatus:DISAPPROVED AND\ndisapprovalReason:UNACCEPTABLE_CONTENT) OR\ndeclaredAttributes:IS_COOKIE_TARGETED'",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. The server may return fewer creatives than requested\n(due to timeout constraint) even if more are available via another call.\nIf unspecified, server will pick an appropriate default.\nAcceptable 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.\nTypically, this is the value of\nListCreativesResponse.nextPageToken\nreturned from the previous call to the 'ListCreatives' method.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the parent buyer that owns the creatives.\n\nThe pattern for this resource is either `buyers/{buyerAccountId}` or\n`bidders/{bidderAccountId}`.\n\nFor `buyers/{buyerAccountId}`, the `buyerAccountId` can be one of the\nfollowing:\n1. The ID of the buyer that is accessing their own creatives.\n2. The ID of the child seat buyer under a bidder account.\n   So for listing creatives pertaining to the child seat buyer (`456`)\n   under bidder account (`123`), you would use the pattern: `buyers/456`.\n3. The ID of the bidder itself.\n   So for listing creatives pertaining to bidder (`123`),\n   you would use `buyers/123`.\n\nIf you want to access all creatives pertaining to both the bidder and all\nof its child seat accounts, you would use `bidders/{bidderAccountId}`,\ne.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.\nBy default only\ncreativeServingDecision\nis included. To retrieve the entire creative\nresource (including the declared\nfields and the creative content) specify the view as \"FULL\".",
	//       "enum": [
	//         "CREATIVE_VIEW_UNSPECIFIED",
	//         "SERVING_DECISION_ONLY",
	//         "FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/creatives",
	//   "response": {
	//     "$ref": "ListCreativesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/adexchange.buyer",
	//     "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/20200710")
	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\nthis endpoint once per bidder. A Pub/Sub topic will be created and\nnotifications will be pushed to the topic when any of the bidder's\ncreatives change status. All of the bidder's service accounts will have\naccess to read from the topic.\nSubsequent invocations of this method will return the existing\nPub/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\naccounts, 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/adexchange.buyer",
	//     "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/20200710")
	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\nJavaScript code that can be placed on a web page. When a user\nvisits a page containing a remarketing tag, Google adds the user to a user\nlist.",
	//   "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\n`buyers/{accountId}` where `{accountId}`\nrepresents ID of a buyer that owns the remarketing tag. For a\nbidder accessing remarketing tag on behalf of a child seat buyer,\n`{accountId}` should represent the ID of the child seat buyer.\nTo fetch remarketing tag for a specific user list, name\nmust follow the pattern\n`buyers/{accountId}/userLists/{userListId}`. See\nUserList.name.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:getRemarketingTag",
	//   "response": {
	//     "$ref": "GetRemarketingTagResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/adexchange.buyer",
	//     "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/20200710")
	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\nfollow the pattern `buyers/{buyerAccountId}`, where `{buyerAccountId}`\nrepresents the account ID of the buyer who owns a creative. For a bidder\naccessing creatives on behalf of a child seat buyer, `{buyerAccountId}`\nshould 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/adexchange.buyer",
	//     "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"
//   "SERVING_DECISION_ONLY"
//   "FULL"
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/20200710")
	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\ncreative.name.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/creatives/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "Controls the amount of information included in the response.\nBy default only\ncreativeServingDecision\nis included. To retrieve the entire creative\nresource (including the declared\nfields and the creative content) specify the view as \"FULL\".",
	//       "enum": [
	//         "CREATIVE_VIEW_UNSPECIFIED",
	//         "SERVING_DECISION_ONLY",
	//         "FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/adexchange.buyer",
	//     "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"
//   "SERVING_DECISION_ONLY"
//   "FULL"
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/20200710")
	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,\nall active creatives will be returned.\n\nExample: 'accountId=12345 AND (dealsStatus:DISAPPROVED AND\ndisapprovalReason:UNACCEPTABLE_CONTENT) OR\ndeclaredAttributes:IS_COOKIE_TARGETED'",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. The server may return fewer creatives than requested\n(due to timeout constraint) even if more are available via another call.\nIf unspecified, server will pick an appropriate default.\nAcceptable 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.\nTypically, this is the value of\nListCreativesResponse.nextPageToken\nreturned from the previous call to the 'ListCreatives' method.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of the parent buyer that owns the creatives.\n\nThe pattern for this resource is either `buyers/{buyerAccountId}` or\n`bidders/{bidderAccountId}`.\n\nFor `buyers/{buyerAccountId}`, the `buyerAccountId` can be one of the\nfollowing:\n1. The ID of the buyer that is accessing their own creatives.\n2. The ID of the child seat buyer under a bidder account.\n   So for listing creatives pertaining to the child seat buyer (`456`)\n   under bidder account (`123`), you would use the pattern: `buyers/456`.\n3. The ID of the bidder itself.\n   So for listing creatives pertaining to bidder (`123`),\n   you would use `buyers/123`.\n\nIf you want to access all creatives pertaining to both the bidder and all\nof its child seat accounts, you would use `bidders/{bidderAccountId}`,\ne.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.\nBy default only\ncreativeServingDecision\nis included. To retrieve the entire creative\nresource (including the declared\nfields and the creative content) specify the view as \"FULL\".",
	//       "enum": [
	//         "CREATIVE_VIEW_UNSPECIFIED",
	//         "SERVING_DECISION_ONLY",
	//         "FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/creatives",
	//   "response": {
	//     "$ref": "ListCreativesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/adexchange.buyer",
	//     "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/20200710")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creative)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "realtimebidding.buyers.creatives.patch" call.
// Exactly one of *Creative or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Creative.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *BuyersCreativesPatchCall) Do(opts ...googleapi.CallOption) (*Creative, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Creative{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a creative.",
	//   "flatPath": "v1/buyers/{buyersId}/creatives/{creativesId}",
	//   "httpMethod": "PATCH",
	//   "id": "realtimebidding.buyers.creatives.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the creative to update. See\ncreative.name.",
	//       "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/adexchange.buyer",
	//     "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/20200710")
	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\nbeing 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.\nSee 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/adexchange.buyer",
	//     "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/20200710")
	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\nmust follow the pattern `buyers/{buyerAccountId}`, where `{buyerAccountId}`\nrepresents the account ID of the buyer who owns user lists. For a bidder\naccessing user lists on behalf of a child seat buyer , `{buyerAccountId}`\nshould 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/adexchange.buyer",
	//     "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/20200710")
	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\nUserList.name.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/userLists/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "UserList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/adexchange.buyer",
	//     "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/20200710")
	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\nJavaScript code that can be placed on a web page. When a user\nvisits a page containing a remarketing tag, Google adds the user to a user\nlist.",
	//   "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\n`buyers/{accountId}` where `{accountId}`\nrepresents ID of a buyer that owns the remarketing tag. For a\nbidder accessing remarketing tag on behalf of a child seat buyer,\n`{accountId}` should represent the ID of the child seat buyer.\nTo fetch remarketing tag for a specific user list, name\nmust follow the pattern\n`buyers/{accountId}/userLists/{userListId}`. See\nUserList.name.",
	//       "location": "path",
	//       "pattern": "^buyers/[^/]+/userLists/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}:getRemarketingTag",
	//   "response": {
	//     "$ref": "GetRemarketingTagResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/adexchange.buyer",
	//     "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/20200710")
	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\nfollow the pattern `buyers/{buyerAccountId}`, where `{buyerAccountId}`\nrepresents the account ID of the buyer who owns user lists. For a bidder\naccessing user lists on behalf of a child seat buyer , `{buyerAccountId}`\nshould 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/adexchange.buyer",
	//     "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/20200710")
	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\nto 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.\nSee 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/adexchange.buyer",
	//     "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/20200710")
	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\nupdated.",
	//   "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\n`buyers/{buyer}/userLists/{user_list}`, where `{buyer}` represents\nthe account ID of the buyer who owns the user list. For a bidder accessing\nuser lists on behalf of a child seat buyer, `{buyer}` represents\nthe account ID of the child seat buyer. `{user_list}` is an int64\nidentifier 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/adexchange.buyer",
	//     "https://www.googleapis.com/auth/realtime-bidding"
	//   ]
	// }

}
