// 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 displayvideo provides access to the Display & Video 360 API.
//
// For product documentation, see: https://developers.google.com/display-video/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/displayvideo/v1"
//   ...
//   ctx := context.Background()
//   displayvideoService, err := displayvideo.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:
//
//   displayvideoService, err := displayvideo.NewService(ctx, option.WithScopes(displayvideo.DoubleclickbidmanagerScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   displayvideoService, err := displayvideo.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, ...)
//   displayvideoService, err := displayvideo.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package displayvideo // import "google.golang.org/api/displayvideo/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 = "displayvideo:v1"
const apiName = "displayvideo"
const apiVersion = "v1"
const basePath = "https://displayvideo.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// Create, see, edit, and permanently delete your Display & Video 360
	// entities and reports
	DisplayVideoScope = "https://www.googleapis.com/auth/display-video"

	// View and manage your reports in DoubleClick Bid Manager
	DoubleclickbidmanagerScope = "https://www.googleapis.com/auth/doubleclickbidmanager"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/display-video",
		"https://www.googleapis.com/auth/doubleclickbidmanager",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	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.Advertisers = NewAdvertisersService(s)
	s.CombinedAudiences = NewCombinedAudiencesService(s)
	s.CustomLists = NewCustomListsService(s)
	s.FirstAndThirdPartyAudiences = NewFirstAndThirdPartyAudiencesService(s)
	s.FloodlightGroups = NewFloodlightGroupsService(s)
	s.GoogleAudiences = NewGoogleAudiencesService(s)
	s.InventorySourceGroups = NewInventorySourceGroupsService(s)
	s.InventorySources = NewInventorySourcesService(s)
	s.Media = NewMediaService(s)
	s.Partners = NewPartnersService(s)
	s.Sdfdownloadtasks = NewSdfdownloadtasksService(s)
	s.TargetingTypes = NewTargetingTypesService(s)
	return s, nil
}

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

	Advertisers *AdvertisersService

	CombinedAudiences *CombinedAudiencesService

	CustomLists *CustomListsService

	FirstAndThirdPartyAudiences *FirstAndThirdPartyAudiencesService

	FloodlightGroups *FloodlightGroupsService

	GoogleAudiences *GoogleAudiencesService

	InventorySourceGroups *InventorySourceGroupsService

	InventorySources *InventorySourcesService

	Media *MediaService

	Partners *PartnersService

	Sdfdownloadtasks *SdfdownloadtasksService

	TargetingTypes *TargetingTypesService
}

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

func NewAdvertisersService(s *Service) *AdvertisersService {
	rs := &AdvertisersService{s: s}
	rs.Assets = NewAdvertisersAssetsService(s)
	rs.Campaigns = NewAdvertisersCampaignsService(s)
	rs.Channels = NewAdvertisersChannelsService(s)
	rs.Creatives = NewAdvertisersCreativesService(s)
	rs.InsertionOrders = NewAdvertisersInsertionOrdersService(s)
	rs.LineItems = NewAdvertisersLineItemsService(s)
	rs.LocationLists = NewAdvertisersLocationListsService(s)
	rs.NegativeKeywordLists = NewAdvertisersNegativeKeywordListsService(s)
	rs.TargetingTypes = NewAdvertisersTargetingTypesService(s)
	return rs
}

type AdvertisersService struct {
	s *Service

	Assets *AdvertisersAssetsService

	Campaigns *AdvertisersCampaignsService

	Channels *AdvertisersChannelsService

	Creatives *AdvertisersCreativesService

	InsertionOrders *AdvertisersInsertionOrdersService

	LineItems *AdvertisersLineItemsService

	LocationLists *AdvertisersLocationListsService

	NegativeKeywordLists *AdvertisersNegativeKeywordListsService

	TargetingTypes *AdvertisersTargetingTypesService
}

func NewAdvertisersAssetsService(s *Service) *AdvertisersAssetsService {
	rs := &AdvertisersAssetsService{s: s}
	return rs
}

type AdvertisersAssetsService struct {
	s *Service
}

func NewAdvertisersCampaignsService(s *Service) *AdvertisersCampaignsService {
	rs := &AdvertisersCampaignsService{s: s}
	return rs
}

type AdvertisersCampaignsService struct {
	s *Service
}

func NewAdvertisersChannelsService(s *Service) *AdvertisersChannelsService {
	rs := &AdvertisersChannelsService{s: s}
	return rs
}

type AdvertisersChannelsService struct {
	s *Service
}

func NewAdvertisersCreativesService(s *Service) *AdvertisersCreativesService {
	rs := &AdvertisersCreativesService{s: s}
	return rs
}

type AdvertisersCreativesService struct {
	s *Service
}

func NewAdvertisersInsertionOrdersService(s *Service) *AdvertisersInsertionOrdersService {
	rs := &AdvertisersInsertionOrdersService{s: s}
	return rs
}

type AdvertisersInsertionOrdersService struct {
	s *Service
}

func NewAdvertisersLineItemsService(s *Service) *AdvertisersLineItemsService {
	rs := &AdvertisersLineItemsService{s: s}
	rs.TargetingTypes = NewAdvertisersLineItemsTargetingTypesService(s)
	return rs
}

type AdvertisersLineItemsService struct {
	s *Service

	TargetingTypes *AdvertisersLineItemsTargetingTypesService
}

func NewAdvertisersLineItemsTargetingTypesService(s *Service) *AdvertisersLineItemsTargetingTypesService {
	rs := &AdvertisersLineItemsTargetingTypesService{s: s}
	rs.AssignedTargetingOptions = NewAdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService(s)
	return rs
}

type AdvertisersLineItemsTargetingTypesService struct {
	s *Service

	AssignedTargetingOptions *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService
}

func NewAdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService(s *Service) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService {
	rs := &AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService{s: s}
	return rs
}

type AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService struct {
	s *Service
}

func NewAdvertisersLocationListsService(s *Service) *AdvertisersLocationListsService {
	rs := &AdvertisersLocationListsService{s: s}
	return rs
}

type AdvertisersLocationListsService struct {
	s *Service
}

func NewAdvertisersNegativeKeywordListsService(s *Service) *AdvertisersNegativeKeywordListsService {
	rs := &AdvertisersNegativeKeywordListsService{s: s}
	return rs
}

type AdvertisersNegativeKeywordListsService struct {
	s *Service
}

func NewAdvertisersTargetingTypesService(s *Service) *AdvertisersTargetingTypesService {
	rs := &AdvertisersTargetingTypesService{s: s}
	rs.AssignedTargetingOptions = NewAdvertisersTargetingTypesAssignedTargetingOptionsService(s)
	return rs
}

type AdvertisersTargetingTypesService struct {
	s *Service

	AssignedTargetingOptions *AdvertisersTargetingTypesAssignedTargetingOptionsService
}

func NewAdvertisersTargetingTypesAssignedTargetingOptionsService(s *Service) *AdvertisersTargetingTypesAssignedTargetingOptionsService {
	rs := &AdvertisersTargetingTypesAssignedTargetingOptionsService{s: s}
	return rs
}

type AdvertisersTargetingTypesAssignedTargetingOptionsService struct {
	s *Service
}

func NewCombinedAudiencesService(s *Service) *CombinedAudiencesService {
	rs := &CombinedAudiencesService{s: s}
	return rs
}

type CombinedAudiencesService struct {
	s *Service
}

func NewCustomListsService(s *Service) *CustomListsService {
	rs := &CustomListsService{s: s}
	return rs
}

type CustomListsService struct {
	s *Service
}

func NewFirstAndThirdPartyAudiencesService(s *Service) *FirstAndThirdPartyAudiencesService {
	rs := &FirstAndThirdPartyAudiencesService{s: s}
	return rs
}

type FirstAndThirdPartyAudiencesService struct {
	s *Service
}

func NewFloodlightGroupsService(s *Service) *FloodlightGroupsService {
	rs := &FloodlightGroupsService{s: s}
	return rs
}

type FloodlightGroupsService struct {
	s *Service
}

func NewGoogleAudiencesService(s *Service) *GoogleAudiencesService {
	rs := &GoogleAudiencesService{s: s}
	return rs
}

type GoogleAudiencesService struct {
	s *Service
}

func NewInventorySourceGroupsService(s *Service) *InventorySourceGroupsService {
	rs := &InventorySourceGroupsService{s: s}
	return rs
}

type InventorySourceGroupsService struct {
	s *Service
}

func NewInventorySourcesService(s *Service) *InventorySourcesService {
	rs := &InventorySourcesService{s: s}
	return rs
}

type InventorySourcesService struct {
	s *Service
}

func NewMediaService(s *Service) *MediaService {
	rs := &MediaService{s: s}
	return rs
}

type MediaService struct {
	s *Service
}

func NewPartnersService(s *Service) *PartnersService {
	rs := &PartnersService{s: s}
	rs.Channels = NewPartnersChannelsService(s)
	return rs
}

type PartnersService struct {
	s *Service

	Channels *PartnersChannelsService
}

func NewPartnersChannelsService(s *Service) *PartnersChannelsService {
	rs := &PartnersChannelsService{s: s}
	return rs
}

type PartnersChannelsService struct {
	s *Service
}

func NewSdfdownloadtasksService(s *Service) *SdfdownloadtasksService {
	rs := &SdfdownloadtasksService{s: s}
	rs.Operations = NewSdfdownloadtasksOperationsService(s)
	return rs
}

type SdfdownloadtasksService struct {
	s *Service

	Operations *SdfdownloadtasksOperationsService
}

func NewSdfdownloadtasksOperationsService(s *Service) *SdfdownloadtasksOperationsService {
	rs := &SdfdownloadtasksOperationsService{s: s}
	return rs
}

type SdfdownloadtasksOperationsService struct {
	s *Service
}

func NewTargetingTypesService(s *Service) *TargetingTypesService {
	rs := &TargetingTypesService{s: s}
	rs.TargetingOptions = NewTargetingTypesTargetingOptionsService(s)
	return rs
}

type TargetingTypesService struct {
	s *Service

	TargetingOptions *TargetingTypesTargetingOptionsService
}

func NewTargetingTypesTargetingOptionsService(s *Service) *TargetingTypesTargetingOptionsService {
	rs := &TargetingTypesTargetingOptionsService{s: s}
	return rs
}

type TargetingTypesTargetingOptionsService struct {
	s *Service
}

// ActiveViewVideoViewabilityMetricConfig: Configuration for custom
// Active View video viewability metrics.
type ActiveViewVideoViewabilityMetricConfig struct {
	// DisplayName: Required. The display name of the custom metric.
	DisplayName string `json:"displayName,omitempty"`

	// MinimumDuration: The minimum visible video duration required (in
	// seconds) in order for an
	// impression to be recorded.
	//
	// You must specify
	// minimum_duration,
	// minimum_quartile
	// or both. If both are specified, an impression meets the metric
	// criteria if
	// either requirement is met (whichever happens first).
	//
	// Possible values:
	//   "VIDEO_DURATION_UNSPECIFIED" - Value is not specified or is unknown
	// in this version.
	//   "VIDEO_DURATION_SECONDS_NONE" - No duration value.
	//   "VIDEO_DURATION_SECONDS_0" - 0 seconds.
	//   "VIDEO_DURATION_SECONDS_1" - 1 second.
	//   "VIDEO_DURATION_SECONDS_2" - 2 seconds.
	//   "VIDEO_DURATION_SECONDS_3" - 3 seconds.
	//   "VIDEO_DURATION_SECONDS_4" - 4 seconds.
	//   "VIDEO_DURATION_SECONDS_5" - 5 seconds.
	//   "VIDEO_DURATION_SECONDS_6" - 6 seconds.
	//   "VIDEO_DURATION_SECONDS_7" - 7 seconds.
	//   "VIDEO_DURATION_SECONDS_8" - 8 seconds.
	//   "VIDEO_DURATION_SECONDS_9" - 9 seconds.
	//   "VIDEO_DURATION_SECONDS_10" - 10 seconds.
	//   "VIDEO_DURATION_SECONDS_11" - 11 seconds.
	//   "VIDEO_DURATION_SECONDS_12" - 12 seconds.
	//   "VIDEO_DURATION_SECONDS_13" - 13 seconds.
	//   "VIDEO_DURATION_SECONDS_14" - 14 seconds.
	//   "VIDEO_DURATION_SECONDS_15" - 15 seconds.
	//   "VIDEO_DURATION_SECONDS_30" - 30 seconds.
	//   "VIDEO_DURATION_SECONDS_45" - 45 seconds.
	//   "VIDEO_DURATION_SECONDS_60" - 60 seconds.
	MinimumDuration string `json:"minimumDuration,omitempty"`

	// MinimumQuartile: The minimum visible video duration required, based
	// on the video quartiles,
	// in order for an impression to be recorded.
	//
	// You must specify
	// minimum_duration,
	// minimum_quartile
	// or both. If both are specified, an impression meets the metric
	// criteria if
	// either requirement is met (whichever happens first).
	//
	// Possible values:
	//   "VIDEO_DURATION_QUARTILE_UNSPECIFIED" - Value is not specified or
	// is unknown in this version.
	//   "VIDEO_DURATION_QUARTILE_NONE" - No quartile value.
	//   "VIDEO_DURATION_QUARTILE_FIRST" - First quartile.
	//   "VIDEO_DURATION_QUARTILE_SECOND" - Second quartile (midpoint).
	//   "VIDEO_DURATION_QUARTILE_THIRD" - Third quartile.
	//   "VIDEO_DURATION_QUARTILE_FOURTH" - Fourth quartile (completion).
	MinimumQuartile string `json:"minimumQuartile,omitempty"`

	// MinimumViewability: Required. The minimum percentage of the video
	// ad's pixels visible on the screen in
	// order for an impression to be recorded.
	//
	// Possible values:
	//   "VIEWABILITY_PERCENT_UNSPECIFIED" - Value is not specified or is
	// unknown in this version.
	//   "VIEWABILITY_PERCENT_0" - 0% viewable.
	//   "VIEWABILITY_PERCENT_25" - 25% viewable.
	//   "VIEWABILITY_PERCENT_50" - 50% viewable.
	//   "VIEWABILITY_PERCENT_75" - 75% viewable.
	//   "VIEWABILITY_PERCENT_100" - 100% viewable.
	MinimumViewability string `json:"minimumViewability,omitempty"`

	// MinimumVolume: Required. The minimum percentage of the video ad's
	// volume required in order for an
	// impression to be recorded.
	//
	// Possible values:
	//   "VIDEO_VOLUME_PERCENT_UNSPECIFIED" - Value is not specified or is
	// unknown in this version.
	//   "VIDEO_VOLUME_PERCENT_0" - 0% volume.
	//   "VIDEO_VOLUME_PERCENT_10" - 10% volume.
	MinimumVolume string `json:"minimumVolume,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *ActiveViewVideoViewabilityMetricConfig) MarshalJSON() ([]byte, error) {
	type NoMethod ActiveViewVideoViewabilityMetricConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Adloox: Details of Adloox settings.
type Adloox struct {
	// ExcludedAdlooxCategories: Adloox's brand safety settings.
	//
	// Possible values:
	//   "ADLOOX_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any Adloox option.
	//   "ADULT_CONTENT_HARD" - Adult content (hard).
	//   "ADULT_CONTENT_SOFT" - Adult content (soft).
	//   "ILLEGAL_CONTENT" - Illegal content.
	//   "BORDERLINE_CONTENT" - Borderline content.
	//   "DISCRIMINATORY_CONTENT" - Discriminatory content.
	//   "VIOLENT_CONTENT_WEAPONS" - Violent content & weapons.
	//   "LOW_VIEWABILITY_DOMAINS" - Low viewability domains.
	//   "FRAUD" - Fraud.
	ExcludedAdlooxCategories []string `json:"excludedAdlooxCategories,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ExcludedAdlooxCategories") 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. "ExcludedAdlooxCategories")
	// 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 *Adloox) MarshalJSON() ([]byte, error) {
	type NoMethod Adloox
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Advertiser: A single advertiser in Display & Video 360 (DV360).
type Advertiser struct {
	// AdServerConfig: Required. Immutable. Ad server related settings of
	// the advertiser.
	AdServerConfig *AdvertiserAdServerConfig `json:"adServerConfig,omitempty"`

	// AdvertiserId: Output only. The unique ID of the advertiser. Assigned
	// by the system.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// CreativeConfig: Required. Creative related settings of the
	// advertiser.
	CreativeConfig *AdvertiserCreativeConfig `json:"creativeConfig,omitempty"`

	// DataAccessConfig: Settings that control how advertiser data may be
	// accessed.
	DataAccessConfig *AdvertiserDataAccessConfig `json:"dataAccessConfig,omitempty"`

	// DisplayName: Required. The display name of the advertiser.
	//
	// Must be UTF-8 encoded with a maximum size of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// EntityStatus: Required. Controls whether or not insertion orders and
	// line items of the
	// advertiser can spend their budgets and bid on inventory.
	//
	// * Accepted values are `ENTITY_STATUS_ACTIVE`
	// and
	// `ENTITY_STATUS_SCHEDULED_FOR_DELETION`.
	// * If set to
	// `ENTITY_STATUS_SCHEDULED_FOR_DELETION`, the advertiser will be
	// deleted 30
	// days from when it was first scheduled for deletion.
	//
	// Possible values:
	//   "ENTITY_STATUS_UNSPECIFIED" - Default value when status is not
	// specified or is unknown in this version.
	//   "ENTITY_STATUS_ACTIVE" - The entity is enabled to bid and spend
	// budget.
	//   "ENTITY_STATUS_ARCHIVED" - The entity is archived. Bidding and
	// budget spending are disabled. An
	// entity can be deleted after archived. Deleted entities cannot be
	// retrieved.
	//   "ENTITY_STATUS_DRAFT" - The entity is under draft. Bidding and
	// budget spending are disabled.
	//   "ENTITY_STATUS_PAUSED" - Bidding and budget spending are paused for
	// the entity.
	//   "ENTITY_STATUS_SCHEDULED_FOR_DELETION" - The entity is scheduled
	// for deletion.
	EntityStatus string `json:"entityStatus,omitempty"`

	// GeneralConfig: Required. General settings of the advertiser.
	GeneralConfig *AdvertiserGeneralConfig `json:"generalConfig,omitempty"`

	// IntegrationDetails: Integration details of the advertiser.
	// Only integrationCode is currently
	// applicable to advertiser. Other fields of IntegrationDetails are
	// not
	// supported and will be ignored if provided.
	IntegrationDetails *IntegrationDetails `json:"integrationDetails,omitempty"`

	// Name: Output only. The resource name of the advertiser.
	Name string `json:"name,omitempty"`

	// PartnerId: Required. Immutable. The unique ID of the partner that the
	// advertiser belongs to.
	PartnerId int64 `json:"partnerId,omitempty,string"`

	// ServingConfig: Targeting settings related to ad serving of the
	// advertiser.
	ServingConfig *AdvertiserTargetingConfig `json:"servingConfig,omitempty"`

	// UpdateTime: Output only. The timestamp when the advertiser was last
	// updated. Assigned by the system.
	UpdateTime string `json:"updateTime,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AdServerConfig") 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. "AdServerConfig") 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 *Advertiser) MarshalJSON() ([]byte, error) {
	type NoMethod Advertiser
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AdvertiserAdServerConfig: Ad server related settings of an
// advertiser.
type AdvertiserAdServerConfig struct {
	// CmHybridConfig: The configuration for advertisers that use both
	// Campaign Manager (CM) and
	// third-party ad servers.
	CmHybridConfig *CmHybridConfig `json:"cmHybridConfig,omitempty"`

	// ThirdPartyOnlyConfig: The configuration for advertisers that use
	// third-party ad servers
	// only.
	ThirdPartyOnlyConfig *ThirdPartyOnlyConfig `json:"thirdPartyOnlyConfig,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CmHybridConfig") 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. "CmHybridConfig") 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 *AdvertiserAdServerConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AdvertiserAdServerConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AdvertiserCreativeConfig: Creatives related settings of an
// advertiser.
type AdvertiserCreativeConfig struct {
	// DynamicCreativeEnabled: Whether or not the advertiser is enabled for
	// dynamic creatives.
	DynamicCreativeEnabled bool `json:"dynamicCreativeEnabled,omitempty"`

	// IasClientId: An ID for configuring campaign monitoring provided by
	// Integral Ad Service
	// (IAS). The DV360 system will append an IAS "Campaign Monitor"
	// tag
	// containing this ID to the creative tag.
	IasClientId int64 `json:"iasClientId,omitempty,string"`

	// ObaComplianceDisabled: Whether or not to use DV360's Online
	// Behavioral Advertising (OBA)
	// compliance.
	//
	// Warning: Changing OBA settings may cause the audit status of your
	// creatives
	// to be reset by some ad exchanges, making them ineligible to serve
	// until
	// they are re-approved.
	ObaComplianceDisabled bool `json:"obaComplianceDisabled,omitempty"`

	// VideoCreativeDataSharingAuthorized: By setting this field to `true`,
	// you, on behalf of your company,
	// authorize Google to use video creatives associated with this Display
	// &
	// Video 360 advertiser to provide reporting and features related to
	// the
	// advertiser's television campaigns.
	//
	// Applicable only when the advertiser has a
	// CM hybrid ad server
	// configuration.
	VideoCreativeDataSharingAuthorized bool `json:"videoCreativeDataSharingAuthorized,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "DynamicCreativeEnabled") 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. "DynamicCreativeEnabled")
	// 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 *AdvertiserCreativeConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AdvertiserCreativeConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AdvertiserDataAccessConfig: Settings that control how advertiser
// related data may be accessed.
type AdvertiserDataAccessConfig struct {
	// SdfConfig: Structured Data Files (SDF) settings for the
	// advertiser.
	//
	// If not specified, the SDF settings of the parent partner are used.
	SdfConfig *AdvertiserSdfConfig `json:"sdfConfig,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SdfConfig") 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. "SdfConfig") 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 *AdvertiserDataAccessConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AdvertiserDataAccessConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AdvertiserGeneralConfig: General settings of an advertiser.
type AdvertiserGeneralConfig struct {
	// CurrencyCode: Required. Immutable. Advertiser's currency in ISO 4217
	// format.
	//
	// Accepted codes and the currencies they represent are:
	//
	// Currency Code : Currency Name
	//
	// * `ARS` : Argentine Peso
	// * `AUD` : Australian Dollar
	// * `BRL` : Brazilian Real
	// * `CAD` : Canadian Dollar
	// * `CHF` : Swiss Franc
	// * `CLP` : Chilean Peso
	// * `CNY` : Chinese Yuan
	// * `COP` : Colombian Peso
	// * `CZK` : Czech Koruna
	// * `DKK` : Danish Krone
	// * `EGP` : Egyption Pound
	// * `EUR` : Euro
	// * `GBP` : British Pound
	// * `HKD` : Hong Kong Dollar
	// * `HUF` : Hungarian Forint
	// * `IDR` : Indonesian Rupiah
	// * `ILS` : Israeli Shekel
	// * `INR` : Indian Rupee
	// * `JPY` : Japanese Yen
	// * `KRW` : South Korean Won
	// * `MXN` : Mexican Pesos
	// * `MYR` : Malaysian Ringgit
	// * `NGN` : Nigerian Naira
	// * `NOK` : Norwegian Krone
	// * `NZD` : New Zealand Dollar
	// * `PEN` : Peruvian Nuevo Sol
	// * `PLN` : Polish Zloty
	// * `RON` : New Romanian Leu
	// * `RUB` : Russian Ruble
	// * `SEK` : Swedish Krona
	// * `TRY` : Turkish Lira
	// * `TWD` : New Taiwan Dollar
	// * `USD` : US Dollar
	// * `ZAR` : South African Rand
	CurrencyCode string `json:"currencyCode,omitempty"`

	// DomainUrl: Required. The domain URL of the advertiser's primary
	// website.
	// The system will send this information to publishers that require
	// website
	// URL to associate a campaign with an advertiser.
	//
	// Provide a URL with no path or query string, beginning with `http:`
	// or
	// `https:`.
	// For example, http://www.example.com
	DomainUrl string `json:"domainUrl,omitempty"`

	// TimeZone: Output only. The standard TZ database name of the
	// advertiser's time zone.
	// For example, `America/New_York`.
	//
	// See more
	// at:
	// https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
	//
	// For CM hybrid advertisers, the time zone is the same as that of
	// the
	// associated CM account; for third-party only advertisers, the time
	// zone is
	// the same as that of the parent partner.
	TimeZone string `json:"timeZone,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CurrencyCode") 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. "CurrencyCode") 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 *AdvertiserGeneralConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AdvertiserGeneralConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AdvertiserSdfConfig: Structured Data Files (SDF) settings of an
// advertiser.
type AdvertiserSdfConfig struct {
	// OverridePartnerSdfConfig: Whether or not this advertiser overrides
	// the SDF configuration of its
	// parent partner.
	//
	// By default, an advertiser inherits the SDF configuration from the
	// parent
	// partner. To override the partner configuration, set this field to
	// `true`
	// and provide the new configuration in
	// sdfConfig.
	OverridePartnerSdfConfig bool `json:"overridePartnerSdfConfig,omitempty"`

	// SdfConfig: The SDF configuration for the advertiser.
	//
	// * Required when
	// overridePartnerSdfConfig
	// is `true`.
	// * Output only when
	// overridePartnerSdfConfig
	// is `false`.
	SdfConfig *SdfConfig `json:"sdfConfig,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "OverridePartnerSdfConfig") 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. "OverridePartnerSdfConfig")
	// 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 *AdvertiserSdfConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AdvertiserSdfConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AdvertiserTargetingConfig: Targeting settings related to ad serving
// of an advertiser.
type AdvertiserTargetingConfig struct {
	// ExemptTvFromViewabilityTargeting: Whether or not connected TV devices
	// are exempt from viewability targeting
	// for all video line items under the advertiser.
	ExemptTvFromViewabilityTargeting bool `json:"exemptTvFromViewabilityTargeting,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ExemptTvFromViewabilityTargeting") 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.
	// "ExemptTvFromViewabilityTargeting") 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 *AdvertiserTargetingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AdvertiserTargetingConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AgeRangeAssignedTargetingOptionDetails: Represents a targetable age
// range. This will be populated in the details
// field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_AGE_RANGE`.
type AgeRangeAssignedTargetingOptionDetails struct {
	// AgeRange: Output only. The age range of an audience. We only support
	// targeting a continuous age
	// range of an audience. Thus, the age range represented in this field
	// can be
	// 1) targeted solely, or, 2) part of a larger continuous age range. The
	// reach
	// of a continuous age range targeting can be expanded by also targeting
	// an
	// audience of an unknown age.
	//
	// Possible values:
	//   "AGE_RANGE_UNSPECIFIED" - Default value when age range is not
	// specified in this version. This enum is
	// a placeholder for default value and does not represent a real age
	// range
	// option.
	//   "AGE_RANGE_18_24" - The age range of the audience is 18 to 24.
	//   "AGE_RANGE_25_34" - The age range of the audience is 25 to 34.
	//   "AGE_RANGE_35_44" - The age range of the audience is 35 to 44.
	//   "AGE_RANGE_45_54" - The age range of the audience is 45 to 54.
	//   "AGE_RANGE_55_64" - The age range of the audience is 55 to 64.
	//   "AGE_RANGE_65_PLUS" - The age range of the audience is 65 and up.
	//   "AGE_RANGE_UNKNOWN" - The age range of the audience is unknown.
	AgeRange string `json:"ageRange,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_AGE_RANGE`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AgeRange") 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. "AgeRange") 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 *AgeRangeAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AgeRangeAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AgeRangeTargetingOptionDetails: Represents a targetable age range.
// This will be populated in the
// age_range_details field when
// targeting_type is
// `TARGETING_TYPE_AGE_RANGE`.
type AgeRangeTargetingOptionDetails struct {
	// AgeRange: Output only. The age range of an audience.
	//
	// Possible values:
	//   "AGE_RANGE_UNSPECIFIED" - Default value when age range is not
	// specified in this version. This enum is
	// a placeholder for default value and does not represent a real age
	// range
	// option.
	//   "AGE_RANGE_18_24" - The age range of the audience is 18 to 24.
	//   "AGE_RANGE_25_34" - The age range of the audience is 25 to 34.
	//   "AGE_RANGE_35_44" - The age range of the audience is 35 to 44.
	//   "AGE_RANGE_45_54" - The age range of the audience is 45 to 54.
	//   "AGE_RANGE_55_64" - The age range of the audience is 55 to 64.
	//   "AGE_RANGE_65_PLUS" - The age range of the audience is 65 and up.
	//   "AGE_RANGE_UNKNOWN" - The age range of the audience is unknown.
	AgeRange string `json:"ageRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AgeRange") 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. "AgeRange") 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 *AgeRangeTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AgeRangeTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AppAssignedTargetingOptionDetails: Details for assigned app targeting
// option. This will be populated in the
// details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_APP`.
type AppAssignedTargetingOptionDetails struct {
	// AppId: Required. The ID of the app.
	//
	// Android's Play store app uses bundle ID, for
	// example
	// `com.google.android.gm`. Apple's App store app ID uses 9 digit
	// string, for
	// example `422689480`.
	AppId string `json:"appId,omitempty"`

	// DisplayName: Output only. The display name of the app.
	DisplayName string `json:"displayName,omitempty"`

	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppId") 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. "AppId") 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 *AppAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AppAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AppCategoryAssignedTargetingOptionDetails: Details for assigned app
// category targeting option. This will be
// populated in the
// app_category_details field of
// an AssignedTargetingOption when
// targeting_type
// is `TARGETING_TYPE_APP_CATEGORY`.
type AppCategoryAssignedTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the app category.
	DisplayName string `json:"displayName,omitempty"`

	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id field
	// when
	// targeting_type is
	// `TARGETING_TYPE_APP_CATEGORY`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *AppCategoryAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AppCategoryAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AppCategoryTargetingOptionDetails: Represents a targetable collection
// of apps. A collection lets you target
// dynamic groups of related apps that are maintained by the platform,
// for
// example `All Apps/Google Play/Games`. This will be populated in
// the
// app_category_details field when
// targeting_type is
// `TARGETING_TYPE_APP_CATEGORY`.
type AppCategoryTargetingOptionDetails struct {
	// DisplayName: Output only. The name of the app collection.
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *AppCategoryTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AppCategoryTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Asset: A single asset.
type Asset struct {
	// Content: The asset content.
	// For uploaded assets, the content is the serving path.
	Content string `json:"content,omitempty"`

	// MediaId: Media ID of the uploaded asset. This is a unique identifier
	// for the asset.
	// This ID can be passed to other API calls, e.g.
	// CreateCreative to associate
	// the asset with a creative.
	MediaId int64 `json:"mediaId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Content") 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. "Content") 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 *Asset) MarshalJSON() ([]byte, error) {
	type NoMethod Asset
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AssetAssociation: Asset association for the creative.
type AssetAssociation struct {
	// Asset: The associated asset.
	Asset *Asset `json:"asset,omitempty"`

	// Role: The role of this asset for the creative.
	//
	// Possible values:
	//   "ASSET_ROLE_UNSPECIFIED" - Asset role is not specified or is
	// unknown in this version.
	//   "ASSET_ROLE_MAIN" - The asset is the main asset of the creative.
	//   "ASSET_ROLE_BACKUP" - The asset is a backup asset of the creative.
	//   "ASSET_ROLE_POLITE_LOAD" - The asset is a polite load asset of the
	// creative.
	//   "ASSET_ROLE_HEADLINE" - Headline of a native creative.
	//
	// The content must be UTF-8 encoded with a length of no more
	// than 25 characters.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	//   "ASSET_ROLE_LONG_HEADLINE" - Long headline of a native
	// creative.
	//
	// The content must be UTF-8 encoded with a length of no more
	// than 50 characters.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	//   "ASSET_ROLE_BODY" - Body text of a native creative.
	//
	// The content must be UTF-8 encoded with a length of no more
	// than 90 characters.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	//   "ASSET_ROLE_LONG_BODY" - Long body text of a native creative.
	//
	// The content must be UTF-8 encoded with a length of no more
	// than 150 characters.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	//   "ASSET_ROLE_CAPTION_URL" - A short, friendly version of the landing
	// page URL to show in the creative.
	// This URL gives people an idea of where they'll arrive after they
	// click on
	// the creative.
	//
	// The content must be UTF-8 encoded with a length of no more
	// than 30 characters.
	//
	// For example, if the landing page URL is
	// 'http://www.example.com/page',
	// the caption URL can be 'example.com'.
	// The protocol (http://) is optional, but the URL can't contain spaces
	// or
	// special characters.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	//   "ASSET_ROLE_CALL_TO_ACTION" - The text to use on the call-to-action
	// button of a native creative.
	//
	// The content must be UTF-8 encoded with a length of no more
	// than 15 characters.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	//   "ASSET_ROLE_ADVERTISER_NAME" - The text that identifies the
	// advertiser or brand name.
	//
	// The content must be UTF-8 encoded with a length of no more
	// than 25 characters.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	//   "ASSET_ROLE_PRICE" - The purchase price of your app in the Google
	// play store or iOS app store
	// (for example, $5.99).
	//
	// Note that this value is not automatically synced with the actual
	// value
	// listed in the store. It will always be the one provided when save
	// the
	// creative.
	//
	// The content must be UTF-8 encoded with a length of no more
	// than 15 characters.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	//   "ASSET_ROLE_ANDROID_APP_ID" - The ID of an Android app in the
	// Google play store.
	//
	// You can find this ID in the App’s Google Play Store URL after
	// ‘id’. For
	// example,
	// in
	// https://play.google.com/store/apps/details?id=com.company.appname
	// the
	// identifier is com.company.appname.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	//   "ASSET_ROLE_IOS_APP_ID" - The ID of an iOS app in the Apple app
	// store.
	//
	// This ID number can be found in the Apple App Store URL as the string
	// of
	// numbers directly after "id". For example,
	// in
	// https://apps.apple.com/us/app/gmail-email-by-google/id422689480 the
	// ID is
	// 422689480.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	//   "ASSET_ROLE_RATING" - The rating of an app in the Google play store
	// or iOS app store.
	//
	// Note that this value is not automatically synced with the actual
	// rating
	// in the store. It will always be the one provided when save the
	// creative.
	//
	// This role is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	//   "ASSET_ROLE_ICON" - The icon of a creative.
	//
	// This role is only supported and required in
	// following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	//   "ASSET_ROLE_COVER_IMAGE" - The cover image of a native video
	// creative.
	//
	// This role is only supported and required in
	// following
	// creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	Role string `json:"role,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Asset") 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. "Asset") 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 *AssetAssociation) MarshalJSON() ([]byte, error) {
	type NoMethod AssetAssociation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AssignedTargetingOption: A single assigned targeting option, which
// defines the state of a targeting
// option for an entity with targeting settings, such as a Line Item
// or
// Insertion Order.
type AssignedTargetingOption struct {
	// AgeRangeDetails: Age range details. This field will be populated when
	// the
	// TargetingType is `TARGETING_TYPE_AGE_RANGE`.
	AgeRangeDetails *AgeRangeAssignedTargetingOptionDetails `json:"ageRangeDetails,omitempty"`

	// AppCategoryDetails: App category details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_APP_CATEGORY`.
	AppCategoryDetails *AppCategoryAssignedTargetingOptionDetails `json:"appCategoryDetails,omitempty"`

	// AppDetails: App details. This field will be populated when
	// the
	// TargetingType is `TARGETING_TYPE_APP`.
	AppDetails *AppAssignedTargetingOptionDetails `json:"appDetails,omitempty"`

	// AssignedTargetingOptionId: Output only. The unique ID of the assigned
	// targeting option. The ID is only unique
	// within a given line item and targeting type. It may be reused in
	// other
	// contexts.
	AssignedTargetingOptionId string `json:"assignedTargetingOptionId,omitempty"`

	// AudienceGroupDetails: Audience targeting details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_AUDIENCE_GROUP`.
	// You can only target one audience group option per line item.
	AudienceGroupDetails *AudienceGroupAssignedTargetingOptionDetails `json:"audienceGroupDetails,omitempty"`

	// AuthorizedSellerStatusDetails: Authorized seller status details. This
	// field will be populated when the
	// TargetingType is `TARGETING_TYPE_AUTHORIZED_SELLER_STATUS`.
	//
	// You can only target one authorized seller status option per line
	// item.
	//
	// If a line item doesn't have an authorized seller status option,
	// all
	// authorized sellers indicated as DIRECT or RESELLER in the ads.txt
	// file
	// are targeted by default.
	AuthorizedSellerStatusDetails *AuthorizedSellerStatusAssignedTargetingOptionDetails `json:"authorizedSellerStatusDetails,omitempty"`

	// BrowserDetails: Browser details. This field will be populated when
	// the
	// TargetingType is `TARGETING_TYPE_BROWSER`.
	BrowserDetails *BrowserAssignedTargetingOptionDetails `json:"browserDetails,omitempty"`

	// CarrierAndIspDetails: Carrier and ISP details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_CARRIER_AND_ISP`.
	CarrierAndIspDetails *CarrierAndIspAssignedTargetingOptionDetails `json:"carrierAndIspDetails,omitempty"`

	// CategoryDetails: Category details. This field will be populated when
	// the TargetingType is
	// `TARGETING_TYPE_CATEGORY`.
	//
	// Targeting a category will also target its subcategories. If a
	// category is
	// excluded from targeting and a subcategory is included, the exclusion
	// will
	// take precedence.
	CategoryDetails *CategoryAssignedTargetingOptionDetails `json:"categoryDetails,omitempty"`

	// ChannelDetails: Channel details. This field will be populated when
	// the
	// TargetingType is `TARGETING_TYPE_CHANNEL`.
	ChannelDetails *ChannelAssignedTargetingOptionDetails `json:"channelDetails,omitempty"`

	// ContentInstreamPositionDetails: Content instream position details.
	// This field will be populated when the
	// TargetingType is `TARGETING_TYPE_CONTENT_INSTREAM_POSITION`.
	ContentInstreamPositionDetails *ContentInstreamPositionAssignedTargetingOptionDetails `json:"contentInstreamPositionDetails,omitempty"`

	// ContentOutstreamPositionDetails: Content outstream position details.
	// This field will be populated when the
	// TargetingType is `TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION`.
	ContentOutstreamPositionDetails *ContentOutstreamPositionAssignedTargetingOptionDetails `json:"contentOutstreamPositionDetails,omitempty"`

	// DayAndTimeDetails: Day and time details. This field will be populated
	// when the
	// TargetingType is `TARGETING_TYPE_DAY_AND_TIME`.
	DayAndTimeDetails *DayAndTimeAssignedTargetingOptionDetails `json:"dayAndTimeDetails,omitempty"`

	// DeviceMakeModelDetails: Device make and model details. This field
	// will be populated when the
	// TargetingType is `TARGETING_TYPE_DEVICE_MAKE_MODEL`.
	DeviceMakeModelDetails *DeviceMakeModelAssignedTargetingOptionDetails `json:"deviceMakeModelDetails,omitempty"`

	// DeviceTypeDetails: Device Type details. This field will be populated
	// when the
	// TargetingType is
	// `TARGETING_TYPE_DEVICE_TYPE`.
	DeviceTypeDetails *DeviceTypeAssignedTargetingOptionDetails `json:"deviceTypeDetails,omitempty"`

	// DigitalContentLabelExclusionDetails: Digital content label details.
	// This field will be populated when the
	// TargetingType is
	// `TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION`.
	//
	// Digital content labels are targeting exclusions. Advertiser level
	// digital
	// content label exclusions, if set, are always applied in serving
	// (even
	// though they aren't visible in line item settings). Line item settings
	// can
	// exclude content labels in addition to advertiser exclusions, but
	// can't
	// override them. A line item won't serve if all the digital content
	// labels
	// are excluded.
	DigitalContentLabelExclusionDetails *DigitalContentLabelAssignedTargetingOptionDetails `json:"digitalContentLabelExclusionDetails,omitempty"`

	// EnvironmentDetails: Environment details. This field will be populated
	// when the
	// TargetingType is `TARGETING_TYPE_ENVIRONMENT`.
	EnvironmentDetails *EnvironmentAssignedTargetingOptionDetails `json:"environmentDetails,omitempty"`

	// ExchangeDetails: Exchange details. This field will be populated when
	// the
	// TargetingType is `TARGETING_TYPE_EXCHANGE`.
	ExchangeDetails *ExchangeAssignedTargetingOptionDetails `json:"exchangeDetails,omitempty"`

	// GenderDetails: Gender details. This field will be populated when
	// the
	// TargetingType is `TARGETING_TYPE_GENDER`.
	GenderDetails *GenderAssignedTargetingOptionDetails `json:"genderDetails,omitempty"`

	// GeoRegionDetails: Geographic region details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_GEO_REGION`.
	GeoRegionDetails *GeoRegionAssignedTargetingOptionDetails `json:"geoRegionDetails,omitempty"`

	// HouseholdIncomeDetails: Household income details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_HOUSEHOLD_INCOME`.
	HouseholdIncomeDetails *HouseholdIncomeAssignedTargetingOptionDetails `json:"householdIncomeDetails,omitempty"`

	// Inheritance: Output only. The inheritance status of the assigned
	// targeting option.
	//
	// Possible values:
	//   "INHERITANCE_UNSPECIFIED" - The inheritance is unspecified or
	// unknown.
	//   "NOT_INHERITED" - The assigned targeting option is not inherited
	// from higher level entity.
	//   "INHERITED_FROM_PARTNER" - The assigned targeting option is
	// inherited from partner targeting
	// settings.
	//   "INHERITED_FROM_ADVERTISER" - The assigned targeting option is
	// inherited from advertiser targeting
	// settings.
	Inheritance string `json:"inheritance,omitempty"`

	// InventorySourceDetails: Inventory source details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_INVENTORY_SOURCE`.
	InventorySourceDetails *InventorySourceAssignedTargetingOptionDetails `json:"inventorySourceDetails,omitempty"`

	// InventorySourceGroupDetails: Inventory source group details. This
	// field will be populated when the
	// TargetingType is `TARGETING_TYPE_INVENTORY_SOURCE_GROUP`.
	InventorySourceGroupDetails *InventorySourceGroupAssignedTargetingOptionDetails `json:"inventorySourceGroupDetails,omitempty"`

	// KeywordDetails: Keyword details. This field will be populated when
	// the TargetingType is
	// `TARGETING_TYPE_KEYWORD`.
	//
	// A maximum of 5000 direct negative keywords can be assigned to a
	// line item. No limit on number of positive keywords that can be
	// assigned.
	KeywordDetails *KeywordAssignedTargetingOptionDetails `json:"keywordDetails,omitempty"`

	// LanguageDetails: Language details. This field will be populated when
	// the TargetingType is
	// `TARGETING_TYPE_LANGUAGE`.
	LanguageDetails *LanguageAssignedTargetingOptionDetails `json:"languageDetails,omitempty"`

	// Name: Output only. The resource name for this assigned targeting
	// option.
	Name string `json:"name,omitempty"`

	// NegativeKeywordListDetails: Keyword details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_NEGATIVE_KEYWORD_LIST`.
	//
	// A maximum of 4 negative keyword lists can be assigned to a line item.
	NegativeKeywordListDetails *NegativeKeywordListAssignedTargetingOptionDetails `json:"negativeKeywordListDetails,omitempty"`

	// OnScreenPositionDetails: On screen position details. This field will
	// be populated when the
	// TargetingType is `TARGETING_TYPE_ON_SCREEN_POSITION`.
	OnScreenPositionDetails *OnScreenPositionAssignedTargetingOptionDetails `json:"onScreenPositionDetails,omitempty"`

	// OperatingSystemDetails: Operating system details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_OPERATING_SYSTEM`.
	OperatingSystemDetails *OperatingSystemAssignedTargetingOptionDetails `json:"operatingSystemDetails,omitempty"`

	// ParentalStatusDetails: Parental status details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_PARENTAL_STATUS`.
	ParentalStatusDetails *ParentalStatusAssignedTargetingOptionDetails `json:"parentalStatusDetails,omitempty"`

	// ProximityLocationListDetails: Proximity location list details. This
	// field will be populated when the
	// TargetingType is
	// `TARGETING_TYPE_PROXIMITY_LOCATION_LIST`.
	ProximityLocationListDetails *ProximityLocationListAssignedTargetingOptionDetails `json:"proximityLocationListDetails,omitempty"`

	// RegionalLocationListDetails: Regional location list details. This
	// field will be populated when the
	// TargetingType is `TARGETING_TYPE_REGIONAL_LOCATION_LIST`.
	RegionalLocationListDetails *RegionalLocationListAssignedTargetingOptionDetails `json:"regionalLocationListDetails,omitempty"`

	// SensitiveCategoryExclusionDetails: Sensitive category details. This
	// field will be populated when the
	// TargetingType is
	// `TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION`.
	//
	// Sensitive categories are targeting exclusions. Advertiser level
	// sensitive
	// category exclusions, if set, are always applied in serving (even
	// though
	// they aren't visible in line item settings). Line item settings
	// can
	// exclude sensitive categories in addition to advertiser exclusions,
	// but
	// can't override them.
	SensitiveCategoryExclusionDetails *SensitiveCategoryAssignedTargetingOptionDetails `json:"sensitiveCategoryExclusionDetails,omitempty"`

	// SubExchangeDetails: Sub-exchange details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_SUB_EXCHANGE`.
	SubExchangeDetails *SubExchangeAssignedTargetingOptionDetails `json:"subExchangeDetails,omitempty"`

	// TargetingType: Output only. Identifies the type of this assigned
	// targeting option.
	//
	// Possible values:
	//   "TARGETING_TYPE_UNSPECIFIED" - Default value when type is not
	// specified or is unknown in this version.
	//   "TARGETING_TYPE_CHANNEL" - Target a channel (a custom group of
	// related websites or apps).
	//   "TARGETING_TYPE_APP_CATEGORY" - Target an app category (for
	// example, education or puzzle games).
	//   "TARGETING_TYPE_APP" - Target a specific app (for example, Angry
	// Birds).
	//   "TARGETING_TYPE_URL" - Target a specific url (for example,
	// quora.com).
	//   "TARGETING_TYPE_DAY_AND_TIME" - Target ads during a chosen time
	// period on a specific day.
	//   "TARGETING_TYPE_AGE_RANGE" - Target ads to a specific age range
	// (for example, 18-24).
	//   "TARGETING_TYPE_REGIONAL_LOCATION_LIST" - Target ads to the
	// specified regions on a regional location list.
	//   "TARGETING_TYPE_PROXIMITY_LOCATION_LIST" - Target ads to the
	// specified points of interest on a proximity location
	// list.
	//   "TARGETING_TYPE_GENDER" - Target ads to a specific gender (for
	// example, female or male).
	//   "TARGETING_TYPE_VIDEO_PLAYER_SIZE" - Target a specific video player
	// size for video ads.
	//   "TARGETING_TYPE_USER_REWARDED_CONTENT" - Target user rewarded
	// content for video ads.
	//   "TARGETING_TYPE_PARENTAL_STATUS" - Target ads to a specific
	// parental status (for example, parent or not a
	// parent).
	//   "TARGETING_TYPE_CONTENT_INSTREAM_POSITION" - Target video or audio
	// ads in a specific content instream position (for
	// example, pre-roll, mid-roll, or post-roll).
	//   "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION" - Target ads in a
	// specific content outstream position.
	//   "TARGETING_TYPE_DEVICE_TYPE" - Target ads to a specific device type
	// (for example, tablet or connected TV).
	//   "TARGETING_TYPE_AUDIENCE_GROUP" - Target ads to an audience or
	// groups of audiences.
	// Singleton field, at most one can exist on a single Lineitem at a
	// time.
	//   "TARGETING_TYPE_BROWSER" - Target ads to specific web browsers (for
	// example, Chrome).
	//   "TARGETING_TYPE_HOUSEHOLD_INCOME" - Target ads to a specific
	// household income range (for example, top 10%).
	//   "TARGETING_TYPE_ON_SCREEN_POSITION" - Target ads in a specific on
	// screen position.
	//   "TARGETING_TYPE_THIRD_PARTY_VERIFIER" - Filter web sites through
	// third party verification (for example, IAS or
	// DoubleVerify).
	//   "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION" - Filter web sites
	// by specific digital content label ratings (for example,
	// DL-MA: suitable only for mature audiences).
	//   "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION" - Filter website
	// content by sensitive categories (for example, adult).
	//   "TARGETING_TYPE_ENVIRONMENT" - Target ads to a specific environment
	// (for example, web or app).
	//   "TARGETING_TYPE_CARRIER_AND_ISP" - Target ads to a specific network
	// carrier or internet service provider
	// (ISP) (for example, Comcast or Orange).
	//   "TARGETING_TYPE_OPERATING_SYSTEM" - Target ads to a specific
	// operating system (for example, macOS).
	//   "TARGETING_TYPE_DEVICE_MAKE_MODEL" - Target ads to a specific
	// device make or model (for example, Roku or
	// Samsung).
	//   "TARGETING_TYPE_KEYWORD" - Target ads to a specific keyword (for
	// example, dog or retriever).
	//   "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST" - Target ads to a specific
	// negative keyword list.
	//   "TARGETING_TYPE_VIEWABILITY" - Target ads to a specific viewability
	// (for example, 80% viewable).
	//   "TARGETING_TYPE_CATEGORY" - Target ads to a specific content
	// category (for example, arts &
	// entertainment).
	//   "TARGETING_TYPE_INVENTORY_SOURCE" - Purchase impressions from
	// specific deals and auction packages.
	//   "TARGETING_TYPE_LANGUAGE" - Target ads to a specific language (for
	// example, English or Japanese).
	//   "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS" - Target ads to ads.txt
	// authorized sellers.
	//   "TARGETING_TYPE_GEO_REGION" - Target ads to a specific regional
	// location (for example, a city or state).
	//   "TARGETING_TYPE_INVENTORY_SOURCE_GROUP" - Purchase impressions from
	// a group of deals and auction packages.
	//   "TARGETING_TYPE_EXCHANGE" - Purchase impressions from specific
	// exchanges.
	//   "TARGETING_TYPE_SUB_EXCHANGE" - Purchase impressions from specific
	// sub-exchanges.
	TargetingType string `json:"targetingType,omitempty"`

	// ThirdPartyVerifierDetails: Third party verification details. This
	// field will be populated when the
	// TargetingType is `TARGETING_TYPE_THIRD_PARTY_VERIFIER`.
	ThirdPartyVerifierDetails *ThirdPartyVerifierAssignedTargetingOptionDetails `json:"thirdPartyVerifierDetails,omitempty"`

	// UrlDetails: URL details. This field will be populated when
	// the
	// TargetingType is `TARGETING_TYPE_URL`.
	UrlDetails *UrlAssignedTargetingOptionDetails `json:"urlDetails,omitempty"`

	// UserRewardedContentDetails: User rewarded content details. This field
	// will be populated when the
	// TargetingType is
	// `TARGETING_TYPE_USER_REWARDED_CONTENT`.
	UserRewardedContentDetails *UserRewardedContentAssignedTargetingOptionDetails `json:"userRewardedContentDetails,omitempty"`

	// VideoPlayerSizeDetails: Video player size details. This field will be
	// populated when the
	// TargetingType is `TARGETING_TYPE_VIDEO_PLAYER_SIZE`.
	VideoPlayerSizeDetails *VideoPlayerSizeAssignedTargetingOptionDetails `json:"videoPlayerSizeDetails,omitempty"`

	// ViewabilityDetails: Viewability details. This field will be populated
	// when the TargetingType
	// is `TARGETING_TYPE_VIEWABILITY`.
	//
	// You can only target one viewability option per line item.
	ViewabilityDetails *ViewabilityAssignedTargetingOptionDetails `json:"viewabilityDetails,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AgeRangeDetails") 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. "AgeRangeDetails") 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 *AssignedTargetingOption) MarshalJSON() ([]byte, error) {
	type NoMethod AssignedTargetingOption
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AudienceGroupAssignedTargetingOptionDetails: Assigned audience group
// targeting option details. This will be populated in
// the details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_AUDIENCE_GROUP`.
// The relation between each group is UNION, except
// for
// excluded_first_and_third_party_audience_group
// and
// excluded_google_audience_group, of which COMPLEMENT is UNION'ed with
// other
// groups.
type AudienceGroupAssignedTargetingOptionDetails struct {
	// ExcludedFirstAndThirdPartyAudienceGroup: The first and third party
	// audience ids and recencies of the excluded
	// first and third party audience group. Used for negative targeting.
	// Its
	// COMPLEMENT is used to UNION other audience groups.
	ExcludedFirstAndThirdPartyAudienceGroup *FirstAndThirdPartyAudienceGroup `json:"excludedFirstAndThirdPartyAudienceGroup,omitempty"`

	// ExcludedGoogleAudienceGroup: The Google audience ids of the excluded
	// Google audience group.
	// Used for negative targeting. It's COMPLEMENT is used to UNION
	// other
	// audience groups.
	// Only contains Affinity, In-market and Installed-apps type Google
	// audiences.
	// All items are logically ‘OR’ of each other.
	ExcludedGoogleAudienceGroup *GoogleAudienceGroup `json:"excludedGoogleAudienceGroup,omitempty"`

	// IncludedCombinedAudienceGroup: The combined audience ids of the
	// included combined audience group.
	// Contains combined audience ids only.
	IncludedCombinedAudienceGroup *CombinedAudienceGroup `json:"includedCombinedAudienceGroup,omitempty"`

	// IncludedCustomListGroup: The custom list ids of the included custom
	// list group.
	// Contains custom list ids only.
	IncludedCustomListGroup *CustomListGroup `json:"includedCustomListGroup,omitempty"`

	// IncludedFirstAndThirdPartyAudienceGroups: The first and third party
	// audience ids and recencies of included first
	// and third party audience groups. Each first and third party audience
	// group
	// contains first and third party audience ids only.
	// The relation between each first and third party audience group
	// is
	// INTERSECTION, and the result is UNION'ed with other audience
	// groups.
	// Repeated groups with same settings will be ignored.
	IncludedFirstAndThirdPartyAudienceGroups []*FirstAndThirdPartyAudienceGroup `json:"includedFirstAndThirdPartyAudienceGroups,omitempty"`

	// IncludedGoogleAudienceGroup: The Google audience ids of the included
	// Google audience group.
	// Contains Google audience ids only.
	IncludedGoogleAudienceGroup *GoogleAudienceGroup `json:"includedGoogleAudienceGroup,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ExcludedFirstAndThirdPartyAudienceGroup") 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.
	// "ExcludedFirstAndThirdPartyAudienceGroup") 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 *AudienceGroupAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AudienceGroupAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AudioVideoOffset: The length an audio or a video has been played.
type AudioVideoOffset struct {
	// Percentage: The offset in percentage of the audio or video duration.
	Percentage int64 `json:"percentage,omitempty,string"`

	// Seconds: The offset in seconds from the start of the audio or video.
	Seconds int64 `json:"seconds,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Percentage") 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. "Percentage") 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 *AudioVideoOffset) MarshalJSON() ([]byte, error) {
	type NoMethod AudioVideoOffset
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AuthorizedSellerStatusAssignedTargetingOptionDetails: Represents an
// assigned authorized seller status. This will be populated in
// the details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_AUTHORIZED_SELLER_STATUS`.
type AuthorizedSellerStatusAssignedTargetingOptionDetails struct {
	// AuthorizedSellerStatus: Output only. The authorized seller status to
	// target.
	//
	// Possible values:
	//   "AUTHORIZED_SELLER_STATUS_UNSPECIFIED" - Default value when
	// authorized seller status is not specified in this
	// version. This enum is a placeholder for default value and does
	// not
	// represent a real authorized seller status option.
	//   "AUTHORIZED_SELLER_STATUS_AUTHORIZED_DIRECT_SELLERS_ONLY" - Only
	// authorized sellers that directly own the inventory being monetized,
	// as
	// indicated by a DIRECT declaration in the ads.txt file.
	//
	// "AUTHORIZED_SELLER_STATUS_AUTHORIZED_AND_NON_PARTICIPATING_PUBLISHERS"
	//  - All authorized sellers, including publishers that have not posted
	// an
	// ads.txt file. Display & Video 360 automatically disallows
	// unauthorized
	// sellers.
	AuthorizedSellerStatus string `json:"authorizedSellerStatus,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_AUTHORIZED_SELLER_STATUS`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AuthorizedSellerStatus") 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. "AuthorizedSellerStatus")
	// 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 *AuthorizedSellerStatusAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AuthorizedSellerStatusAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AuthorizedSellerStatusTargetingOptionDetails: Represents a targetable
// authorized seller status. This will be populated
// in
// the
// authorized_seller_status_details
// field when targeting_type
// is
// `TARGETING_TYPE_AUTHORIZED_SELLER_STATUS`.
type AuthorizedSellerStatusTargetingOptionDetails struct {
	// AuthorizedSellerStatus: Output only. The authorized seller status.
	//
	// Possible values:
	//   "AUTHORIZED_SELLER_STATUS_UNSPECIFIED" - Default value when
	// authorized seller status is not specified in this
	// version. This enum is a placeholder for default value and does
	// not
	// represent a real authorized seller status option.
	//   "AUTHORIZED_SELLER_STATUS_AUTHORIZED_DIRECT_SELLERS_ONLY" - Only
	// authorized sellers that directly own the inventory being monetized,
	// as
	// indicated by a DIRECT declaration in the ads.txt file.
	//
	// "AUTHORIZED_SELLER_STATUS_AUTHORIZED_AND_NON_PARTICIPATING_PUBLISHERS"
	//  - All authorized sellers, including publishers that have not posted
	// an
	// ads.txt file. Display & Video 360 automatically disallows
	// unauthorized
	// sellers.
	AuthorizedSellerStatus string `json:"authorizedSellerStatus,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AuthorizedSellerStatus") 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. "AuthorizedSellerStatus")
	// 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 *AuthorizedSellerStatusTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod AuthorizedSellerStatusTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BiddingStrategy: Settings that control the bid strategy.
// Bid strategy determines the bid price.
type BiddingStrategy struct {
	// FixedBid: A strategy that uses a fixed bid price.
	FixedBid *FixedBidStrategy `json:"fixedBid,omitempty"`

	// MaximizeSpendAutoBid: A strategy that automatically adjusts the bid
	// to optimize to your
	// performance goal while spending the full budget.
	//
	// At insertion order level, the
	// markup_type of line items
	// cannot be set to `PARTNER_REVENUE_MODEL_MARKUP_TYPE_CPM`. In
	// addition,
	// when
	// performance_goal_type
	// is one of:
	//
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPA`
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPC`
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_AV_VIEWED` ,
	//
	// the line_item_type
	// of the insertion order line items must be either:
	//
	// * `LINE_ITEM_TYPE_DISPLAY_DEFAULT`
	// * `LINE_ITEM_TYPE_VIDEO_DEFAULT` ,
	//
	// and when
	// performance_goal_type
	// is either:
	//
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CIVA`
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_IVO_TEN`
	//
	// the line_item_type
	// of the insertion order line items must be
	// `LINE_ITEM_TYPE_VIDEO_DEFAULT`.
	MaximizeSpendAutoBid *MaximizeSpendBidStrategy `json:"maximizeSpendAutoBid,omitempty"`

	// PerformanceGoalAutoBid: A strategy that automatically adjusts the bid
	// to meet or beat a specified
	// performance goal. It is to be used only for a line item entity.
	PerformanceGoalAutoBid *PerformanceGoalBidStrategy `json:"performanceGoalAutoBid,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FixedBid") 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. "FixedBid") 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 *BiddingStrategy) MarshalJSON() ([]byte, error) {
	type NoMethod BiddingStrategy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BrowserAssignedTargetingOptionDetails: Details for assigned browser
// targeting option. This will be populated in
// the details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_BROWSER`.
type BrowserAssignedTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the browser.
	DisplayName string `json:"displayName,omitempty"`

	// Negative: Indicates if this option is being negatively targeted. All
	// assigned browser
	// targeting options on the same line item must have the same value for
	// this
	// field.
	Negative bool `json:"negative,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_BROWSER`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *BrowserAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod BrowserAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BrowserTargetingOptionDetails: Represents a targetable browser. This
// will be populated in the
// browser_details field when
// targeting_type is
// `TARGETING_TYPE_BROWSER`.
type BrowserTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the browser.
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *BrowserTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod BrowserTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BulkEditAdvertiserAssignedTargetingOptionsRequest: Request message
// for
// BulkEditAdvertiserAssignedTargetingOptions.
type BulkEditAdvertiserAssignedTargetingOptionsRequest struct {
	// CreateRequests: The assigned targeting options to create in batch,
	// specified as a list of
	// `CreateAssignedTargetingOptionsRequest`.
	CreateRequests []*CreateAssignedTargetingOptionsRequest `json:"createRequests,omitempty"`

	// DeleteRequests: The assigned targeting options to delete in batch,
	// specified as a list of
	// `DeleteAssignedTargetingOptionsRequest`.
	DeleteRequests []*DeleteAssignedTargetingOptionsRequest `json:"deleteRequests,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateRequests") 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. "CreateRequests") 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 *BulkEditAdvertiserAssignedTargetingOptionsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod BulkEditAdvertiserAssignedTargetingOptionsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BulkEditAdvertiserAssignedTargetingOptionsResponse struct {
	// CreatedAssignedTargetingOptions: The list of assigned targeting
	// options that have been successfully created.
	//
	// This list will be absent if empty.
	CreatedAssignedTargetingOptions []*AssignedTargetingOption `json:"createdAssignedTargetingOptions,omitempty"`

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

	// ForceSendFields is a list of field names (e.g.
	// "CreatedAssignedTargetingOptions") 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.
	// "CreatedAssignedTargetingOptions") 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 *BulkEditAdvertiserAssignedTargetingOptionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BulkEditAdvertiserAssignedTargetingOptionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BulkEditLineItemAssignedTargetingOptionsRequest: Request message
// for
// BulkEditLineItemAssignedTargetingOptions.
type BulkEditLineItemAssignedTargetingOptionsRequest struct {
	// CreateRequests: The assigned targeting options to create in batch,
	// specified as a list of
	// `CreateAssignedTargetingOptionsRequest`.
	CreateRequests []*CreateAssignedTargetingOptionsRequest `json:"createRequests,omitempty"`

	// DeleteRequests: The assigned targeting options to delete in batch,
	// specified as a list of
	// `DeleteAssignedTargetingOptionsRequest`.
	DeleteRequests []*DeleteAssignedTargetingOptionsRequest `json:"deleteRequests,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateRequests") 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. "CreateRequests") 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 *BulkEditLineItemAssignedTargetingOptionsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod BulkEditLineItemAssignedTargetingOptionsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BulkEditLineItemAssignedTargetingOptionsResponse struct {
	// CreatedAssignedTargetingOptions: The list of assigned targeting
	// options that have been successfully created.
	//
	// This list will be absent if empty.
	CreatedAssignedTargetingOptions []*AssignedTargetingOption `json:"createdAssignedTargetingOptions,omitempty"`

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

	// ForceSendFields is a list of field names (e.g.
	// "CreatedAssignedTargetingOptions") 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.
	// "CreatedAssignedTargetingOptions") 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 *BulkEditLineItemAssignedTargetingOptionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BulkEditLineItemAssignedTargetingOptionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BulkListAdvertiserAssignedTargetingOptionsResponse struct {
	// AssignedTargetingOptions: The list of assigned targeting
	// options.
	//
	// This list will be absent if empty.
	AssignedTargetingOptions []*AssignedTargetingOption `json:"assignedTargetingOptions,omitempty"`

	// NextPageToken: A token identifying the next page of results. This
	// value should be
	// specified as the
	// pageToken
	// in a subsequent BulkListAdvertiserAssignedTargetingOptionsRequest
	// to
	// fetch the next page of results. This token will be absent if there
	// are no
	// more
	// assigned_targeting_options
	// to return.
	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.
	// "AssignedTargetingOptions") 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. "AssignedTargetingOptions")
	// 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 *BulkListAdvertiserAssignedTargetingOptionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BulkListAdvertiserAssignedTargetingOptionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BulkListLineItemAssignedTargetingOptionsResponse struct {
	// AssignedTargetingOptions: The list of assigned targeting
	// options.
	//
	// This list will be absent if empty.
	AssignedTargetingOptions []*AssignedTargetingOption `json:"assignedTargetingOptions,omitempty"`

	// NextPageToken: A token identifying the next page of results. This
	// value should be
	// specified as the
	// pageToken in
	// a subsequent BulkListLineItemAssignedTargetingOptionsRequest to
	// fetch
	// the next page of results. This token will be absent if there are no
	// more
	// assigned_targeting_options
	// to return.
	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.
	// "AssignedTargetingOptions") 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. "AssignedTargetingOptions")
	// 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 *BulkListLineItemAssignedTargetingOptionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BulkListLineItemAssignedTargetingOptionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Campaign: A single campaign.
type Campaign struct {
	// AdvertiserId: Output only. The unique ID of the advertiser the
	// campaign belongs to.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// CampaignFlight: Required. The planned spend and duration of the
	// campaign.
	CampaignFlight *CampaignFlight `json:"campaignFlight,omitempty"`

	// CampaignGoal: Required. The goal of the campaign.
	CampaignGoal *CampaignGoal `json:"campaignGoal,omitempty"`

	// CampaignId: Output only. The unique ID of the campaign. Assigned by
	// the system.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// DisplayName: Required. The display name of the campaign.
	//
	// Must be UTF-8 encoded with a maximum size of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// EntityStatus: Required. Controls whether or not the insertion orders
	// under this campaign
	// can spend their budgets and bid on inventory.
	//
	// * Accepted values are `ENTITY_STATUS_ACTIVE`,
	// `ENTITY_STATUS_ARCHIVED`, and
	// `ENTITY_STATUS_PAUSED`.
	// * For
	// CreateCampaign method,
	// `ENTITY_STATUS_ARCHIVED` is not allowed.
	//
	// Possible values:
	//   "ENTITY_STATUS_UNSPECIFIED" - Default value when status is not
	// specified or is unknown in this version.
	//   "ENTITY_STATUS_ACTIVE" - The entity is enabled to bid and spend
	// budget.
	//   "ENTITY_STATUS_ARCHIVED" - The entity is archived. Bidding and
	// budget spending are disabled. An
	// entity can be deleted after archived. Deleted entities cannot be
	// retrieved.
	//   "ENTITY_STATUS_DRAFT" - The entity is under draft. Bidding and
	// budget spending are disabled.
	//   "ENTITY_STATUS_PAUSED" - Bidding and budget spending are paused for
	// the entity.
	//   "ENTITY_STATUS_SCHEDULED_FOR_DELETION" - The entity is scheduled
	// for deletion.
	EntityStatus string `json:"entityStatus,omitempty"`

	// FrequencyCap: Required. The frequency cap setting of the campaign.
	FrequencyCap *FrequencyCap `json:"frequencyCap,omitempty"`

	// Name: Output only. The resource name of the campaign.
	Name string `json:"name,omitempty"`

	// UpdateTime: Output only. The timestamp when the campaign was last
	// updated. Assigned by the system.
	UpdateTime string `json:"updateTime,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "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 *Campaign) MarshalJSON() ([]byte, error) {
	type NoMethod Campaign
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CampaignFlight: Settings that track the planned spend and duration of
// a campaign.
type CampaignFlight struct {
	// PlannedDates: Required. The dates that the campaign is expected to
	// run. They are resolved
	// relative to the parent advertiser's time zone.
	//
	// * The dates specified here will not affect serving. They are used
	// to
	// generate alerts and warnings. For example, if the flight date of any
	// child
	// insertion order is outside the range of these dates, the user
	// interface
	// will show a warning.
	// * `start_date` is required and must be the current date or later.
	// * `end_date` is optional. If specified, it must be the `start_date`
	// or
	// later.
	// * Any specified date must be before the year 2037.
	PlannedDates *DateRange `json:"plannedDates,omitempty"`

	// PlannedSpendAmountMicros: The amount the campaign is expected to
	// spend for its given
	// planned_dates. This will not limit serving,
	// but will be used for tracking spend in the DV360 UI.
	//
	// The amount is in micros. Must be greater than or equal to 0. For
	// example,
	// 500000000 represents 500 standard units of the currency.
	PlannedSpendAmountMicros int64 `json:"plannedSpendAmountMicros,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "PlannedDates") 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. "PlannedDates") 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 *CampaignFlight) MarshalJSON() ([]byte, error) {
	type NoMethod CampaignFlight
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CampaignGoal: Settings that control the goal of a campaign.
type CampaignGoal struct {
	// CampaignGoalType: Required. The type of the campaign goal.
	//
	// Possible values:
	//   "CAMPAIGN_GOAL_TYPE_UNSPECIFIED" - Goal value is not specified or
	// unknown in this version.
	//   "CAMPAIGN_GOAL_TYPE_APP_INSTALL" - Drive app installs or
	// engagements.
	//   "CAMPAIGN_GOAL_TYPE_BRAND_AWARENESS" - Raise awareness of a brand
	// or product.
	//   "CAMPAIGN_GOAL_TYPE_OFFLINE_ACTION" - Drive offline or in-store
	// sales.
	//   "CAMPAIGN_GOAL_TYPE_ONLINE_ACTION" - Drive online action or visits.
	CampaignGoalType string `json:"campaignGoalType,omitempty"`

	// PerformanceGoal: Required. The performance goal of the
	// campaign.
	//
	// Acceptable values for
	// performance_goal_type are:
	//
	// * `PERFORMANCE_GOAL_TYPE_CPM`
	// * `PERFORMANCE_GOAL_TYPE_CPC`
	// * `PERFORMANCE_GOAL_TYPE_CPA`
	// * `PERFORMANCE_GOAL_TYPE_CPIAVC`
	// * `PERFORMANCE_GOAL_TYPE_CTR`
	// * `PERFORMANCE_GOAL_TYPE_VIEWABILITY`
	// * `PERFORMANCE_GOAL_TYPE_OTHER`
	PerformanceGoal *PerformanceGoal `json:"performanceGoal,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CampaignGoalType") 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. "CampaignGoalType") 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 *CampaignGoal) MarshalJSON() ([]byte, error) {
	type NoMethod CampaignGoal
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CarrierAndIspAssignedTargetingOptionDetails: Details for assigned
// carrier and ISP targeting option. This will be populated
// in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_CARRIER_AND_ISP`.
type CarrierAndIspAssignedTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the carrier or ISP.
	DisplayName string `json:"displayName,omitempty"`

	// Negative: Indicates if this option is being negatively targeted. All
	// assigned carrier
	// and ISP targeting options on the same line item must have the same
	// value
	// for this field.
	Negative bool `json:"negative,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_CARRIER_AND_ISP`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *CarrierAndIspAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod CarrierAndIspAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CarrierAndIspTargetingOptionDetails: Represents a targetable carrier
// or ISP. This will be populated in the
// carrier_and_isp_details field of
// a TargetingOption when
// targeting_type is
// `TARGETING_TYPE_CARRIER_AND_ISP`.
type CarrierAndIspTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the carrier or ISP.
	DisplayName string `json:"displayName,omitempty"`

	// Type: Output only. The type indicating if it's carrier or ISP.
	//
	// Possible values:
	//   "CARRIER_AND_ISP_TYPE_UNSPECIFIED" - Default value when type is not
	// specified or is unknown in this version.
	//   "CARRIER_AND_ISP_TYPE_ISP" - Indicates this targeting resource
	// refers to an ISP.
	//   "CARRIER_AND_ISP_TYPE_CARRIER" - Indicates this targeting resource
	// refers to a mobile carrier.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *CarrierAndIspTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod CarrierAndIspTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CategoryAssignedTargetingOptionDetails: Assigned category targeting
// option details. This will be populated in the
// category_details field when
// targeting_type is
// `TARGETING_TYPE_CATEGORY`.
type CategoryAssignedTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the category.
	DisplayName string `json:"displayName,omitempty"`

	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id field
	// when
	// targeting_type is
	// `TARGETING_TYPE_CATEGORY`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *CategoryAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod CategoryAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CategoryTargetingOptionDetails: Represents a targetable category.
// This will be populated in the
// category_details field of a
// TargetingOption when targeting_type is
// `TARGETING_TYPE_CATEGORY`.
type CategoryTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the category.
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *CategoryTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod CategoryTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Channel: A single channel. Channels are custom groups of related
// websites and apps.
type Channel struct {
	// AdvertiserId: The ID of the advertiser that owns the channel.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// ChannelId: Output only. The unique ID of the channel. Assigned by the
	// system.
	ChannelId int64 `json:"channelId,omitempty,string"`

	// DisplayName: Required. The display name of the channel.
	// Must be UTF-8 encoded with a maximum length of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// Name: Output only. The resource name of the channel.
	Name string `json:"name,omitempty"`

	// PartnerId: The ID of the partner that owns the channel.
	PartnerId int64 `json:"partnerId,omitempty,string"`

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

	// 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 *Channel) MarshalJSON() ([]byte, error) {
	type NoMethod Channel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ChannelAssignedTargetingOptionDetails: Details for assigned channel
// targeting option. This will be populated in
// the details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_CHANNEL`.
type ChannelAssignedTargetingOptionDetails struct {
	// ChannelId: Required. ID of the channel. Should refer to the channel
	// ID
	// field on a
	// [Partner-owned channel](partners.channels#Channel.FIELDS.channel_id)
	// or
	// [advertiser-owned
	// channel](advertisers.channels#Channel.FIELDS.channel_id)
	// resource.
	ChannelId int64 `json:"channelId,omitempty,string"`

	// Negative: Indicates if this option is being negatively targeted. For
	// advertiser
	// level assigned targeting option, this field must be true.
	Negative bool `json:"negative,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChannelId") 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. "ChannelId") 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 *ChannelAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ChannelAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CmHybridConfig: Settings for advertisers that use both Campaign
// Manager (CM) and third-party
// ad servers.
type CmHybridConfig struct {
	// CmAccountId: Required. Immutable. Account ID of the CM Floodlight
	// configuration linked with the DV360
	// advertiser.
	CmAccountId int64 `json:"cmAccountId,omitempty,string"`

	// CmFloodlightConfigId: Required. Immutable. ID of the CM Floodlight
	// configuration linked with the DV360 advertiser.
	CmFloodlightConfigId int64 `json:"cmFloodlightConfigId,omitempty,string"`

	// CmFloodlightLinkingAuthorized: Required. Immutable. By setting this
	// field to `true`, you, on behalf of your company,
	// authorize the sharing of information from the given
	// Floodlight
	// configuration to this Display & Video 360 advertiser.
	CmFloodlightLinkingAuthorized bool `json:"cmFloodlightLinkingAuthorized,omitempty"`

	// CmSyncableSiteIds: A list of CM sites whose placements will be synced
	// to DV360 as creatives.
	//
	// If absent or empty in
	// CreateAdvertiser method, the system
	// will automatically create a CM site.
	//
	// Removing sites from this list may cause DV360 creatives synced from
	// CM to
	// be deleted. At least one site must be specified.
	CmSyncableSiteIds googleapi.Int64s `json:"cmSyncableSiteIds,omitempty"`

	// Dv360ToCmCostReportingEnabled: Whether or not to report DV360 cost to
	// CM.
	Dv360ToCmCostReportingEnabled bool `json:"dv360ToCmCostReportingEnabled,omitempty"`

	// Dv360ToCmDataSharingEnabled: Whether or not to include DV360 data in
	// CM data transfer reports.
	Dv360ToCmDataSharingEnabled bool `json:"dv360ToCmDataSharingEnabled,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CmAccountId") 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. "CmAccountId") 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 *CmHybridConfig) MarshalJSON() ([]byte, error) {
	type NoMethod CmHybridConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CmTrackingAd: A Campaign Manager tracking ad.
type CmTrackingAd struct {
	// CmAdId: The ad ID of the campaign manager tracking Ad.
	CmAdId int64 `json:"cmAdId,omitempty,string"`

	// CmCreativeId: The creative ID of the campaign manager tracking Ad.
	CmCreativeId int64 `json:"cmCreativeId,omitempty,string"`

	// CmPlacementId: The placement ID of the campaign manager tracking Ad.
	CmPlacementId int64 `json:"cmPlacementId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CmAdId") 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. "CmAdId") 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 *CmTrackingAd) MarshalJSON() ([]byte, error) {
	type NoMethod CmTrackingAd
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CombinedAudience: Describes a combined audience resource.
type CombinedAudience struct {
	// CombinedAudienceId: Output only. The unique ID of the combined
	// audience. Assigned by the system.
	CombinedAudienceId int64 `json:"combinedAudienceId,omitempty,string"`

	// DisplayName: Output only. The display name of the combined
	// audience.
	// .
	DisplayName string `json:"displayName,omitempty"`

	// Name: Output only. The resource name of the combined audience.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CombinedAudienceId")
	// 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. "CombinedAudienceId") 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 *CombinedAudience) MarshalJSON() ([]byte, error) {
	type NoMethod CombinedAudience
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CombinedAudienceGroup: Details of combined audience group.
// All combined audience targeting settings are logically ‘OR’ of
// each other.
type CombinedAudienceGroup struct {
	// Settings: Required. All combined audience targeting settings in
	// combined audience group.
	// Repeated settings with same id will be ignored.
	// The number of combined audience settings should be no more than five,
	// error
	// will be thrown otherwise.
	Settings []*CombinedAudienceTargetingSetting `json:"settings,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Settings") 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. "Settings") 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 *CombinedAudienceGroup) MarshalJSON() ([]byte, error) {
	type NoMethod CombinedAudienceGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CombinedAudienceTargetingSetting: Details of combined audience
// targeting setting.
type CombinedAudienceTargetingSetting struct {
	// CombinedAudienceId: Required. Combined audience id of combined
	// audience targeting setting.
	// This id is combined_audience_id.
	CombinedAudienceId int64 `json:"combinedAudienceId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CombinedAudienceId")
	// 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. "CombinedAudienceId") 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 *CombinedAudienceTargetingSetting) MarshalJSON() ([]byte, error) {
	type NoMethod CombinedAudienceTargetingSetting
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ContentInstreamPositionAssignedTargetingOptionDetails: Assigned
// content instream position targeting option details. This will
// be
// populated in the
// content_instream_position_details
// field when
// targeting_type is
// `TARGETING_TYPE_CONTENT_INSTREAM_POSITION`.
type ContentInstreamPositionAssignedTargetingOptionDetails struct {
	// ContentInstreamPosition: Output only. The content instream position
	// for video or audio ads.
	//
	// Possible values:
	//   "CONTENT_INSTREAM_POSITION_UNSPECIFIED" - Content instream position
	// is not specified in this version. This enum is a
	// place holder for a default value and does not represent a real in
	// stream ad
	// position.
	//   "CONTENT_INSTREAM_POSITION_PRE_ROLL" - Ads that play before
	// streaming content.
	//   "CONTENT_INSTREAM_POSITION_MID_ROLL" - Ads that play between the
	// beginning and end of streaming content.
	//   "CONTENT_INSTREAM_POSITION_POST_ROLL" - Ads that play at the end of
	// streaming content.
	ContentInstreamPosition string `json:"contentInstreamPosition,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id field
	// when
	// targeting_type is
	// `TARGETING_TYPE_CONTENT_INSTREAM_POSITION`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ContentInstreamPosition") 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. "ContentInstreamPosition")
	// 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 *ContentInstreamPositionAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ContentInstreamPositionAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ContentInstreamPositionTargetingOptionDetails: Represents a
// targetable content instream position, which could be used by
// video and audio ads. This will be populated in
// the
// content_instream_position_details
// field when targeting_type
// is
// `TARGETING_TYPE_CONTENT_INSTREAM_POSITION`.
type ContentInstreamPositionTargetingOptionDetails struct {
	// ContentInstreamPosition: Output only. The content instream position.
	//
	// Possible values:
	//   "CONTENT_INSTREAM_POSITION_UNSPECIFIED" - Content instream position
	// is not specified in this version. This enum is a
	// place holder for a default value and does not represent a real in
	// stream ad
	// position.
	//   "CONTENT_INSTREAM_POSITION_PRE_ROLL" - Ads that play before
	// streaming content.
	//   "CONTENT_INSTREAM_POSITION_MID_ROLL" - Ads that play between the
	// beginning and end of streaming content.
	//   "CONTENT_INSTREAM_POSITION_POST_ROLL" - Ads that play at the end of
	// streaming content.
	ContentInstreamPosition string `json:"contentInstreamPosition,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ContentInstreamPosition") 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. "ContentInstreamPosition")
	// 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 *ContentInstreamPositionTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ContentInstreamPositionTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ContentOutstreamPositionAssignedTargetingOptionDetails: Assigned
// content outstream position targeting option details. This will
// be
// populated in the
// content_outstream_position_details
// field when
// targeting_type is
// `TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION`.
type ContentOutstreamPositionAssignedTargetingOptionDetails struct {
	// ContentOutstreamPosition: Output only. The content outstream
	// position.
	//
	// Possible values:
	//   "CONTENT_OUTSTREAM_POSITION_UNSPECIFIED" - Content outstream
	// position is not specified in this version. This enum is a
	// place holder for a default value and does not represent a real
	// content
	// outstream position.
	//   "CONTENT_OUTSTREAM_POSITION_UNKNOWN" - The ad position is unknown
	// in the content outstream.
	//   "CONTENT_OUTSTREAM_POSITION_IN_ARTICLE" - Ads that appear between
	// the paragraphs of your pages.
	//   "CONTENT_OUTSTREAM_POSITION_IN_BANNER" - Ads that display on the
	// top and the sides of a page.
	//   "CONTENT_OUTSTREAM_POSITION_IN_FEED" - Ads that appear in a
	// scrollable stream of content. A feed is typically
	// editorial (e.g. a list of articles or news) or listings (e.g. a list
	// of
	// products or services).
	//   "CONTENT_OUTSTREAM_POSITION_INTERSTITIAL" - Ads shown before or
	// between content loads.
	ContentOutstreamPosition string `json:"contentOutstreamPosition,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id field
	// when
	// targeting_type is
	// `TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ContentOutstreamPosition") 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. "ContentOutstreamPosition")
	// 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 *ContentOutstreamPositionAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ContentOutstreamPositionAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ContentOutstreamPositionTargetingOptionDetails: Represents a
// targetable content outstream position, which could be used by
// display and video ads. This will be populated in
// the
// content_outstream_position_details
// field when targeting_type
// is
// `TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION`.
type ContentOutstreamPositionTargetingOptionDetails struct {
	// ContentOutstreamPosition: Output only. The content outstream
	// position.
	//
	// Possible values:
	//   "CONTENT_OUTSTREAM_POSITION_UNSPECIFIED" - Content outstream
	// position is not specified in this version. This enum is a
	// place holder for a default value and does not represent a real
	// content
	// outstream position.
	//   "CONTENT_OUTSTREAM_POSITION_UNKNOWN" - The ad position is unknown
	// in the content outstream.
	//   "CONTENT_OUTSTREAM_POSITION_IN_ARTICLE" - Ads that appear between
	// the paragraphs of your pages.
	//   "CONTENT_OUTSTREAM_POSITION_IN_BANNER" - Ads that display on the
	// top and the sides of a page.
	//   "CONTENT_OUTSTREAM_POSITION_IN_FEED" - Ads that appear in a
	// scrollable stream of content. A feed is typically
	// editorial (e.g. a list of articles or news) or listings (e.g. a list
	// of
	// products or services).
	//   "CONTENT_OUTSTREAM_POSITION_INTERSTITIAL" - Ads shown before or
	// between content loads.
	ContentOutstreamPosition string `json:"contentOutstreamPosition,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ContentOutstreamPosition") 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. "ContentOutstreamPosition")
	// 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 *ContentOutstreamPositionTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ContentOutstreamPositionTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ConversionCountingConfig: Settings that control how conversions are
// counted.
//
// All post-click conversions will be counted. A percentage value can be
// set
// for post-view conversions counting.
type ConversionCountingConfig struct {
	// FloodlightActivityConfigs: The Floodlight activity configs used to
	// track conversions.
	//
	// The number of conversions counted is the sum of all of the
	// conversions
	// counted by all of the Floodlight activity IDs specified in this
	// field.
	FloodlightActivityConfigs []*TrackingFloodlightActivityConfig `json:"floodlightActivityConfigs,omitempty"`

	// PostViewCountPercentageMillis: The percentage of post-view
	// conversions to count, in millis (1/1000 of a
	// percent). Must be between 0 and 100000 inclusive.
	//
	// For example, to track 50% of the post-click conversions, set a value
	// of
	// 50000.
	PostViewCountPercentageMillis int64 `json:"postViewCountPercentageMillis,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "FloodlightActivityConfigs") 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.
	// "FloodlightActivityConfigs") 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 *ConversionCountingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod ConversionCountingConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CounterEvent: Counter event of the creative.
type CounterEvent struct {
	// Name: Required. The name of the counter event.
	Name string `json:"name,omitempty"`

	// ReportingName: Required. The name used to identify this counter event
	// in reports.
	ReportingName string `json:"reportingName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *CounterEvent) MarshalJSON() ([]byte, error) {
	type NoMethod CounterEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateAssetRequest: A request message for CreateAsset.
type CreateAssetRequest struct {
	// Filename: Required. The filename of the asset, including the file
	// extension.
	//
	// The filename must be UTF-8 encoded with a maximum size of 240 bytes.
	Filename string `json:"filename,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Filename") 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. "Filename") 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 *CreateAssetRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateAssetRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateAssetResponse: A response message for CreateAsset.
type CreateAssetResponse struct {
	// Asset: The uploaded asset, if successful.
	Asset *Asset `json:"asset,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Asset") 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. "Asset") 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 *CreateAssetResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateAssetResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateAssignedTargetingOptionsRequest: A request listing which
// assigned targeting options of a given targeting type
// should be created and added.
type CreateAssignedTargetingOptionsRequest struct {
	// AssignedTargetingOptions: Required. The assigned targeting options to
	// create and add.
	AssignedTargetingOptions []*AssignedTargetingOption `json:"assignedTargetingOptions,omitempty"`

	// TargetingType: Required. Identifies the type of this assigned
	// targeting option.
	//
	// Possible values:
	//   "TARGETING_TYPE_UNSPECIFIED" - Default value when type is not
	// specified or is unknown in this version.
	//   "TARGETING_TYPE_CHANNEL" - Target a channel (a custom group of
	// related websites or apps).
	//   "TARGETING_TYPE_APP_CATEGORY" - Target an app category (for
	// example, education or puzzle games).
	//   "TARGETING_TYPE_APP" - Target a specific app (for example, Angry
	// Birds).
	//   "TARGETING_TYPE_URL" - Target a specific url (for example,
	// quora.com).
	//   "TARGETING_TYPE_DAY_AND_TIME" - Target ads during a chosen time
	// period on a specific day.
	//   "TARGETING_TYPE_AGE_RANGE" - Target ads to a specific age range
	// (for example, 18-24).
	//   "TARGETING_TYPE_REGIONAL_LOCATION_LIST" - Target ads to the
	// specified regions on a regional location list.
	//   "TARGETING_TYPE_PROXIMITY_LOCATION_LIST" - Target ads to the
	// specified points of interest on a proximity location
	// list.
	//   "TARGETING_TYPE_GENDER" - Target ads to a specific gender (for
	// example, female or male).
	//   "TARGETING_TYPE_VIDEO_PLAYER_SIZE" - Target a specific video player
	// size for video ads.
	//   "TARGETING_TYPE_USER_REWARDED_CONTENT" - Target user rewarded
	// content for video ads.
	//   "TARGETING_TYPE_PARENTAL_STATUS" - Target ads to a specific
	// parental status (for example, parent or not a
	// parent).
	//   "TARGETING_TYPE_CONTENT_INSTREAM_POSITION" - Target video or audio
	// ads in a specific content instream position (for
	// example, pre-roll, mid-roll, or post-roll).
	//   "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION" - Target ads in a
	// specific content outstream position.
	//   "TARGETING_TYPE_DEVICE_TYPE" - Target ads to a specific device type
	// (for example, tablet or connected TV).
	//   "TARGETING_TYPE_AUDIENCE_GROUP" - Target ads to an audience or
	// groups of audiences.
	// Singleton field, at most one can exist on a single Lineitem at a
	// time.
	//   "TARGETING_TYPE_BROWSER" - Target ads to specific web browsers (for
	// example, Chrome).
	//   "TARGETING_TYPE_HOUSEHOLD_INCOME" - Target ads to a specific
	// household income range (for example, top 10%).
	//   "TARGETING_TYPE_ON_SCREEN_POSITION" - Target ads in a specific on
	// screen position.
	//   "TARGETING_TYPE_THIRD_PARTY_VERIFIER" - Filter web sites through
	// third party verification (for example, IAS or
	// DoubleVerify).
	//   "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION" - Filter web sites
	// by specific digital content label ratings (for example,
	// DL-MA: suitable only for mature audiences).
	//   "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION" - Filter website
	// content by sensitive categories (for example, adult).
	//   "TARGETING_TYPE_ENVIRONMENT" - Target ads to a specific environment
	// (for example, web or app).
	//   "TARGETING_TYPE_CARRIER_AND_ISP" - Target ads to a specific network
	// carrier or internet service provider
	// (ISP) (for example, Comcast or Orange).
	//   "TARGETING_TYPE_OPERATING_SYSTEM" - Target ads to a specific
	// operating system (for example, macOS).
	//   "TARGETING_TYPE_DEVICE_MAKE_MODEL" - Target ads to a specific
	// device make or model (for example, Roku or
	// Samsung).
	//   "TARGETING_TYPE_KEYWORD" - Target ads to a specific keyword (for
	// example, dog or retriever).
	//   "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST" - Target ads to a specific
	// negative keyword list.
	//   "TARGETING_TYPE_VIEWABILITY" - Target ads to a specific viewability
	// (for example, 80% viewable).
	//   "TARGETING_TYPE_CATEGORY" - Target ads to a specific content
	// category (for example, arts &
	// entertainment).
	//   "TARGETING_TYPE_INVENTORY_SOURCE" - Purchase impressions from
	// specific deals and auction packages.
	//   "TARGETING_TYPE_LANGUAGE" - Target ads to a specific language (for
	// example, English or Japanese).
	//   "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS" - Target ads to ads.txt
	// authorized sellers.
	//   "TARGETING_TYPE_GEO_REGION" - Target ads to a specific regional
	// location (for example, a city or state).
	//   "TARGETING_TYPE_INVENTORY_SOURCE_GROUP" - Purchase impressions from
	// a group of deals and auction packages.
	//   "TARGETING_TYPE_EXCHANGE" - Purchase impressions from specific
	// exchanges.
	//   "TARGETING_TYPE_SUB_EXCHANGE" - Purchase impressions from specific
	// sub-exchanges.
	TargetingType string `json:"targetingType,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AssignedTargetingOptions") 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. "AssignedTargetingOptions")
	// 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 *CreateAssignedTargetingOptionsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateAssignedTargetingOptionsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSdfDownloadTaskRequest: Request message for
// [SdfDownloadTaskService.CreateSdfDownloadTask].
type CreateSdfDownloadTaskRequest struct {
	// AdvertiserId: The ID of the advertiser to download SDF for.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// IdFilter: Filters on entities by their entity IDs.
	IdFilter *IdFilter `json:"idFilter,omitempty"`

	// InventorySourceFilter: Filters on Inventory Sources by their IDs.
	InventorySourceFilter *InventorySourceFilter `json:"inventorySourceFilter,omitempty"`

	// ParentEntityFilter: Filters on selected file types. The entities in
	// each file are filtered
	//  by a chosen set of filter entities. The filter entities must be the
	// same
	//  type as, or a parent type of, the selected file types.
	ParentEntityFilter *ParentEntityFilter `json:"parentEntityFilter,omitempty"`

	// PartnerId: The ID of the partner to download SDF for.
	PartnerId int64 `json:"partnerId,omitempty,string"`

	// Version: Required. The SDF version of the downloaded file. If set
	// to
	// `SDF_VERSION_UNSPECIFIED`, this will default to the version specified
	// by
	// the advertiser or partner identified by `root_id`. An advertiser
	// inherits
	// its SDF version from its partner unless configured otherwise.
	//
	// Possible values:
	//   "SDF_VERSION_UNSPECIFIED" - SDF version value is not specified or
	// is unknown in this version.
	//   "SDF_VERSION_3_1" - SDF version 3.1
	//   "SDF_VERSION_4" - SDF version 4
	//   "SDF_VERSION_4_1" - SDF version 4.1
	//   "SDF_VERSION_4_2" - SDF version 4.2
	//   "SDF_VERSION_5" - SDF version 5.
	//   "SDF_VERSION_5_1" - SDF version 5.1
	Version string `json:"version,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 *CreateSdfDownloadTaskRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSdfDownloadTaskRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Creative: A single Creative.
type Creative struct {
	// AdditionalDimensions: Additional dimensions.
	// Applicable when creative_type is one of:
	//
	// * `CREATIVE_TYPE_STANDARD`
	// * `CREATIVE_TYPE_EXPANDABLE`
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_TEMPLATED_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_LIGHTBOX`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_PUBLISHER_HOSTED`
	//
	// If this field is specified, width_pixels and
	// height_pixels are both required and must be
	// greater than or equal to 0.
	AdditionalDimensions []*Dimensions `json:"additionalDimensions,omitempty"`

	// AdvertiserId: Output only. The unique ID of the advertiser the
	// creative belongs to.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AppendedTag: Third-party HTML tracking tag to be appended to the
	// creative tag.
	AppendedTag string `json:"appendedTag,omitempty"`

	// Assets: Required. Assets associated to this creative.
	// Assets can be associated to the creative in one of following
	// roles:
	//
	// * `ASSET_ROLE_UNSPECIFIED`
	// * `ASSET_ROLE_MAIN`
	// * `ASSET_ROLE_BACKUP`
	// * `ASSET_ROLE_POLITE_LOAD`
	Assets []*AssetAssociation `json:"assets,omitempty"`

	// CmPlacementId: Output only. The unique ID of the Campaign Manager
	// placement associated with the
	// creative.
	// This field is only applicable for creatives that are synced from
	// Campaign
	// Manager.
	CmPlacementId int64 `json:"cmPlacementId,omitempty,string"`

	// CmTrackingAd: The Campaign Manager tracking ad associated with the
	// creative.
	//
	// Optional for the following creative_type when
	// created by an advertiser that uses both Campaign Manager and
	// third-party ad
	// serving:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	//
	// Output only for other cases.
	CmTrackingAd *CmTrackingAd `json:"cmTrackingAd,omitempty"`

	// CompanionCreativeIds: The IDs of companion creatives for a video
	// creative.
	//
	// You can assign existing display creatives (with image or HTML5
	// assets)
	// to serve surrounding the publisher's video player. Companions
	// display
	// around the video player while the video is playing and remain after
	// the
	// video has completed.
	//
	// Creatives contain additional dimensions
	// can not be companion creatives.
	//
	// This field is only supported for following
	// creative_type:
	//
	// * `CREATIVE_TYPE_AUDIO`
	// * `CREATIVE_TYPE_VIDEO`
	CompanionCreativeIds googleapi.Int64s `json:"companionCreativeIds,omitempty"`

	// CounterEvents: Counter events for a rich media creative.
	// Counters track the number of times that a user interacts with any
	// part of a
	// rich media creative in a specified way (mouse-overs, mouse-outs,
	// clicks,
	// taps, data loading, keyboard entries, etc.).
	// Any event that can be captured in the creative can be recorded as
	// a
	// counter.
	// Leave it empty or unset for creatives containing image assets only.
	CounterEvents []*CounterEvent `json:"counterEvents,omitempty"`

	// CreateTime: Output only. The timestamp when the creative was created.
	// Assigned by
	// the system.
	CreateTime string `json:"createTime,omitempty"`

	// CreativeAttributes: Output only. A list of attributes of the creative
	// that is generated by the system.
	//
	// Possible values:
	//   "CREATIVE_ATTRIBUTE_UNSPECIFIED" - The creative attribute is not
	// specified or is unknown in this version.
	//   "CREATIVE_ATTRIBUTE_VAST" - The creative is a VAST creative.
	//   "CREATIVE_ATTRIBUTE_VPAID_LINEAR" - The creative is a linear VPAID
	// creative.
	//   "CREATIVE_ATTRIBUTE_VPAID_NON_LINEAR" - The creative is a
	// non-linear VPAID creative.
	CreativeAttributes []string `json:"creativeAttributes,omitempty"`

	// CreativeId: Output only. The unique ID of the creative. Assigned by
	// the system.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// CreativeType: Required. Immutable. The type of the creative.
	//
	// Possible values:
	//   "CREATIVE_TYPE_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "CREATIVE_TYPE_STANDARD" - Standard display creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is one of the following:
	//
	// * `HOSTING_SOURCE_HOSTED`
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//   "CREATIVE_TYPE_EXPANDABLE" - Expandable creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_THIRD_PARTY`
	//   "CREATIVE_TYPE_VIDEO" - Video creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is one of the following:
	//
	// * `HOSTING_SOURCE_HOSTED`
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//   "CREATIVE_TYPE_NATIVE" - Native creative rendered by publishers
	// with assets from advertiser.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_TEMPLATED_APP_INSTALL" - Templated app install
	// mobile creative (banner).
	//
	// Create and update methods are **not** supported for this creative
	// type.
	//   "CREATIVE_TYPE_NATIVE_SITE_SQUARE" - Square native
	// creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_TEMPLATED_APP_INSTALL_INTERSTITIAL" - Interstitial
	// creative including both display and video.
	//
	// Create and update methods are **not** supported for this creative
	// type.
	//   "CREATIVE_TYPE_LIGHTBOX" - Responsive and expandable Lightbox
	// creative.
	//
	// Create and update methods are **not** supported for this creative
	// type.
	//   "CREATIVE_TYPE_NATIVE_APP_INSTALL" - Native app install
	// creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE" - Square native app
	// install creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_AUDIO" - Audio creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_PUBLISHER_HOSTED" - Publisher hosted
	// creative.
	//
	// Create and update methods are **not** supported for this creative
	// type.
	//   "CREATIVE_TYPE_NATIVE_VIDEO" - Native video creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_TEMPLATED_APP_INSTALL_VIDEO" - Templated app install
	// mobile video creative.
	//
	// Create and update methods are **not** supported for this creative
	// type.
	CreativeType string `json:"creativeType,omitempty"`

	// Dimensions: Required. Primary dimensions of the creative.
	// Applicable to all creative types. The value of
	// width_pixels and
	// height_pixels defaults to `0`
	// when creative_type is one of:
	//
	// * `CREATIVE_TYPE_VIDEO`
	// * `CREATIVE_TYPE_TEMPLATED_APP_INSTALL_INTERSTITIAL`
	// * `CREATIVE_TYPE_AUDIO`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	// * `CREATIVE_TYPE_TEMPLATED_APP_INSTALL_VIDEO`
	Dimensions *Dimensions `json:"dimensions,omitempty"`

	// DisplayName: Required. The display name of the creative.
	//
	// Must be UTF-8 encoded with a maximum size of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// Dynamic: Output only. Indicates whether the creative is dynamic.
	Dynamic bool `json:"dynamic,omitempty"`

	// EntityStatus: Required. Controls whether or not the creative can
	// serve.
	//
	// Accepted values are:
	//
	// * `ENTITY_STATUS_ACTIVE`
	// * `ENTITY_STATUS_ARCHIVED`
	// * `ENTITY_STATUS_PAUSED`
	//
	// Possible values:
	//   "ENTITY_STATUS_UNSPECIFIED" - Default value when status is not
	// specified or is unknown in this version.
	//   "ENTITY_STATUS_ACTIVE" - The entity is enabled to bid and spend
	// budget.
	//   "ENTITY_STATUS_ARCHIVED" - The entity is archived. Bidding and
	// budget spending are disabled. An
	// entity can be deleted after archived. Deleted entities cannot be
	// retrieved.
	//   "ENTITY_STATUS_DRAFT" - The entity is under draft. Bidding and
	// budget spending are disabled.
	//   "ENTITY_STATUS_PAUSED" - Bidding and budget spending are paused for
	// the entity.
	//   "ENTITY_STATUS_SCHEDULED_FOR_DELETION" - The entity is scheduled
	// for deletion.
	EntityStatus string `json:"entityStatus,omitempty"`

	// ExitEvents: Required. Exit events for this creative.
	// An exit (also known as a click tag) is any area in your creative
	// that
	// someone can click or tap to open an advertiser's landing page.
	// Every creative must include at least one exit.
	// You can add an exit to your creative in any of the following ways:
	//
	// * Use Google Web Designer's tap area.
	// * Define a JavaScript variable called "clickTag".
	// * Use the Enabler (Enabler.exit()) to track exits in rich media
	// formats.
	ExitEvents []*ExitEvent `json:"exitEvents,omitempty"`

	// ExpandOnHover: Optional. Indicates the creative will automatically
	// expand on hover.
	//
	// Optional and only valid for third-party expandable
	// creatives.
	// Third-party expandable creatives are creatives with following
	// hosting
	// source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_EXPANDABLE`
	ExpandOnHover bool `json:"expandOnHover,omitempty"`

	// ExpandingDirection: Optional. Specifies the expanding direction of
	// the creative.
	//
	// Required and only valid for third-party expandable
	// creatives.
	//
	// Third-party expandable creatives are creatives with following
	// hosting
	// source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_EXPANDABLE`
	//
	// Possible values:
	//   "EXPANDING_DIRECTION_UNSPECIFIED" - The expanding direction is not
	// specified.
	//   "EXPANDING_DIRECTION_NONE" - Does not expand in any direction.
	//   "EXPANDING_DIRECTION_UP" - Expands up.
	//   "EXPANDING_DIRECTION_DOWN" - Expands down.
	//   "EXPANDING_DIRECTION_LEFT" - Expands left.
	//   "EXPANDING_DIRECTION_RIGHT" - Expands right.
	//   "EXPANDING_DIRECTION_UP_AND_LEFT" - Expands up and to the left
	// side.
	//   "EXPANDING_DIRECTION_UP_AND_RIGHT" - Expands up and to the right
	// side.
	//   "EXPANDING_DIRECTION_DOWN_AND_LEFT" - Expands down and to the left
	// side.
	//   "EXPANDING_DIRECTION_DOWN_AND_RIGHT" - Expands down and to the
	// right side.
	//   "EXPANDING_DIRECTION_UP_OR_DOWN" - Expands either up or down.
	//   "EXPANDING_DIRECTION_LEFT_OR_RIGHT" - Expands to either the left or
	// the right side.
	//   "EXPANDING_DIRECTION_ANY_DIAGONAL" - Can expand in any diagonal
	// direction.
	ExpandingDirection string `json:"expandingDirection,omitempty"`

	// HostingSource: Required. Indicates where the creative is hosted.
	//
	// Possible values:
	//   "HOSTING_SOURCE_UNSPECIFIED" - Hosting source is not specified or
	// is unknown in this version.
	//   "HOSTING_SOURCE_CM" - A creative synced from Campaign
	// Manager.
	//
	// Create and update methods are **not** supported for this hosting
	// type.
	//   "HOSTING_SOURCE_THIRD_PARTY" - A creative hosted by a third-party
	// ad server (3PAS).
	//
	// Create and update methods are supported for this hosting type if
	// the
	// creative_type is one of the following:
	//
	// * `CREATIVE_TYPE_EXPANDABLE`
	// * `CREATIVE_TYPE_STANDARD`
	// * `CREATIVE_TYPE_VIDEO`
	//   "HOSTING_SOURCE_HOSTED" - A creative created in DV360 and hosted by
	// Campaign Manager.
	//
	// Create and update methods are supported for this hosting type if
	// the
	// creative_type is one of the following:
	//
	// * `CREATIVE_TYPE_AUDIO`
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	// * `CREATIVE_TYPE_STANDARD`
	// * `CREATIVE_TYPE_VIDEO`
	//   "HOSTING_SOURCE_RICH_MEDIA" - A rich media creative created in
	// Studio and hosted by Campaign Manager.
	//
	// Create and update methods are **not** supported for this hosting
	// type.
	HostingSource string `json:"hostingSource,omitempty"`

	// Html5Video: Output only. Indicates the third-party VAST tag creative
	// requires HTML5 Video support.
	//
	// Output only and only valid for third-party VAST tag
	// creatives.
	//
	// Third-party VAST tag creatives are creatives with
	// following
	// hosting_source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	Html5Video bool `json:"html5Video,omitempty"`

	// IasCampaignMonitoring: Indicates whether Integral Ad Science (IAS)
	// campaign monitoring is enabled.
	// To enable this for the creative, make sure
	// the
	// Advertiser.creative_config.ias_client_id
	// has been set to your IAS client ID.
	IasCampaignMonitoring bool `json:"iasCampaignMonitoring,omitempty"`

	// IntegrationCode: ID information used to link this creative to an
	// external system.
	// Must be UTF-8 encoded with a length of no more than 10,000
	// characters.
	IntegrationCode string `json:"integrationCode,omitempty"`

	// JsTrackerUrl: JavaScript measurement URL from supported third-party
	// verification
	// providers (ComScore, DoubleVerify, IAS, Moat). HTML script tags are
	// not
	// supported.
	//
	// This field is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	JsTrackerUrl string `json:"jsTrackerUrl,omitempty"`

	// LineItemIds: Output only. The IDs of the line items this creative
	// associated with.
	//
	// To associate a creative to a line item, use
	// LineItem.creative_ids instead.
	LineItemIds googleapi.Int64s `json:"lineItemIds,omitempty"`

	// MediaDuration: Output only. Media duration of the
	// creative.
	// Applicable when creative_type
	// is one of:
	//
	// * `CREATIVE_TYPE_VIDEO`
	// * `CREATIVE_TYPE_AUDIO`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	// * `CREATIVE_TYPE_PUBLISHER_HOSTED`
	MediaDuration string `json:"mediaDuration,omitempty"`

	// Name: Output only. The resource name of the creative.
	Name string `json:"name,omitempty"`

	// Notes: User notes for this creative.
	// Must be UTF-8 encoded with a length of no more than 20,000
	// characters.
	Notes string `json:"notes,omitempty"`

	// ObaIcon: Specifies the OBA icon for a video creative.
	//
	// This field is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	ObaIcon *ObaIcon `json:"obaIcon,omitempty"`

	// ProgressOffset: Amount of time to play the video before counting a
	// view.
	//
	// This field is required when skippable is true.
	//
	// This field is only supported for the following
	// creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	ProgressOffset *AudioVideoOffset `json:"progressOffset,omitempty"`

	// RequireHtml5: Optional. Indicates that the creative relies on HTML5
	// to render properly.
	//
	// Optional and only valid for third-party tag creatives.
	// Third-party tag creatives are creatives with
	// following
	// hosting_source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_STANDARD`
	// * `CREATIVE_TYPE_EXPANDABLE`
	RequireHtml5 bool `json:"requireHtml5,omitempty"`

	// RequireMraid: Optional. Indicates that the creative requires MRAID
	// (Mobile Rich Media Ad Interface
	// Definitions system).
	//
	// Set this if the creative relies on mobile gestures for interactivity,
	// such
	// as swiping or tapping.
	//
	// Optional and only valid for third-party tag creatives.
	//
	// Third-party tag creatives are creatives with
	// following
	// hosting_source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_STANDARD`
	// * `CREATIVE_TYPE_EXPANDABLE`
	RequireMraid bool `json:"requireMraid,omitempty"`

	// RequirePingForAttribution: Optional. Indicates that the creative will
	// wait for a return ping for attribution.
	//
	// Only valid when using a Campaign Manager tracking ad with a
	// third-party ad
	// server parameter and the ${DC_DBM_TOKEN} macro.
	//
	// Optional and only valid for third-party tag creatives or third-party
	// VAST
	// tag creatives.
	//
	// Third-party tag creatives are creatives with
	// following
	// hosting_source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_STANDARD`
	// * `CREATIVE_TYPE_EXPANDABLE`
	//
	// Third-party VAST tag creatives are creatives with
	// following
	// hosting_source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	RequirePingForAttribution bool `json:"requirePingForAttribution,omitempty"`

	// ReviewStatus: Output only. The current status of the creative review
	// process.
	ReviewStatus *ReviewStatusInfo `json:"reviewStatus,omitempty"`

	// SkipOffset: Amount of time to play the video before the skip button
	// appears.
	//
	// This field is required when skippable is true.
	//
	// This field is only supported for the following
	// creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	SkipOffset *AudioVideoOffset `json:"skipOffset,omitempty"`

	// Skippable: Whether the user can choose to skip a video
	// creative.
	//
	// This field is only supported for the following
	// creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	Skippable bool `json:"skippable,omitempty"`

	// ThirdPartyTag: Optional. The original third-party tag used for the
	// creative.
	//
	// Required and only valid for third-party tag creatives.
	//
	// Third-party tag creatives are creatives with
	// following
	// hosting_source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_STANDARD`
	// * `CREATIVE_TYPE_EXPANDABLE`
	ThirdPartyTag string `json:"thirdPartyTag,omitempty"`

	// ThirdPartyUrls: Tracking URLs from third parties to track
	// interactions with a video
	// creative.
	//
	// This field is only supported for the following
	// creative_type:
	//
	// * `CREATIVE_TYPE_AUDIO`
	// * `CREATIVE_TYPE_VIDEO`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	ThirdPartyUrls []*ThirdPartyUrl `json:"thirdPartyUrls,omitempty"`

	// TimerEvents: Timer custom events for a rich media creative.
	// Timers track the time during which a user views and interacts with
	// a
	// specified part of a rich media creative.
	// A creative can have multiple timer events, each timed
	// independently.
	// Leave it empty or unset for creatives containing image assets only.
	TimerEvents []*TimerEvent `json:"timerEvents,omitempty"`

	// TrackerUrls: Tracking URLs for analytics providers or third-party ad
	// technology vendors.
	//
	// The URLs must start with https (except on inventory that doesn't
	// require
	// SSL compliance).
	// If using macros in your URL, use only macros supported by Display &
	// Video
	// 360.
	//
	// Standard URLs only, no IMG or SCRIPT tags.
	//
	// This field is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_NATIVE`
	// * `CREATIVE_TYPE_NATIVE_SITE_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL`
	// * `CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	TrackerUrls []string `json:"trackerUrls,omitempty"`

	// Transcodes: Output only. Audio/Video transcodes.
	//
	// Display & Video 360 transcodes the main asset into a number of
	// alternative
	// versions that use different file formats or have different
	// properties
	// (resolution, audio bit rate, and video bit rate), each designed
	// for
	// specific video players or bandwidths.
	//
	// These transcodes give a publisher's system more options to choose
	// from for
	// each impression on your video and ensures that the appropriate file
	// serves
	// based on the viewer’s connection and screen size.
	//
	// This field is only supported in following
	// creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	// * `CREATIVE_TYPE_NATIVE_VIDEO`
	// * `CREATIVE_TYPE_AUDIO`
	Transcodes []*Transcode `json:"transcodes,omitempty"`

	// UniversalAdId: Optional. An optional creative identifier provided by
	// a registry that is unique
	// across all platforms.
	//
	// Universal Ad ID is part of the VAST 4.0 standard. It can be modified
	// after
	// the creative is created.
	//
	// This field is only supported for the following
	// creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	UniversalAdId *UniversalAdId `json:"universalAdId,omitempty"`

	// UpdateTime: Output only. The timestamp when the creative was last
	// updated. Assigned by
	// the system.
	UpdateTime string `json:"updateTime,omitempty"`

	// VastTagUrl: Optional. The URL of the VAST tag for a third-party VAST
	// tag creative.
	//
	// Required and only valid for third-party VAST tag
	// creatives.
	//
	// Third-party VAST tag creatives are creatives with
	// following
	// hosting_source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	VastTagUrl string `json:"vastTagUrl,omitempty"`

	// Vpaid: Output only. Indicates the third-party VAST tag creative
	// requires VPAID (Digital Video
	// Player-Ad Interface).
	//
	// Output only and only valid for third-party VAST tag
	// creatives.
	//
	// Third-party VAST tag creatives are creatives with
	// following
	// hosting_source:
	//
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//
	// combined with following creative_type:
	//
	// * `CREATIVE_TYPE_VIDEO`
	Vpaid bool `json:"vpaid,omitempty"`

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

	// ForceSendFields is a list of field names (e.g.
	// "AdditionalDimensions") 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. "AdditionalDimensions") 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)
}

// CreativeConfig: Creative requirements configuration for the inventory
// source.
type CreativeConfig struct {
	// CreativeType: The type of creative that can be assigned to the
	// inventory source.
	//
	// Possible values:
	//   "CREATIVE_TYPE_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "CREATIVE_TYPE_STANDARD" - Standard display creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is one of the following:
	//
	// * `HOSTING_SOURCE_HOSTED`
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//   "CREATIVE_TYPE_EXPANDABLE" - Expandable creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_THIRD_PARTY`
	//   "CREATIVE_TYPE_VIDEO" - Video creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is one of the following:
	//
	// * `HOSTING_SOURCE_HOSTED`
	// * `HOSTING_SOURCE_THIRD_PARTY`
	//   "CREATIVE_TYPE_NATIVE" - Native creative rendered by publishers
	// with assets from advertiser.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_TEMPLATED_APP_INSTALL" - Templated app install
	// mobile creative (banner).
	//
	// Create and update methods are **not** supported for this creative
	// type.
	//   "CREATIVE_TYPE_NATIVE_SITE_SQUARE" - Square native
	// creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_TEMPLATED_APP_INSTALL_INTERSTITIAL" - Interstitial
	// creative including both display and video.
	//
	// Create and update methods are **not** supported for this creative
	// type.
	//   "CREATIVE_TYPE_LIGHTBOX" - Responsive and expandable Lightbox
	// creative.
	//
	// Create and update methods are **not** supported for this creative
	// type.
	//   "CREATIVE_TYPE_NATIVE_APP_INSTALL" - Native app install
	// creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_NATIVE_APP_INSTALL_SQUARE" - Square native app
	// install creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_AUDIO" - Audio creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_PUBLISHER_HOSTED" - Publisher hosted
	// creative.
	//
	// Create and update methods are **not** supported for this creative
	// type.
	//   "CREATIVE_TYPE_NATIVE_VIDEO" - Native video creative.
	//
	// Create and update methods are supported for this creative type if
	// the
	// hosting_source is `HOSTING_SOURCE_HOSTED`
	//   "CREATIVE_TYPE_TEMPLATED_APP_INSTALL_VIDEO" - Templated app install
	// mobile video creative.
	//
	// Create and update methods are **not** supported for this creative
	// type.
	CreativeType string `json:"creativeType,omitempty"`

	// DisplayCreativeConfig: The configuration for display
	// creatives.
	// Applicable when creative_type is
	// `CREATIVE_TYPE_STANDARD`.
	DisplayCreativeConfig *InventorySourceDisplayCreativeConfig `json:"displayCreativeConfig,omitempty"`

	// VideoCreativeConfig: The configuration for video
	// creatives.
	// Applicable when creative_type is
	// `CREATIVE_TYPE_VIDEO`.
	VideoCreativeConfig *InventorySourceVideoCreativeConfig `json:"videoCreativeConfig,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreativeType") 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. "CreativeType") 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 *CreativeConfig) MarshalJSON() ([]byte, error) {
	type NoMethod CreativeConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CustomList: Describes a custom list entity, such as a custom affinity
// or custom intent
// audience list.
type CustomList struct {
	// CustomListId: Output only. The unique ID of the custom list. Assigned
	// by the system.
	CustomListId int64 `json:"customListId,omitempty,string"`

	// DisplayName: Output only. The display name of the custom list.
	// .
	DisplayName string `json:"displayName,omitempty"`

	// Name: Output only. The resource name of the custom list.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CustomListId") 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. "CustomListId") 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 *CustomList) MarshalJSON() ([]byte, error) {
	type NoMethod CustomList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CustomListGroup: Details of custom list group.
// All custom list targeting settings are logically ‘OR’ of each
// other.
type CustomListGroup struct {
	// Settings: Required. All custom list targeting settings in custom list
	// group.
	// Repeated settings with same id will be ignored.
	Settings []*CustomListTargetingSetting `json:"settings,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Settings") 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. "Settings") 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 *CustomListGroup) MarshalJSON() ([]byte, error) {
	type NoMethod CustomListGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CustomListTargetingSetting: Details of custom list targeting setting.
type CustomListTargetingSetting struct {
	// CustomListId: Required. Custom id of custom list targeting
	// setting.
	// This id is custom_list_id.
	CustomListId int64 `json:"customListId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CustomListId") 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. "CustomListId") 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 *CustomListTargetingSetting) MarshalJSON() ([]byte, error) {
	type NoMethod CustomListTargetingSetting
	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)
}

// DateRange: A date range.
type DateRange struct {
	// EndDate: The upper bound of the date range, inclusive. Must specify a
	// positive value
	// for `year`, `month`, and `day`.
	EndDate *Date `json:"endDate,omitempty"`

	// StartDate: The lower bound of the date range, inclusive. Must specify
	// a positive value
	// for `year`, `month`, and `day`.
	StartDate *Date `json:"startDate,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 *DateRange) MarshalJSON() ([]byte, error) {
	type NoMethod DateRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DayAndTimeAssignedTargetingOptionDetails: Representation of a segment
// of time defined on a specific day of the week and
// with a start and end time.
// The time represented by `start_hour` must be before the time
// represented by
// `end_hour`.
type DayAndTimeAssignedTargetingOptionDetails struct {
	// DayOfWeek: Required. The day of the week for this day and time
	// targeting setting.
	//
	// Possible values:
	//   "DAY_OF_WEEK_UNSPECIFIED" - The day of the week is unspecified.
	//   "MONDAY" - Monday
	//   "TUESDAY" - Tuesday
	//   "WEDNESDAY" - Wednesday
	//   "THURSDAY" - Thursday
	//   "FRIDAY" - Friday
	//   "SATURDAY" - Saturday
	//   "SUNDAY" - Sunday
	DayOfWeek string `json:"dayOfWeek,omitempty"`

	// EndHour: Required. The end hour for day and time targeting. Must be
	// between 1 (1 hour after
	// start of day) and 24 (end of day).
	EndHour int64 `json:"endHour,omitempty"`

	// StartHour: Required. The start hour for day and time targeting. Must
	// be between 0 (start of day)
	// and 23 (1 hour before end of day).
	StartHour int64 `json:"startHour,omitempty"`

	// TimeZoneResolution: Required. The mechanism used to determine which
	// timezone to use for this day and time
	// targeting setting.
	//
	// Possible values:
	//   "TIME_ZONE_RESOLUTION_UNSPECIFIED" - Time zone resolution is either
	// unspecific or unknown.
	//   "TIME_ZONE_RESOLUTION_END_USER" - Times are resolved in the time
	// zone of the user that saw the ad.
	//   "TIME_ZONE_RESOLUTION_ADVERTISER" - Times are resolved in the time
	// zone of the advertiser that served the ad.
	TimeZoneResolution string `json:"timeZoneResolution,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DayOfWeek") 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. "DayOfWeek") 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 *DayAndTimeAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod DayAndTimeAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteAssignedTargetingOptionsRequest: A request listing which
// assigned targeting options of a given targeting type
// should be deleted.
type DeleteAssignedTargetingOptionsRequest struct {
	// AssignedTargetingOptionIds: Required. The assigned targeting option
	// IDs to delete.
	AssignedTargetingOptionIds []string `json:"assignedTargetingOptionIds,omitempty"`

	// TargetingType: Required. Identifies the type of this assigned
	// targeting option.
	//
	// Possible values:
	//   "TARGETING_TYPE_UNSPECIFIED" - Default value when type is not
	// specified or is unknown in this version.
	//   "TARGETING_TYPE_CHANNEL" - Target a channel (a custom group of
	// related websites or apps).
	//   "TARGETING_TYPE_APP_CATEGORY" - Target an app category (for
	// example, education or puzzle games).
	//   "TARGETING_TYPE_APP" - Target a specific app (for example, Angry
	// Birds).
	//   "TARGETING_TYPE_URL" - Target a specific url (for example,
	// quora.com).
	//   "TARGETING_TYPE_DAY_AND_TIME" - Target ads during a chosen time
	// period on a specific day.
	//   "TARGETING_TYPE_AGE_RANGE" - Target ads to a specific age range
	// (for example, 18-24).
	//   "TARGETING_TYPE_REGIONAL_LOCATION_LIST" - Target ads to the
	// specified regions on a regional location list.
	//   "TARGETING_TYPE_PROXIMITY_LOCATION_LIST" - Target ads to the
	// specified points of interest on a proximity location
	// list.
	//   "TARGETING_TYPE_GENDER" - Target ads to a specific gender (for
	// example, female or male).
	//   "TARGETING_TYPE_VIDEO_PLAYER_SIZE" - Target a specific video player
	// size for video ads.
	//   "TARGETING_TYPE_USER_REWARDED_CONTENT" - Target user rewarded
	// content for video ads.
	//   "TARGETING_TYPE_PARENTAL_STATUS" - Target ads to a specific
	// parental status (for example, parent or not a
	// parent).
	//   "TARGETING_TYPE_CONTENT_INSTREAM_POSITION" - Target video or audio
	// ads in a specific content instream position (for
	// example, pre-roll, mid-roll, or post-roll).
	//   "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION" - Target ads in a
	// specific content outstream position.
	//   "TARGETING_TYPE_DEVICE_TYPE" - Target ads to a specific device type
	// (for example, tablet or connected TV).
	//   "TARGETING_TYPE_AUDIENCE_GROUP" - Target ads to an audience or
	// groups of audiences.
	// Singleton field, at most one can exist on a single Lineitem at a
	// time.
	//   "TARGETING_TYPE_BROWSER" - Target ads to specific web browsers (for
	// example, Chrome).
	//   "TARGETING_TYPE_HOUSEHOLD_INCOME" - Target ads to a specific
	// household income range (for example, top 10%).
	//   "TARGETING_TYPE_ON_SCREEN_POSITION" - Target ads in a specific on
	// screen position.
	//   "TARGETING_TYPE_THIRD_PARTY_VERIFIER" - Filter web sites through
	// third party verification (for example, IAS or
	// DoubleVerify).
	//   "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION" - Filter web sites
	// by specific digital content label ratings (for example,
	// DL-MA: suitable only for mature audiences).
	//   "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION" - Filter website
	// content by sensitive categories (for example, adult).
	//   "TARGETING_TYPE_ENVIRONMENT" - Target ads to a specific environment
	// (for example, web or app).
	//   "TARGETING_TYPE_CARRIER_AND_ISP" - Target ads to a specific network
	// carrier or internet service provider
	// (ISP) (for example, Comcast or Orange).
	//   "TARGETING_TYPE_OPERATING_SYSTEM" - Target ads to a specific
	// operating system (for example, macOS).
	//   "TARGETING_TYPE_DEVICE_MAKE_MODEL" - Target ads to a specific
	// device make or model (for example, Roku or
	// Samsung).
	//   "TARGETING_TYPE_KEYWORD" - Target ads to a specific keyword (for
	// example, dog or retriever).
	//   "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST" - Target ads to a specific
	// negative keyword list.
	//   "TARGETING_TYPE_VIEWABILITY" - Target ads to a specific viewability
	// (for example, 80% viewable).
	//   "TARGETING_TYPE_CATEGORY" - Target ads to a specific content
	// category (for example, arts &
	// entertainment).
	//   "TARGETING_TYPE_INVENTORY_SOURCE" - Purchase impressions from
	// specific deals and auction packages.
	//   "TARGETING_TYPE_LANGUAGE" - Target ads to a specific language (for
	// example, English or Japanese).
	//   "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS" - Target ads to ads.txt
	// authorized sellers.
	//   "TARGETING_TYPE_GEO_REGION" - Target ads to a specific regional
	// location (for example, a city or state).
	//   "TARGETING_TYPE_INVENTORY_SOURCE_GROUP" - Purchase impressions from
	// a group of deals and auction packages.
	//   "TARGETING_TYPE_EXCHANGE" - Purchase impressions from specific
	// exchanges.
	//   "TARGETING_TYPE_SUB_EXCHANGE" - Purchase impressions from specific
	// sub-exchanges.
	TargetingType string `json:"targetingType,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AssignedTargetingOptionIds") 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.
	// "AssignedTargetingOptionIds") 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 *DeleteAssignedTargetingOptionsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteAssignedTargetingOptionsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceMakeModelAssignedTargetingOptionDetails: Assigned device make
// and model targeting option details. This will be
// populated in the
// device_make_model_details
// field when
// targeting_type is
// `TARGETING_TYPE_DEVICE_MAKE_MODEL`.
type DeviceMakeModelAssignedTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the device make and
	// model.
	DisplayName string `json:"displayName,omitempty"`

	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id field
	// when
	// targeting_type is
	// `TARGETING_TYPE_DEVICE_MAKE_MODEL`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *DeviceMakeModelAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceMakeModelAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceMakeModelTargetingOptionDetails: Represents a targetable device
// make and model. This will be populated in
// the
// device_make_model_details
// field of a TargetingOption when
// targeting_type is
// `TARGETING_TYPE_DEVICE_MAKE_MODEL`.
type DeviceMakeModelTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the device make and
	// model.
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *DeviceMakeModelTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceMakeModelTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceTypeAssignedTargetingOptionDetails: Targeting details for
// device type. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_DEVICE_TYPE`.
type DeviceTypeAssignedTargetingOptionDetails struct {
	// DeviceType: Output only. The display name of the device type.
	//
	// Possible values:
	//   "DEVICE_TYPE_UNSPECIFIED" - Default value when device type is not
	// specified in this version. This
	// enum is a placeholder for default value and does not represent a
	// real
	// device type option.
	//   "DEVICE_TYPE_COMPUTER" - The device type is computer.
	//   "DEVICE_TYPE_CONNECTED_TV" - The device type is connected TV.
	//   "DEVICE_TYPE_SMART_PHONE" - The device type is smart phone..
	//   "DEVICE_TYPE_TABLET" - The device type is tablet.
	DeviceType string `json:"deviceType,omitempty"`

	// TargetingOptionId: Required. ID of the device type.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeviceType") 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. "DeviceType") 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 *DeviceTypeAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceTypeAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceTypeTargetingOptionDetails: Represents a targetable device
// type. This will be populated in the
// device_type_details field of a
// TargetingOption when targeting_type is
// `TARGETING_TYPE_DEVICE_TYPE`.
type DeviceTypeTargetingOptionDetails struct {
	// DeviceType: Output only. The device type that is used to be targeted.
	//
	// Possible values:
	//   "DEVICE_TYPE_UNSPECIFIED" - Default value when device type is not
	// specified in this version. This
	// enum is a placeholder for default value and does not represent a
	// real
	// device type option.
	//   "DEVICE_TYPE_COMPUTER" - The device type is computer.
	//   "DEVICE_TYPE_CONNECTED_TV" - The device type is connected TV.
	//   "DEVICE_TYPE_SMART_PHONE" - The device type is smart phone..
	//   "DEVICE_TYPE_TABLET" - The device type is tablet.
	DeviceType string `json:"deviceType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeviceType") 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. "DeviceType") 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 *DeviceTypeTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceTypeTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DigitalContentLabelAssignedTargetingOptionDetails: Targeting details
// for digital content label. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION`.
type DigitalContentLabelAssignedTargetingOptionDetails struct {
	// ContentRatingTier: Output only. The display name of the digital
	// content label rating tier.
	//
	// Possible values:
	//   "CONTENT_RATING_TIER_UNSPECIFIED" - Content label is not specified
	// in this version. This enum is a place
	// holder for a default value and does not represent a real content
	// rating.
	//   "CONTENT_RATING_TIER_UNRATED" - Content that has not been labeled.
	//   "CONTENT_RATING_TIER_GENERAL" - Content suitable for general
	// audiences.
	//   "CONTENT_RATING_TIER_PARENTAL_GUIDANCE" - Content suitable for most
	// audiences with parental guidance.
	//   "CONTENT_RATING_TIER_TEENS" - Content suitable for teen and older
	// audiences.
	//   "CONTENT_RATING_TIER_MATURE" - Content suitable only for mature
	// audiences.
	ContentRatingTier string `json:"contentRatingTier,omitempty"`

	// ExcludedTargetingOptionId: Required. ID of the digital content label
	// to be EXCLUDED.
	ExcludedTargetingOptionId string `json:"excludedTargetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentRatingTier")
	// 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. "ContentRatingTier") 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 *DigitalContentLabelAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod DigitalContentLabelAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DigitalContentLabelTargetingOptionDetails: Represents a targetable
// digital content label rating tier. This will be
// populated in the
// digital_content_label_details
// field of the TargetingOption when
// targeting_type is
// `TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION`.
type DigitalContentLabelTargetingOptionDetails struct {
	// ContentRatingTier: Output only. An enum for the content label brand
	// safety tiers.
	//
	// Possible values:
	//   "CONTENT_RATING_TIER_UNSPECIFIED" - Content label is not specified
	// in this version. This enum is a place
	// holder for a default value and does not represent a real content
	// rating.
	//   "CONTENT_RATING_TIER_UNRATED" - Content that has not been labeled.
	//   "CONTENT_RATING_TIER_GENERAL" - Content suitable for general
	// audiences.
	//   "CONTENT_RATING_TIER_PARENTAL_GUIDANCE" - Content suitable for most
	// audiences with parental guidance.
	//   "CONTENT_RATING_TIER_TEENS" - Content suitable for teen and older
	// audiences.
	//   "CONTENT_RATING_TIER_MATURE" - Content suitable only for mature
	// audiences.
	ContentRatingTier string `json:"contentRatingTier,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentRatingTier")
	// 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. "ContentRatingTier") 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 *DigitalContentLabelTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod DigitalContentLabelTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Dimensions: Dimensions.
type Dimensions struct {
	// HeightPixels: The height in pixels.
	HeightPixels int64 `json:"heightPixels,omitempty"`

	// WidthPixels: The width in pixels.
	WidthPixels int64 `json:"widthPixels,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HeightPixels") 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. "HeightPixels") 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 *Dimensions) MarshalJSON() ([]byte, error) {
	type NoMethod Dimensions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DoubleVerify: Details of DoubleVerify settings.
type DoubleVerify struct {
	// AppStarRating: Avoid bidding on apps with the star ratings.
	AppStarRating *DoubleVerifyAppStarRating `json:"appStarRating,omitempty"`

	// AvoidedAgeRatings: Avoid bidding on apps with the age rating.
	//
	// Possible values:
	//   "AGE_RATING_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any age rating
	// options.
	//   "APP_AGE_RATE_UNKNOWN" - Apps with unknown age rating.
	//   "APP_AGE_RATE_4_PLUS" - Apps rated for Everyone (4+).
	//   "APP_AGE_RATE_9_PLUS" - Apps rated for Everyone (9+).
	//   "APP_AGE_RATE_12_PLUS" - Apps rated for Teens (12+).
	//   "APP_AGE_RATE_17_PLUS" - Apps rated for Mature (17+).
	//   "APP_AGE_RATE_18_PLUS" - Apps rated for Adults Only (18+).
	AvoidedAgeRatings []string `json:"avoidedAgeRatings,omitempty"`

	// BrandSafetyCategories: DV Brand Safety Controls.
	BrandSafetyCategories *DoubleVerifyBrandSafetyCategories `json:"brandSafetyCategories,omitempty"`

	// DisplayViewability: Display viewability settings (applicable to
	// display line items only).
	DisplayViewability *DoubleVerifyDisplayViewability `json:"displayViewability,omitempty"`

	// FraudInvalidTraffic: Avoid Sites and Apps with historical Fraud & IVT
	// Rates.
	FraudInvalidTraffic *DoubleVerifyFraudInvalidTraffic `json:"fraudInvalidTraffic,omitempty"`

	// VideoViewability: Video viewability settings (applicable to video
	// line items only).
	VideoViewability *DoubleVerifyVideoViewability `json:"videoViewability,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppStarRating") 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. "AppStarRating") 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 *DoubleVerify) MarshalJSON() ([]byte, error) {
	type NoMethod DoubleVerify
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DoubleVerifyAppStarRating: Details of DoubleVerify star ratings
// settings.
type DoubleVerifyAppStarRating struct {
	// AvoidInsufficientStarRating: Avoid bidding on apps with insufficient
	// star ratings.
	AvoidInsufficientStarRating bool `json:"avoidInsufficientStarRating,omitempty"`

	// AvoidedStarRating: Avoid bidding on apps with the star ratings.
	//
	// Possible values:
	//   "APP_STAR_RATE_UNSPECIFIED" - This enum is only a placeholder and
	// it doesn't specify any app star
	// rating options.
	//   "APP_STAR_RATE_1_POINT_5_LESS" - Official Apps with rating < 1.5
	// Stars.
	//   "APP_STAR_RATE_2_LESS" - Official Apps with rating < 2 Stars.
	//   "APP_STAR_RATE_2_POINT_5_LESS" - Official Apps with rating < 2.5
	// Stars.
	//   "APP_STAR_RATE_3_LESS" - Official Apps with rating < 3 Stars.
	//   "APP_STAR_RATE_3_POINT_5_LESS" - Official Apps with rating < 3.5
	// Stars.
	//   "APP_STAR_RATE_4_LESS" - Official Apps with rating < 4 Stars.
	//   "APP_STAR_RATE_4_POINT_5_LESS" - Official Apps with rating < 4.5
	// Stars.
	AvoidedStarRating string `json:"avoidedStarRating,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AvoidInsufficientStarRating") 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.
	// "AvoidInsufficientStarRating") 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 *DoubleVerifyAppStarRating) MarshalJSON() ([]byte, error) {
	type NoMethod DoubleVerifyAppStarRating
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DoubleVerifyBrandSafetyCategories: Settings for brand safety
// controls.
type DoubleVerifyBrandSafetyCategories struct {
	// AvoidUnknownBrandSafetyCategory: Unknown or unrateable.
	AvoidUnknownBrandSafetyCategory bool `json:"avoidUnknownBrandSafetyCategory,omitempty"`

	// AvoidedHighSeverityCategories: Brand safety high severity avoidance
	// categories.
	//
	// Possible values:
	//   "HIGHER_SEVERITY_UNSPECIFIED" - This enum is only a placeholder and
	// it doesn't specify any high
	// severity categories.
	//   "ADULT_CONTENT_PORNOGRAPHY" - Adult Content: Pornography, Mature
	// Topics & Nudity.
	//   "COPYRIGHT_INFRINGEMENT" - Copyright Infringement.
	//   "SUBSTANCE_ABUSE" - Drugs/Alcohol/Controlled Substances: Substance
	// Abuse.
	//   "GRAPHIC_VIOLENCE_WEAPONS" - Extreme Graphic/Explicit
	// Violence/Weapons.
	//   "HATE_PROFANITY" - Hate/Profanity.
	//   "CRIMINAL_SKILLS" - Illegal Activities: Criminal Skills.
	//   "NUISANCE_INCENTIVIZED_MALWARE_CLUTTER" -
	// Incentivized/Malware/Clutter.
	AvoidedHighSeverityCategories []string `json:"avoidedHighSeverityCategories,omitempty"`

	// AvoidedMediumSeverityCategories: Brand safety medium severity
	// avoidance categories.
	//
	// Possible values:
	//   "MEDIUM_SEVERITY_UNSPECIFIED" - This enum is only a placeholder and
	// it doesn't specify any medium
	// severity categories.
	//   "AD_SERVERS" - Ad Servers.
	//   "ADULT_CONTENT_SWIMSUIT" - Adult Content: Swimsuit.
	//   "ALTERNATIVE_LIFESTYLES" - Controversial Subjects: Alternative
	// Lifestyles.
	//   "CELEBRITY_GOSSIP" - Controversial Subjects: Celebrity Gossip.
	//   "GAMBLING" - Controversial Subjects: Gambling.
	//   "OCCULT" - Controversial Subjects: Occult.
	//   "SEX_EDUCATION" - Controversial Subjects: Sex Education.
	//   "DISASTER_AVIATION" - Disaster: Aviation.
	//   "DISASTER_MAN_MADE" - Disaster: Man-made.
	//   "DISASTER_NATURAL" - Disaster: Natural.
	//   "DISASTER_TERRORIST_EVENTS" - Disaster: Terrorist Events.
	//   "DISASTER_VEHICLE" - Disaster: Vehicle.
	//   "ALCOHOL" - Drugs/Alcohol/Controlled Substances: Alcohol.
	//   "SMOKING" - Drugs/Alcohol/Controlled Substances: Smoking.
	//   "NEGATIVE_NEWS_FINANCIAL" - Negative News: Financial.
	//   "NON_ENGLISH" - Non-Std Content: Non-English.
	//   "PARKING_PAGE" - Non-Std Content: Parking Page.
	//   "UNMODERATED_UGC" - Unmoderated UGC: Forums, Images & Video.
	//   "INFLAMMATORY_POLITICS_AND_NEWS" - Controversial Subjects:
	// Inflammatory Politics and News.
	//   "NEGATIVE_NEWS_PHARMACEUTICAL" - Negative News: Pharmaceutical.
	AvoidedMediumSeverityCategories []string `json:"avoidedMediumSeverityCategories,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AvoidUnknownBrandSafetyCategory") 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.
	// "AvoidUnknownBrandSafetyCategory") 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 *DoubleVerifyBrandSafetyCategories) MarshalJSON() ([]byte, error) {
	type NoMethod DoubleVerifyBrandSafetyCategories
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DoubleVerifyDisplayViewability: Details of DoubleVerify display
// viewability settings.
type DoubleVerifyDisplayViewability struct {
	// Iab: Target web and app inventory to maximize IAB viewable rate.
	//
	// Possible values:
	//   "IAB_VIEWED_RATE_UNSPECIFIED" - This enum is only a placeholder and
	// it doesn't specify any IAB viewed
	// rate options.
	//   "IAB_VIEWED_RATE_80_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 80% or
	// higher.
	//   "IAB_VIEWED_RATE_75_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 75% or
	// higher.
	//   "IAB_VIEWED_RATE_70_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 70% or
	// higher.
	//   "IAB_VIEWED_RATE_65_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 65% or
	// higher.
	//   "IAB_VIEWED_RATE_60_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 60% or
	// higher.
	//   "IAB_VIEWED_RATE_55_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 55% or
	// higher.
	//   "IAB_VIEWED_RATE_50_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 50% or
	// higher.
	//   "IAB_VIEWED_RATE_40_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 40% or
	// higher.
	//   "IAB_VIEWED_RATE_30_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 30% or
	// higher.
	Iab string `json:"iab,omitempty"`

	// ViewableDuring: Target web and app inventory to maximize 100%
	// viewable duration.
	//
	// Possible values:
	//   "AVERAGE_VIEW_DURATION_UNSPECIFIED" - This enum is only a
	// placeholder and it doesn't specify any average view
	// duration options.
	//   "AVERAGE_VIEW_DURATION_5_SEC" - Target web and app inventory to
	// maximize 100% viewable duration 5
	// seconds or more.
	//   "AVERAGE_VIEW_DURATION_10_SEC" - Target web and app inventory to
	// maximize 100% viewable duration 10
	// seconds or more.
	//   "AVERAGE_VIEW_DURATION_15_SEC" - Target web and app inventory to
	// maximize 100% viewable duration 15
	// seconds or more.
	ViewableDuring string `json:"viewableDuring,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Iab") 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. "Iab") 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 *DoubleVerifyDisplayViewability) MarshalJSON() ([]byte, error) {
	type NoMethod DoubleVerifyDisplayViewability
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DoubleVerifyFraudInvalidTraffic: DoubleVerify Fraud & Invalid Traffic
// settings.
type DoubleVerifyFraudInvalidTraffic struct {
	// AvoidInsufficientOption: Insufficient Historical Fraud & IVT Stats.
	AvoidInsufficientOption bool `json:"avoidInsufficientOption,omitempty"`

	// AvoidedFraudOption: Avoid Sites and Apps with historical Fraud & IVT.
	//
	// Possible values:
	//   "FRAUD_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any fraud and
	// invalid traffic options.
	//   "AD_IMPRESSION_FRAUD_100" - 100% Fraud & IVT.
	//   "AD_IMPRESSION_FRAUD_50" - 50% or Higher Fraud & IVT.
	//   "AD_IMPRESSION_FRAUD_25" - 25% or Higher Fraud & IVT.
	//   "AD_IMPRESSION_FRAUD_10" - 10% or Higher Fraud & IVT.
	//   "AD_IMPRESSION_FRAUD_8" - 8% or Higher Fraud & IVT.
	//   "AD_IMPRESSION_FRAUD_6" - 6% or Higher Fraud & IVT.
	//   "AD_IMPRESSION_FRAUD_4" - 4% or Higher Fraud & IVT.
	//   "AD_IMPRESSION_FRAUD_2" - 2% or Higher Fraud & IVT.
	AvoidedFraudOption string `json:"avoidedFraudOption,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AvoidInsufficientOption") 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. "AvoidInsufficientOption")
	// 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 *DoubleVerifyFraudInvalidTraffic) MarshalJSON() ([]byte, error) {
	type NoMethod DoubleVerifyFraudInvalidTraffic
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DoubleVerifyVideoViewability: Details of DoubleVerify video
// viewability settings.
type DoubleVerifyVideoViewability struct {
	// PlayerImpressionRate: Target inventory to maximize impressions with
	// 400x300 or greater player
	// size.
	//
	// Possible values:
	//   "PLAYER_SIZE_400X300_UNSPECIFIED" - This enum is only a placeholder
	// and it doesn't specify any impressions
	// options.
	//   "PLAYER_SIZE_400X300_95" - Sites with 95%+ of impressions.
	//   "PLAYER_SIZE_400X300_70" - Sites with 70%+ of impressions.
	//   "PLAYER_SIZE_400X300_25" - Sites with 25%+ of impressions.
	//   "PLAYER_SIZE_400X300_5" - Sites with 5%+ of impressions.
	PlayerImpressionRate string `json:"playerImpressionRate,omitempty"`

	// VideoIab: Target web inventory to maximize IAB viewable rate.
	//
	// Possible values:
	//   "VIDEO_IAB_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any video IAB
	// viewable rate options.
	//   "IAB_VIEWABILITY_80_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 80% or
	// higher.
	//   "IAB_VIEWABILITY_75_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 75% or
	// higher.
	//   "IAB_VIEWABILITY_70_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 70% or
	// higher.
	//   "IAB_VIEWABILITY_65_PERCENT_HIHGER" - Target web and app inventory
	// to maximize IAB viewable rate 65% or
	// higher.
	//   "IAB_VIEWABILITY_60_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 60% or
	// higher.
	//   "IAB_VIEWABILITY_55_PERCENT_HIHGER" - Target web and app inventory
	// to maximize IAB viewable rate 55% or
	// higher.
	//   "IAB_VIEWABILITY_50_PERCENT_HIGHER" - Target web and app inventory
	// to maximize IAB viewable rate 50% or
	// higher.
	//   "IAB_VIEWABILITY_40_PERCENT_HIHGER" - Target web and app inventory
	// to maximize IAB viewable rate 40% or
	// higher.
	//   "IAB_VIEWABILITY_30_PERCENT_HIHGER" - Target web and app inventory
	// to maximize IAB viewable rate 30% or
	// higher.
	VideoIab string `json:"videoIab,omitempty"`

	// VideoViewableRate: Target web inventory to maximize fully viewable
	// rate.
	//
	// Possible values:
	//   "VIDEO_VIEWABLE_RATE_UNSPECIFIED" - This enum is only a placeholder
	// and it doesn't specify any video
	// viewable rate options.
	//   "VIEWED_PERFORMANCE_40_PERCENT_HIGHER" - Target web inventory to
	// maximize fully viewable rate 40% or higher.
	//   "VIEWED_PERFORMANCE_35_PERCENT_HIGHER" - Target web inventory to
	// maximize fully viewable rate 35% or higher.
	//   "VIEWED_PERFORMANCE_30_PERCENT_HIGHER" - Target web inventory to
	// maximize fully viewable rate 30% or higher.
	//   "VIEWED_PERFORMANCE_25_PERCENT_HIGHER" - Target web inventory to
	// maximize fully viewable rate 25% or higher.
	//   "VIEWED_PERFORMANCE_20_PERCENT_HIGHER" - Target web inventory to
	// maximize fully viewable rate 20% or higher.
	//   "VIEWED_PERFORMANCE_10_PERCENT_HIGHER" - Target web inventory to
	// maximize fully viewable rate 10% or higher.
	VideoViewableRate string `json:"videoViewableRate,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PlayerImpressionRate") 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. "PlayerImpressionRate") 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 *DoubleVerifyVideoViewability) MarshalJSON() ([]byte, error) {
	type NoMethod DoubleVerifyVideoViewability
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// EnvironmentAssignedTargetingOptionDetails: Assigned environment
// targeting option details. This will be populated
// in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_ENVIRONMENT`.
type EnvironmentAssignedTargetingOptionDetails struct {
	// Environment: Output only. The serving environment.
	//
	// Possible values:
	//   "ENVIRONMENT_UNSPECIFIED" - Default value when environment is not
	// specified in this version. This enum
	// is a placeholder for default value and does not represent a
	// real
	// environment option.
	//   "ENVIRONMENT_WEB_OPTIMIZED" - Target inventory displayed in
	// browsers. This includes inventory that was
	// designed for the device it was viewed on, such as mobile websites
	// viewed on
	// a mobile device. ENVIRONMENT_WEB_NOT_OPTIMIZED, if targeted, should
	// be
	// deleted prior to the deletion of this targeting option.
	//   "ENVIRONMENT_WEB_NOT_OPTIMIZED" - Target inventory displayed in
	// browsers. This includes inventory that was
	// not designed for the device but viewed on it, such as websites
	// optimized
	// for desktop but viewed on a mobile device. ENVIRONMENT_WEB_OPTIMIZED
	// should
	// be targeted prior to the addition of this targeting option.
	//   "ENVIRONMENT_APP" - Target inventory displayed in apps.
	Environment string `json:"environment,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_ENVIRONMENT` (e.g.,
	// "508010"
	// for targeting the `ENVIRONMENT_WEB_OPTIMIZED` option).
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Environment") 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. "Environment") 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 *EnvironmentAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod EnvironmentAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnvironmentTargetingOptionDetails: Represents a targetable
// environment. This will be populated in the
// environment_details field of a
// TargetingOption when targeting_type is
// `TARGETING_TYPE_ENVIRONMENT`.
type EnvironmentTargetingOptionDetails struct {
	// Environment: Output only. The serving environment.
	//
	// Possible values:
	//   "ENVIRONMENT_UNSPECIFIED" - Default value when environment is not
	// specified in this version. This enum
	// is a placeholder for default value and does not represent a
	// real
	// environment option.
	//   "ENVIRONMENT_WEB_OPTIMIZED" - Target inventory displayed in
	// browsers. This includes inventory that was
	// designed for the device it was viewed on, such as mobile websites
	// viewed on
	// a mobile device. ENVIRONMENT_WEB_NOT_OPTIMIZED, if targeted, should
	// be
	// deleted prior to the deletion of this targeting option.
	//   "ENVIRONMENT_WEB_NOT_OPTIMIZED" - Target inventory displayed in
	// browsers. This includes inventory that was
	// not designed for the device but viewed on it, such as websites
	// optimized
	// for desktop but viewed on a mobile device. ENVIRONMENT_WEB_OPTIMIZED
	// should
	// be targeted prior to the addition of this targeting option.
	//   "ENVIRONMENT_APP" - Target inventory displayed in apps.
	Environment string `json:"environment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Environment") 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. "Environment") 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 *EnvironmentTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod EnvironmentTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExchangeAssignedTargetingOptionDetails: Details for assigned exchange
// targeting option. This will be populated in
// the details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_EXCHANGE`.
type ExchangeAssignedTargetingOptionDetails struct {
	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_EXCHANGE`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetingOptionId")
	// 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. "TargetingOptionId") 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 *ExchangeAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ExchangeAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExchangeReviewStatus: Exchange review status for the creative.
type ExchangeReviewStatus struct {
	// Exchange: The exchange reviewing the creative.
	//
	// Possible values:
	//   "EXCHANGE_UNSPECIFIED" - Exchange is not specified or is unknown in
	// this version.
	//   "EXCHANGE_GOOGLE_AD_MANAGER" - Google Ad Manager.
	//   "EXCHANGE_APPNEXUS" - AppNexus.
	//   "EXCHANGE_BRIGHTROLL" - BrightRoll Exchange for Video from Yahoo!.
	//   "EXCHANGE_ADFORM" - Adform.
	//   "EXCHANGE_ADMETA" - Admeta.
	//   "EXCHANGE_ADMIXER" - Admixer.
	//   "EXCHANGE_ADSMOGO" - AdsMogo.
	//   "EXCHANGE_ADSWIZZ" - AdsWizz.
	//   "EXCHANGE_BIDSWITCH" - BidSwitch.
	//   "EXCHANGE_BRIGHTROLL_DISPLAY" - BrightRoll Exchange for Display
	// from Yahoo!.
	//   "EXCHANGE_CADREON" - Cadreon.
	//   "EXCHANGE_DAILYMOTION" - Dailymotion.
	//   "EXCHANGE_FIVE" - Five.
	//   "EXCHANGE_FLUCT" - Fluct.
	//   "EXCHANGE_FREEWHEEL" - FreeWheel SSP.
	//   "EXCHANGE_GENIEE" - Geniee.
	//   "EXCHANGE_GUMGUM" - GumGum.
	//   "EXCHANGE_IMOBILE" - i-mobile.
	//   "EXCHANGE_IBILLBOARD" - iBILLBOARD.
	//   "EXCHANGE_IMPROVE_DIGITAL" - Improve Digital.
	//   "EXCHANGE_INDEX" - Index Exchange.
	//   "EXCHANGE_KARGO" - Kargo.
	//   "EXCHANGE_MICROAD" - MicroAd.
	//   "EXCHANGE_MOPUB" - MoPub.
	//   "EXCHANGE_NEND" - Nend.
	//   "EXCHANGE_ONE_BY_AOL_DISPLAY" - ONE by AOL: Display Market Place.
	//   "EXCHANGE_ONE_BY_AOL_MOBILE" - ONE by AOL: Mobile.
	//   "EXCHANGE_ONE_BY_AOL_VIDEO" - ONE by AOL: Video.
	//   "EXCHANGE_OOYALA" - Ooyala.
	//   "EXCHANGE_OPENX" - OpenX.
	//   "EXCHANGE_PERMODO" - Permodo.
	//   "EXCHANGE_PLATFORMONE" - Platform One.
	//   "EXCHANGE_PLATFORMID" - PlatformId.
	//   "EXCHANGE_PUBMATIC" - PubMatic.
	//   "EXCHANGE_PULSEPOINT" - PulsePoint.
	//   "EXCHANGE_REVENUEMAX" - RevenueMax.
	//   "EXCHANGE_RUBICON" - Rubicon.
	//   "EXCHANGE_SMARTCLIP" - SmartClip.
	//   "EXCHANGE_SMARTRTB" - SmartRTB+.
	//   "EXCHANGE_SMARTSTREAMTV" - SmartstreamTv.
	//   "EXCHANGE_SOVRN" - Sovrn.
	//   "EXCHANGE_SPOTXCHANGE" - SpotXchange.
	//   "EXCHANGE_STROER" - Ströer SSP.
	//   "EXCHANGE_TEADSTV" - TeadsTv.
	//   "EXCHANGE_TELARIA" - Telaria.
	//   "EXCHANGE_TVN" - TVN.
	//   "EXCHANGE_UNITED" - United.
	//   "EXCHANGE_YIELDLAB" - Yieldlab.
	//   "EXCHANGE_YIELDMO" - Yieldmo.
	//   "EXCHANGE_TRIPLELIFT" - TripleLift
	//   "EXCHANGE_TABOOLA" - Taboola
	//   "EXCHANGE_INMOBI" - InMobi.
	//   "EXCHANGE_SMAATO" - Smaato
	//   "EXCHANGE_AJA" - Aja.
	//   "EXCHANGE_NEXSTAR_DIGITAL" - Nexstar Digital.
	//   "EXCHANGE_WAZE" - Waze.
	Exchange string `json:"exchange,omitempty"`

	// Status: Status of the exchange review.
	//
	// Possible values:
	//   "REVIEW_STATUS_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "REVIEW_STATUS_APPROVED" - The creative is approved.
	//   "REVIEW_STATUS_REJECTED" - The creative is rejected.
	//   "REVIEW_STATUS_PENDING" - The creative is pending review.
	Status string `json:"status,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Exchange") 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. "Exchange") 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 *ExchangeReviewStatus) MarshalJSON() ([]byte, error) {
	type NoMethod ExchangeReviewStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExchangeTargetingOptionDetails: Represents a targetable exchange.
// This will be populated in the
// exchange_details field
// of a TargetingOption when
// targeting_type is
// `TARGETING_TYPE_EXCHANGE`.
type ExchangeTargetingOptionDetails struct {
	// Exchange: Output only. The type of exchange.
	//
	// Possible values:
	//   "EXCHANGE_UNSPECIFIED" - Exchange is not specified or is unknown in
	// this version.
	//   "EXCHANGE_GOOGLE_AD_MANAGER" - Google Ad Manager.
	//   "EXCHANGE_APPNEXUS" - AppNexus.
	//   "EXCHANGE_BRIGHTROLL" - BrightRoll Exchange for Video from Yahoo!.
	//   "EXCHANGE_ADFORM" - Adform.
	//   "EXCHANGE_ADMETA" - Admeta.
	//   "EXCHANGE_ADMIXER" - Admixer.
	//   "EXCHANGE_ADSMOGO" - AdsMogo.
	//   "EXCHANGE_ADSWIZZ" - AdsWizz.
	//   "EXCHANGE_BIDSWITCH" - BidSwitch.
	//   "EXCHANGE_BRIGHTROLL_DISPLAY" - BrightRoll Exchange for Display
	// from Yahoo!.
	//   "EXCHANGE_CADREON" - Cadreon.
	//   "EXCHANGE_DAILYMOTION" - Dailymotion.
	//   "EXCHANGE_FIVE" - Five.
	//   "EXCHANGE_FLUCT" - Fluct.
	//   "EXCHANGE_FREEWHEEL" - FreeWheel SSP.
	//   "EXCHANGE_GENIEE" - Geniee.
	//   "EXCHANGE_GUMGUM" - GumGum.
	//   "EXCHANGE_IMOBILE" - i-mobile.
	//   "EXCHANGE_IBILLBOARD" - iBILLBOARD.
	//   "EXCHANGE_IMPROVE_DIGITAL" - Improve Digital.
	//   "EXCHANGE_INDEX" - Index Exchange.
	//   "EXCHANGE_KARGO" - Kargo.
	//   "EXCHANGE_MICROAD" - MicroAd.
	//   "EXCHANGE_MOPUB" - MoPub.
	//   "EXCHANGE_NEND" - Nend.
	//   "EXCHANGE_ONE_BY_AOL_DISPLAY" - ONE by AOL: Display Market Place.
	//   "EXCHANGE_ONE_BY_AOL_MOBILE" - ONE by AOL: Mobile.
	//   "EXCHANGE_ONE_BY_AOL_VIDEO" - ONE by AOL: Video.
	//   "EXCHANGE_OOYALA" - Ooyala.
	//   "EXCHANGE_OPENX" - OpenX.
	//   "EXCHANGE_PERMODO" - Permodo.
	//   "EXCHANGE_PLATFORMONE" - Platform One.
	//   "EXCHANGE_PLATFORMID" - PlatformId.
	//   "EXCHANGE_PUBMATIC" - PubMatic.
	//   "EXCHANGE_PULSEPOINT" - PulsePoint.
	//   "EXCHANGE_REVENUEMAX" - RevenueMax.
	//   "EXCHANGE_RUBICON" - Rubicon.
	//   "EXCHANGE_SMARTCLIP" - SmartClip.
	//   "EXCHANGE_SMARTRTB" - SmartRTB+.
	//   "EXCHANGE_SMARTSTREAMTV" - SmartstreamTv.
	//   "EXCHANGE_SOVRN" - Sovrn.
	//   "EXCHANGE_SPOTXCHANGE" - SpotXchange.
	//   "EXCHANGE_STROER" - Ströer SSP.
	//   "EXCHANGE_TEADSTV" - TeadsTv.
	//   "EXCHANGE_TELARIA" - Telaria.
	//   "EXCHANGE_TVN" - TVN.
	//   "EXCHANGE_UNITED" - United.
	//   "EXCHANGE_YIELDLAB" - Yieldlab.
	//   "EXCHANGE_YIELDMO" - Yieldmo.
	//   "EXCHANGE_TRIPLELIFT" - TripleLift
	//   "EXCHANGE_TABOOLA" - Taboola
	//   "EXCHANGE_INMOBI" - InMobi.
	//   "EXCHANGE_SMAATO" - Smaato
	//   "EXCHANGE_AJA" - Aja.
	//   "EXCHANGE_NEXSTAR_DIGITAL" - Nexstar Digital.
	//   "EXCHANGE_WAZE" - Waze.
	Exchange string `json:"exchange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Exchange") 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. "Exchange") 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 *ExchangeTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ExchangeTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ExitEvent: Exit event of the creative.
type ExitEvent struct {
	// Name: The name of the click tag of the exit event.
	//
	// The name must be unique within one creative.
	//
	// Leave it empty or unset for creatives containing image assets only.
	Name string `json:"name,omitempty"`

	// ReportingName: The name used to identify this event in reports.
	// Leave it empty or unset for creatives containing image assets only.
	ReportingName string `json:"reportingName,omitempty"`

	// Type: Required. The type of the exit event.
	//
	// Possible values:
	//   "EXIT_EVENT_TYPE_UNSPECIFIED" - Exit event type is not specified or
	// is unknown in this version.
	//   "EXIT_EVENT_TYPE_DEFAULT" - The exit event is the default one.
	//   "EXIT_EVENT_TYPE_BACKUP" - The exit event is a backup exit
	// event.
	// There could be multiple backup exit events in a creative.
	Type string `json:"type,omitempty"`

	// Url: Required. The click through URL of the exit event.
	// This is required when type is:
	//
	// * `EXIT_EVENT_TYPE_DEFAULT`
	// * `EXIT_EVENT_TYPE_BACKUP`
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *ExitEvent) MarshalJSON() ([]byte, error) {
	type NoMethod ExitEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FirstAndThirdPartyAudience: Describes a first or third party audience
// list used for targeting.
// First party audiences are created via usage of client data.
// Third party audiences are provided by Third Party data providers and
// can only
// be licensed to customers.
type FirstAndThirdPartyAudience struct {
	// DisplayName: Output only. The display name of the first and third
	// party audience.
	// .
	DisplayName string `json:"displayName,omitempty"`

	// FirstAndThirdPartyAudienceId: Output only. The unique ID of the first
	// and third party audience. Assigned by the
	// system.
	FirstAndThirdPartyAudienceId int64 `json:"firstAndThirdPartyAudienceId,omitempty,string"`

	// FirstAndThirdPartyAudienceType: Output only. Whether the audience is
	// a first or third party audience.
	// .
	//
	// Possible values:
	//   "FIRST_AND_THIRD_PARTY_AUDIENCE_TYPE_UNSPECIFIED" - Default value
	// when type is not specified or is unknown.
	//   "FIRST_AND_THIRD_PARTY_AUDIENCE_TYPE_FIRST_PARTY" - Audience that
	// is created via usage of client data.
	//   "FIRST_AND_THIRD_PARTY_AUDIENCE_TYPE_THIRD_PARTY" - Audience that
	// is provided by Third Party data providers.
	FirstAndThirdPartyAudienceType string `json:"firstAndThirdPartyAudienceType,omitempty"`

	// Name: Output only. The resource name of the first and third party
	// audience.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "DisplayName") 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 *FirstAndThirdPartyAudience) MarshalJSON() ([]byte, error) {
	type NoMethod FirstAndThirdPartyAudience
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FirstAndThirdPartyAudienceGroup: Details of first and third party
// audience group.
// All first and third party audience targeting settings are logically
// ‘OR’ of
// each other.
type FirstAndThirdPartyAudienceGroup struct {
	// Settings: Required. All first and third party audience targeting
	// settings in first and
	// third party audience group.
	// Repeated settings with same id are not allowed.
	Settings []*FirstAndThirdPartyAudienceTargetingSetting `json:"settings,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Settings") 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. "Settings") 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 *FirstAndThirdPartyAudienceGroup) MarshalJSON() ([]byte, error) {
	type NoMethod FirstAndThirdPartyAudienceGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FirstAndThirdPartyAudienceTargetingSetting: Details of first and
// third party audience targeting setting.
type FirstAndThirdPartyAudienceTargetingSetting struct {
	// FirstAndThirdPartyAudienceId: Required. First and third party
	// audience id of the first and third party audience
	// targeting setting. This id is
	// first_and_third_party_audience_id.
	FirstAndThirdPartyAudienceId int64 `json:"firstAndThirdPartyAudienceId,omitempty,string"`

	// Recency: The recency of the first and third party audience targeting
	// setting.
	// Only applicable to first party audiences, otherwise
	// will be ignored. For more info, refer
	// to
	// https://support.google.com/displayvideo/answer/2949947#recency
	// When
	//  unspecified, no recency limit will be used.
	//
	// Possible values:
	//   "RECENCY_NO_LIMIT" - No limit of recency.
	//   "RECENCY_1_MINUTE" - Recency is 1 minute.
	//   "RECENCY_5_MINUTES" - Recency is 5 minutes.
	//   "RECENCY_10_MINUTES" - Recency is 10 minutes.
	//   "RECENCY_15_MINUTES" - Recency is 15 minutes.
	//   "RECENCY_30_MINUTES" - Recency is 30 minutes.
	//   "RECENCY_1_HOUR" - Recency is 1 hour.
	//   "RECENCY_2_HOURS" - Recency is 2 hours.
	//   "RECENCY_3_HOURS" - Recency is 3 hours.
	//   "RECENCY_6_HOURS" - Recency is 6 hours.
	//   "RECENCY_12_HOURS" - Recency is 12 hours.
	//   "RECENCY_1_DAY" - Recency is 1 day.
	//   "RECENCY_2_DAYS" - Recency is 2 days.
	//   "RECENCY_3_DAYS" - Recency is 3 days.
	//   "RECENCY_5_DAYS" - Recency is 5 days.
	//   "RECENCY_7_DAYS" - Recency is 7 days.
	//   "RECENCY_10_DAYS" - Recency is 10 days.
	//   "RECENCY_14_DAYS" - Recency is 14 days.
	//   "RECENCY_15_DAYS" - Recency is 15 days.
	//   "RECENCY_21_DAYS" - Recency is 21 days.
	//   "RECENCY_28_DAYS" - Recency is 28 days.
	//   "RECENCY_30_DAYS" - Recency is 30 days.
	//   "RECENCY_40_DAYS" - Recency is 40 days.
	//   "RECENCY_60_DAYS" - Recency is 60 days.
	//   "RECENCY_90_DAYS" - Recency is 90 days.
	//   "RECENCY_120_DAYS" - Recency is 120 days.
	//   "RECENCY_180_DAYS" - Recency is 180 days.
	//   "RECENCY_270_DAYS" - Recency is 270 days.
	//   "RECENCY_365_DAYS" - Recency is 365 days.
	Recency string `json:"recency,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "FirstAndThirdPartyAudienceId") 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.
	// "FirstAndThirdPartyAudienceId") 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 *FirstAndThirdPartyAudienceTargetingSetting) MarshalJSON() ([]byte, error) {
	type NoMethod FirstAndThirdPartyAudienceTargetingSetting
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FixedBidStrategy: A strategy that uses a fixed bidding price.
type FixedBidStrategy struct {
	// BidAmountMicros: The fixed bid amount, in micros of the advertiser's
	// currency.
	// For insertion order entity,
	// bid_amount_micros should be set as 0.
	// For line item entity,
	// bid_amount_micros must be greater
	// than or equal to billable unit of the given currency and smaller than
	// or
	// equal to the upper limit 1000000000.
	//
	// For example, 1500000 represents 1.5 standard units of the currency.
	BidAmountMicros int64 `json:"bidAmountMicros,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "BidAmountMicros") 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. "BidAmountMicros") 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 *FixedBidStrategy) MarshalJSON() ([]byte, error) {
	type NoMethod FixedBidStrategy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FloodlightGroup: A single Floodlight group.
type FloodlightGroup struct {
	// ActiveViewConfig: The Active View video viewability metric
	// configuration for the Floodlight
	// group.
	ActiveViewConfig *ActiveViewVideoViewabilityMetricConfig `json:"activeViewConfig,omitempty"`

	// CustomVariables: User-defined custom variables owned by the
	// Floodlight group.
	// Use custom Floodlight variables to create reporting data that is
	// tailored
	// to your unique business needs. Custom Floodlight variables use the
	// keys
	// `U1=`, `U2=`, and so on, and can take any values that you choose to
	// pass to
	// them. You can use them to track virtually any type of data that you
	// collect
	// about your customers, such as the genre of movie that a customer
	// purchases,
	// the country to which the item is shipped, and so on.
	//
	// Custom Floodlight variables may not be used to pass any data that
	// could be
	// used or recognized as personally identifiable information
	// (PII).
	//
	// Example:
	// `custom_variables {
	//   fields {
	//     "U1": value { number_value: 123.4 },
	//     "U2": value { string_value: "MyVariable2" },
	//     "U3": value { string_value: "MyVariable3" }
	//   }
	// }`
	//
	// Acceptable values for keys are "U1" through "U100", inclusive.
	// String
	// values must be less than 64 characters long, and cannot contain
	// the
	// following characters: "<>`.
	CustomVariables googleapi.RawMessage `json:"customVariables,omitempty"`

	// DisplayName: Required. The display name of the Floodlight group.
	DisplayName string `json:"displayName,omitempty"`

	// FloodlightGroupId: Output only. The unique ID of the Floodlight
	// group. Assigned by the system.
	FloodlightGroupId int64 `json:"floodlightGroupId,omitempty,string"`

	// LookbackWindow: Required. The lookback window for the Floodlight
	// group.
	// Both click_days and
	// impression_days are required. Acceptable
	// values for both are `0` to `90`, inclusive.
	LookbackWindow *LookbackWindow `json:"lookbackWindow,omitempty"`

	// Name: Output only. The resource name of the Floodlight group.
	Name string `json:"name,omitempty"`

	// WebTagType: Required. The web tag type enabled for the Floodlight
	// group.
	//
	// Possible values:
	//   "WEB_TAG_TYPE_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "WEB_TAG_TYPE_NONE" - No tag type.
	//   "WEB_TAG_TYPE_IMAGE" - Image tag.
	//   "WEB_TAG_TYPE_DYNAMIC" - Dynamic tag.
	WebTagType string `json:"webTagType,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ActiveViewConfig") 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. "ActiveViewConfig") 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 *FloodlightGroup) MarshalJSON() ([]byte, error) {
	type NoMethod FloodlightGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FrequencyCap: Settings that control the number of times a user may be
// shown with the same
// ad during a given time period.
type FrequencyCap struct {
	// MaxImpressions: The maximum number of times a user may be shown with
	// the same ad
	// during this period. Must be greater than 0.
	//
	// Applicable when unlimited is `false`.
	MaxImpressions int64 `json:"maxImpressions,omitempty"`

	// TimeUnit: The time unit in which the frequency cap will be
	// applied.
	//
	// Applicable when unlimited is `false`.
	//
	// Possible values:
	//   "TIME_UNIT_UNSPECIFIED" - Time unit value is not specified or is
	// unknown in this version.
	//   "TIME_UNIT_LIFETIME" - The frequency cap will be applied to the
	// whole life time of the line
	// item.
	//   "TIME_UNIT_MONTHS" - The frequency cap will be applied to a number
	// of months.
	//   "TIME_UNIT_WEEKS" - The frequency cap will be applied to a number
	// of weeks.
	//   "TIME_UNIT_DAYS" - The frequency cap will be applied to a number of
	// days.
	//   "TIME_UNIT_HOURS" - The frequency cap will be applied to a number
	// of hours.
	//   "TIME_UNIT_MINUTES" - The frequency cap will be applied to a number
	// of minutes.
	TimeUnit string `json:"timeUnit,omitempty"`

	// TimeUnitCount: The number of time_unit the frequency cap
	// will
	// last.
	//
	// Applicable when unlimited is `false`.
	// The following restrictions apply based on the value of
	// time_unit:
	//
	// * `TIME_UNIT_LIFETIME` - this field is output only and will
	// default to 1
	// * `TIME_UNIT_MONTHS` - must be between 1 and 2
	// * `TIME_UNIT_WEEKS` - must be between 1 and 4
	// * `TIME_UNIT_DAYS` - must be between 1 and 6
	// * `TIME_UNIT_HOURS` - must be between 1 and 23
	// * `TIME_UNIT_MINUTES` - must be between 1 and 59
	TimeUnitCount int64 `json:"timeUnitCount,omitempty"`

	// Unlimited: Whether unlimited frequency capping is applied. When this
	// field is set to
	// `true`, the remaining frequency cap fields are not applicable.
	Unlimited bool `json:"unlimited,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MaxImpressions") 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. "MaxImpressions") 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 *FrequencyCap) MarshalJSON() ([]byte, error) {
	type NoMethod FrequencyCap
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GenderAssignedTargetingOptionDetails: Details for assigned gender
// targeting option. This will be populated in
// the details field of an AssignedTargetingOption when
// targeting_type is
// `TARTGETING_TYPE_GENDER`.
type GenderAssignedTargetingOptionDetails struct {
	// Gender: Output only. The gender of the audience.
	//
	// Possible values:
	//   "GENDER_UNSPECIFIED" - Default value when gender is not specified
	// in this version. This enum is a
	// place holder for default value and does not represent a real gender
	// option.
	//   "GENDER_MALE" - The audience gender is male.
	//   "GENDER_FEMALE" - The audience gender is female.
	//   "GENDER_UNKNOWN" - The audience gender is unknown.
	Gender string `json:"gender,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_GENDER`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Gender") 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. "Gender") 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 *GenderAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod GenderAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GenderTargetingOptionDetails: Represents a targetable gender. This
// will be populated in the
// gender_details field of a TargetingOption
// when targeting_type is
// `TARGETING_TYPE_GENDER`.
type GenderTargetingOptionDetails struct {
	// Gender: Output only. The gender of an audience.
	//
	// Possible values:
	//   "GENDER_UNSPECIFIED" - Default value when gender is not specified
	// in this version. This enum is a
	// place holder for default value and does not represent a real gender
	// option.
	//   "GENDER_MALE" - The audience gender is male.
	//   "GENDER_FEMALE" - The audience gender is female.
	//   "GENDER_UNKNOWN" - The audience gender is unknown.
	Gender string `json:"gender,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Gender") 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. "Gender") 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 *GenderTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod GenderTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GeoRegionAssignedTargetingOptionDetails: Details for assigned
// geographic region targeting option. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_GEO_REGION`.
type GeoRegionAssignedTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the geographic region
	// (e.g., "Ontario, Canada").
	DisplayName string `json:"displayName,omitempty"`

	// GeoRegionType: Output only. The type of geographic region targeting.
	//
	// Possible values:
	//   "GEO_REGION_TYPE_UNKNOWN" - The geographic region type is unknown.
	//   "GEO_REGION_TYPE_OTHER" - The geographic region type is other.
	//   "GEO_REGION_TYPE_COUNTRY" - The geographic region is a country.
	//   "GEO_REGION_TYPE_REGION" - The geographic region type is region.
	//   "GEO_REGION_TYPE_TERRITORY" - The geographic region is a territory.
	//   "GEO_REGION_TYPE_PROVINCE" - The geographic region is a province.
	//   "GEO_REGION_TYPE_STATE" - The geographic region is a state.
	//   "GEO_REGION_TYPE_PREFECTURE" - The geographic region is a
	// prefecture.
	//   "GEO_REGION_TYPE_GOVERNORATE" - The geographic region is a
	// governorate.
	//   "GEO_REGION_TYPE_CANTON" - The geographic region is a canton.
	//   "GEO_REGION_TYPE_UNION_TERRITORY" - The geographic region is a
	// union territory.
	//   "GEO_REGION_TYPE_AUTONOMOUS_COMMUNITY" - The geographic region is
	// an autonomous community.
	//   "GEO_REGION_TYPE_DMA_REGION" - The geographic region is a
	// designated market area (DMA) region.
	//   "GEO_REGION_TYPE_METRO" - The geographic region type is metro.
	//   "GEO_REGION_TYPE_CONGRESSIONAL_DISTRICT" - The geographic region is
	// a congressional district.
	//   "GEO_REGION_TYPE_COUNTY" - The geographic region is a county.
	//   "GEO_REGION_TYPE_MUNICIPALITY" - The geographic region is a
	// municipality.
	//   "GEO_REGION_TYPE_CITY" - The geographic region is a city.
	//   "GEO_REGION_TYPE_POSTAL_CODE" - The geographic region targeting
	// type is postal code.
	//   "GEO_REGION_TYPE_DEPARTMENT" - The geographic region targeting type
	// is department.
	//   "GEO_REGION_TYPE_AIRPORT" - The geographic region is an airport.
	//   "GEO_REGION_TYPE_TV_REGION" - The geographic region is a TV region.
	//   "GEO_REGION_TYPE_OKRUG" - The geographic region is an okrug.
	//   "GEO_REGION_TYPE_BOROUGH" - The geographic region is a borough.
	//   "GEO_REGION_TYPE_CITY_REGION" - The geographic region is a city
	// region.
	//   "GEO_REGION_TYPE_ARRONDISSEMENT" - The geographic region is an
	// arrondissement.
	//   "GEO_REGION_TYPE_NEIGHBORHOOD" - The geographic region is a
	// neighborhood.
	//   "GEO_REGION_TYPE_UNIVERSITY" - The geographic region is a
	// university.
	//   "GEO_REGION_TYPE_DISTRICT" - The geographic region is a district.
	GeoRegionType string `json:"geoRegionType,omitempty"`

	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_GEO_REGION`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *GeoRegionAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod GeoRegionAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GeoRegionTargetingOptionDetails: Represents a targetable geographic
// region. This will be populated in the
// geo_region_details field when
// targeting_type is
// `TARGETING_TYPE_GEO_REGION`.
type GeoRegionTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the geographic region
	// (e.g., "Ontario, Canada").
	DisplayName string `json:"displayName,omitempty"`

	// GeoRegionType: Output only. The type of geographic region targeting.
	//
	// Possible values:
	//   "GEO_REGION_TYPE_UNKNOWN" - The geographic region type is unknown.
	//   "GEO_REGION_TYPE_OTHER" - The geographic region type is other.
	//   "GEO_REGION_TYPE_COUNTRY" - The geographic region is a country.
	//   "GEO_REGION_TYPE_REGION" - The geographic region type is region.
	//   "GEO_REGION_TYPE_TERRITORY" - The geographic region is a territory.
	//   "GEO_REGION_TYPE_PROVINCE" - The geographic region is a province.
	//   "GEO_REGION_TYPE_STATE" - The geographic region is a state.
	//   "GEO_REGION_TYPE_PREFECTURE" - The geographic region is a
	// prefecture.
	//   "GEO_REGION_TYPE_GOVERNORATE" - The geographic region is a
	// governorate.
	//   "GEO_REGION_TYPE_CANTON" - The geographic region is a canton.
	//   "GEO_REGION_TYPE_UNION_TERRITORY" - The geographic region is a
	// union territory.
	//   "GEO_REGION_TYPE_AUTONOMOUS_COMMUNITY" - The geographic region is
	// an autonomous community.
	//   "GEO_REGION_TYPE_DMA_REGION" - The geographic region is a
	// designated market area (DMA) region.
	//   "GEO_REGION_TYPE_METRO" - The geographic region type is metro.
	//   "GEO_REGION_TYPE_CONGRESSIONAL_DISTRICT" - The geographic region is
	// a congressional district.
	//   "GEO_REGION_TYPE_COUNTY" - The geographic region is a county.
	//   "GEO_REGION_TYPE_MUNICIPALITY" - The geographic region is a
	// municipality.
	//   "GEO_REGION_TYPE_CITY" - The geographic region is a city.
	//   "GEO_REGION_TYPE_POSTAL_CODE" - The geographic region targeting
	// type is postal code.
	//   "GEO_REGION_TYPE_DEPARTMENT" - The geographic region targeting type
	// is department.
	//   "GEO_REGION_TYPE_AIRPORT" - The geographic region is an airport.
	//   "GEO_REGION_TYPE_TV_REGION" - The geographic region is a TV region.
	//   "GEO_REGION_TYPE_OKRUG" - The geographic region is an okrug.
	//   "GEO_REGION_TYPE_BOROUGH" - The geographic region is a borough.
	//   "GEO_REGION_TYPE_CITY_REGION" - The geographic region is a city
	// region.
	//   "GEO_REGION_TYPE_ARRONDISSEMENT" - The geographic region is an
	// arrondissement.
	//   "GEO_REGION_TYPE_NEIGHBORHOOD" - The geographic region is a
	// neighborhood.
	//   "GEO_REGION_TYPE_UNIVERSITY" - The geographic region is a
	// university.
	//   "GEO_REGION_TYPE_DISTRICT" - The geographic region is a district.
	GeoRegionType string `json:"geoRegionType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *GeoRegionTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod GeoRegionTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAudience: Describes a Google audience resource.
// Includes Google audience lists.
type GoogleAudience struct {
	// DisplayName: Output only. The display name of the Google audience.
	// .
	DisplayName string `json:"displayName,omitempty"`

	// GoogleAudienceId: Output only. The unique ID of the Google audience.
	// Assigned by the system.
	GoogleAudienceId int64 `json:"googleAudienceId,omitempty,string"`

	// GoogleAudienceType: Output only. The type of Google audience.
	// .
	//
	// Possible values:
	//   "GOOGLE_AUDIENCE_TYPE_UNSPECIFIED" - Default value when type is not
	// specified or is unknown.
	//   "GOOGLE_AUDIENCE_TYPE_AFFINITY" - Affinity type Google audience.
	//   "GOOGLE_AUDIENCE_TYPE_IN_MARKET" - In-Market type Google audience.
	//   "GOOGLE_AUDIENCE_TYPE_INSTALLED_APPS" - Installed-apps type Google
	// audience.
	//   "GOOGLE_AUDIENCE_TYPE_NEW_MOBILE_DEVICES" - New-mobile-devices type
	// Google audience.
	GoogleAudienceType string `json:"googleAudienceType,omitempty"`

	// Name: Output only. The resource name of the google audience.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "DisplayName") 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 *GoogleAudience) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAudience
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAudienceGroup: Details of Google audience group.
// All Google audience targeting settings are logically ‘OR’ of each
// other.
type GoogleAudienceGroup struct {
	// Settings: Required. All Google audience targeting settings in Google
	// audience group.
	// Repeated settings with same id will be ignored.
	Settings []*GoogleAudienceTargetingSetting `json:"settings,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Settings") 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. "Settings") 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 *GoogleAudienceGroup) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAudienceGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAudienceTargetingSetting: Details of Google audience targeting
// setting.
type GoogleAudienceTargetingSetting struct {
	// GoogleAudienceId: Required. Google audience id of the Google audience
	// targeting setting.
	// This id is google_audience_id.
	GoogleAudienceId int64 `json:"googleAudienceId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "GoogleAudienceId") 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. "GoogleAudienceId") 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 *GoogleAudienceTargetingSetting) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAudienceTargetingSetting
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleBytestreamMedia: Media resource.
type GoogleBytestreamMedia struct {
	// ResourceName: Name of the media resource.
	ResourceName string `json:"resourceName,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "ResourceName") 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. "ResourceName") 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 *GoogleBytestreamMedia) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleBytestreamMedia
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HouseholdIncomeAssignedTargetingOptionDetails: Details for assigned
// household income targeting option. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_HOUSEHOLD_INCOME`.
type HouseholdIncomeAssignedTargetingOptionDetails struct {
	// HouseholdIncome: Output only. The household income of the audience.
	//
	// Possible values:
	//   "HOUSEHOLD_INCOME_UNSPECIFIED" - Default value when household
	// income is not specified in this version. This
	// enum is a placeholder for default value and does not represent a
	// real
	// household income option.
	//   "HOUSEHOLD_INCOME_UNKNOWN" - The household income of the audience
	// is unknown.
	//   "HOUSEHOLD_INCOME_LOWER_50_PERCENT" - The audience is in the lower
	// 50% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_41_TO_50_PERCENT" - The audience is in the
	// top 41-50% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_31_TO_40_PERCENT" - The audience is in the
	// top 31-40% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_21_TO_30_PERCENT" - The audience is in the
	// top 21-30% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_11_TO_20_PERCENT" - The audience is in the
	// top 11-20% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_10_PERCENT" - The audience is in the top 10%
	// of U.S. household incomes.
	HouseholdIncome string `json:"householdIncome,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_HOUSEHOLD_INCOME`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HouseholdIncome") 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. "HouseholdIncome") 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 *HouseholdIncomeAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod HouseholdIncomeAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// HouseholdIncomeTargetingOptionDetails: Represents a targetable
// household income. This will be populated in
// the
// household_income_details field of
// a TargetingOption when targeting_type
// is
// `TARGETING_TYPE_HOUSEHOLD_INCOME`.
type HouseholdIncomeTargetingOptionDetails struct {
	// HouseholdIncome: Output only. The household income of an audience.
	//
	// Possible values:
	//   "HOUSEHOLD_INCOME_UNSPECIFIED" - Default value when household
	// income is not specified in this version. This
	// enum is a placeholder for default value and does not represent a
	// real
	// household income option.
	//   "HOUSEHOLD_INCOME_UNKNOWN" - The household income of the audience
	// is unknown.
	//   "HOUSEHOLD_INCOME_LOWER_50_PERCENT" - The audience is in the lower
	// 50% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_41_TO_50_PERCENT" - The audience is in the
	// top 41-50% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_31_TO_40_PERCENT" - The audience is in the
	// top 31-40% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_21_TO_30_PERCENT" - The audience is in the
	// top 21-30% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_11_TO_20_PERCENT" - The audience is in the
	// top 11-20% of U.S. household incomes.
	//   "HOUSEHOLD_INCOME_TOP_10_PERCENT" - The audience is in the top 10%
	// of U.S. household incomes.
	HouseholdIncome string `json:"householdIncome,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HouseholdIncome") 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. "HouseholdIncome") 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 *HouseholdIncomeTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod HouseholdIncomeTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IdFilter: A filtering option that filters entities by their entity
// IDs.
type IdFilter struct {
	// AdGroupAdIds: TrueView Ads to download by ID. All IDs must belong to
	// the same
	// Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest.
	AdGroupAdIds googleapi.Int64s `json:"adGroupAdIds,omitempty"`

	// AdGroupIds: TrueView Ad Groups to download by ID. All IDs must belong
	// to the same
	// Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest.
	AdGroupIds googleapi.Int64s `json:"adGroupIds,omitempty"`

	// CampaignIds: Campaigns to download by ID. All IDs must belong to the
	// same
	// Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest.
	CampaignIds googleapi.Int64s `json:"campaignIds,omitempty"`

	// InsertionOrderIds: Insertion Orders to download by ID. All IDs must
	// belong to the same
	// Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest.
	InsertionOrderIds googleapi.Int64s `json:"insertionOrderIds,omitempty"`

	// LineItemIds: Line Items to download by ID. All IDs must belong to the
	// same
	// Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest.
	LineItemIds googleapi.Int64s `json:"lineItemIds,omitempty"`

	// MediaProductIds: Media Products to download by ID. All IDs must
	// belong to the same
	// Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest.
	MediaProductIds googleapi.Int64s `json:"mediaProductIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdGroupAdIds") 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. "AdGroupAdIds") 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 *IdFilter) MarshalJSON() ([]byte, error) {
	type NoMethod IdFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertionOrder: A single insertion order.
type InsertionOrder struct {
	// AdvertiserId: Output only. The unique ID of the advertiser the
	// insertion order belongs to.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// BidStrategy: Optional. The bidding strategy of the insertion order.
	// By default,
	// fixed_bid is set.
	BidStrategy *BiddingStrategy `json:"bidStrategy,omitempty"`

	// Budget: Required. The budget allocation settings of the insertion
	// order.
	Budget *InsertionOrderBudget `json:"budget,omitempty"`

	// CampaignId: Required. Immutable. The unique ID of the campaign that
	// the insertion order belongs to.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// DisplayName: Required. The display name of the insertion order.
	//
	// Must be UTF-8 encoded with a maximum size of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// EntityStatus: Required. Controls whether or not the insertion order
	// can spend its budget
	// and bid on inventory.
	//
	// * For
	// CreateInsertionOrder method,
	// only `ENTITY_STATUS_DRAFT` is allowed. To activate an insertion
	// order, use
	// UpdateInsertionOrder method
	// and update the status to `ENTITY_STATUS_ACTIVE` after creation.
	// * An insertion order cannot be changed back to `ENTITY_STATUS_DRAFT`
	// status
	// from any other status.
	// * An insertion order cannot be set to `ENTITY_STATUS_ACTIVE` if its
	// parent
	// campaign is not active.
	//
	// Possible values:
	//   "ENTITY_STATUS_UNSPECIFIED" - Default value when status is not
	// specified or is unknown in this version.
	//   "ENTITY_STATUS_ACTIVE" - The entity is enabled to bid and spend
	// budget.
	//   "ENTITY_STATUS_ARCHIVED" - The entity is archived. Bidding and
	// budget spending are disabled. An
	// entity can be deleted after archived. Deleted entities cannot be
	// retrieved.
	//   "ENTITY_STATUS_DRAFT" - The entity is under draft. Bidding and
	// budget spending are disabled.
	//   "ENTITY_STATUS_PAUSED" - Bidding and budget spending are paused for
	// the entity.
	//   "ENTITY_STATUS_SCHEDULED_FOR_DELETION" - The entity is scheduled
	// for deletion.
	EntityStatus string `json:"entityStatus,omitempty"`

	// FrequencyCap: Required. The frequency capping setting of the
	// insertion order.
	FrequencyCap *FrequencyCap `json:"frequencyCap,omitempty"`

	// InsertionOrderId: Output only. The unique ID of the insertion order.
	// Assigned by the system.
	InsertionOrderId int64 `json:"insertionOrderId,omitempty,string"`

	// IntegrationDetails: Additional integration details of the insertion
	// order.
	IntegrationDetails *IntegrationDetails `json:"integrationDetails,omitempty"`

	// Name: Output only. The resource name of the insertion order.
	Name string `json:"name,omitempty"`

	// Pacing: Required. The budget spending speed setting of the insertion
	// order.
	Pacing *Pacing `json:"pacing,omitempty"`

	// PartnerCosts: The partner costs associated with the insertion
	// order.
	//
	// If absent or empty in
	// CreateInsertionOrder
	// method, the newly created insertion order will inherit partner costs
	// from
	// the partner settings.
	PartnerCosts []*PartnerCost `json:"partnerCosts,omitempty"`

	// PerformanceGoal: Required. Performance goal of the insertion order.
	PerformanceGoal *PerformanceGoal `json:"performanceGoal,omitempty"`

	// UpdateTime: Output only. The timestamp when the insertion order was
	// last updated.
	// Assigned by the system.
	UpdateTime string `json:"updateTime,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "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 *InsertionOrder) MarshalJSON() ([]byte, error) {
	type NoMethod InsertionOrder
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertionOrderBudget: Settings that control how insertion order
// budget is allocated.
type InsertionOrderBudget struct {
	// AutomationType: The type of automation used to manage bid and budget
	// for
	// the insertion order.
	//
	// If this field is unspecified in creation, the value defaults
	// to
	// `INSERTION_ORDER_AUTOMATION_TYPE_NONE`.
	//
	// Possible values:
	//   "INSERTION_ORDER_AUTOMATION_TYPE_UNSPECIFIED" - Insertion order
	// automation option is not specified or is unknown in
	// this version.
	//   "INSERTION_ORDER_AUTOMATION_TYPE_BUDGET" - Automatic budget
	// allocation. Allow the system to automatically shift
	// budget to owning line items to optimize performance defined
	// by
	// performance_goal. No automation
	// on bid settings.
	//   "INSERTION_ORDER_AUTOMATION_TYPE_NONE" - No automation of bid or
	// budget on insertion order level.
	// Bid and budget must be manually configured at the line item level.
	//   "INSERTION_ORDER_AUTOMATION_TYPE_BID_BUDGET" - Allow the system to
	// automatically adjust bids and shift budget to
	// owning line items to optimize performance defined
	// by
	// performance_goal.
	AutomationType string `json:"automationType,omitempty"`

	// BudgetSegments: Required. The list of budget segments. Use a budget
	// segment to specify
	// a specific budget for a given period of time an insertion order is
	// running.
	BudgetSegments []*InsertionOrderBudgetSegment `json:"budgetSegments,omitempty"`

	// BudgetUnit: Required. Immutable. The budget unit specifies whether
	// the budget is currency based or
	// impression based.
	//
	// Possible values:
	//   "BUDGET_UNIT_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "BUDGET_UNIT_CURRENCY" - Budgeting in currency amounts.
	//   "BUDGET_UNIT_IMPRESSIONS" - Budgeting in impression amounts.
	BudgetUnit string `json:"budgetUnit,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutomationType") 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. "AutomationType") 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 *InsertionOrderBudget) MarshalJSON() ([]byte, error) {
	type NoMethod InsertionOrderBudget
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertionOrderBudgetSegment: Settings that control the budget of a
// single budget segment.
type InsertionOrderBudgetSegment struct {
	// BudgetAmountMicros: Required. The budget amount the insertion order
	// will spend for the given
	// date_range.
	// The amount is in micros. Must be greater than 0. For example,
	// 500000000
	// represents 500 standard units of the currency.
	BudgetAmountMicros int64 `json:"budgetAmountMicros,omitempty,string"`

	// CampaignBudgetId: The ID of the campaign budget linked to this
	// insertion order budget
	// segment.
	CampaignBudgetId int64 `json:"campaignBudgetId,omitempty,string"`

	// DateRange: Required. The start and end date settings of the budget
	// segment. They are resolved
	// relative to the parent advertiser's time zone.
	//
	// * When creating a new budget segment, both `start_date` and
	// `end_date`
	// must be in the future.
	// * An existing budget segment with a `start_date` in the past has a
	// mutable
	// `end_date` but an immutable `start_date`.
	// * `end_date` must be the `start_date` or later, both before the year
	// 2037.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Description: The budget segment description. It can be used to enter
	// Purchase Order
	// information for each budget segment and have that information printed
	// on
	// the invoices.
	//
	// Must be UTF-8 encoded with a length of no more than 80 characters.
	Description string `json:"description,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BudgetAmountMicros")
	// 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. "BudgetAmountMicros") 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 *InsertionOrderBudgetSegment) MarshalJSON() ([]byte, error) {
	type NoMethod InsertionOrderBudgetSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IntegralAdScience: Details of Integral Ad Science settings.
type IntegralAdScience struct {
	// DisplayViewability: Display Viewability section (applicable to
	// display line items only).
	//
	// Possible values:
	//   "PERFORMANCE_VIEWABILITY_UNSPECIFIED" - This enum is only a
	// placeholder and it doesn't specify any display
	// viewability options.
	//   "PERFORMANCE_VIEWABILITY_40" - Target 40% Viewability or Higher.
	//   "PERFORMANCE_VIEWABILITY_50" - Target 50% Viewability or Higher.
	//   "PERFORMANCE_VIEWABILITY_60" - Target 60% Viewability or Higher.
	//   "PERFORMANCE_VIEWABILITY_70" - Target 70% Viewability or Higher.
	DisplayViewability string `json:"displayViewability,omitempty"`

	// ExcludeUnrateable: Brand Safety - **Unrateable**.
	ExcludeUnrateable bool `json:"excludeUnrateable,omitempty"`

	// ExcludedAdFraudRisk: Ad Fraud settings.
	//
	// Possible values:
	//   "SUSPICIOUS_ACTIVITY_UNSPECIFIED" - This enum is only a placeholder
	// and it doesn't specify any ad fraud
	// prevention options.
	//   "SUSPICIOUS_ACTIVITY_HR" - Ad Fraud - Exclude High Risk.
	//   "SUSPICIOUS_ACTIVITY_HMR" - Ad Fraud - Exclude High and Moderate
	// Risk.
	ExcludedAdFraudRisk string `json:"excludedAdFraudRisk,omitempty"`

	// ExcludedAdultRisk: Brand Safety - **Adult content**.
	//
	// Possible values:
	//   "ADULT_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any adult options.
	//   "ADULT_HR" - Adult - Exclude High Risk.
	//   "ADULT_HMR" - Adult - Exclude High and Moderate Risk.
	ExcludedAdultRisk string `json:"excludedAdultRisk,omitempty"`

	// ExcludedAlcoholRisk: Brand Safety - **Alcohol**.
	//
	// Possible values:
	//   "ALCOHOL_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any alcohol
	// options.
	//   "ALCOHOL_HR" - Alcohol - Exclude High Risk.
	//   "ALCOHOL_HMR" - Alcohol - Exclude High and Moderate Risk.
	ExcludedAlcoholRisk string `json:"excludedAlcoholRisk,omitempty"`

	// ExcludedDrugsRisk: Brand Safety - **Drugs**.
	//
	// Possible values:
	//   "DRUGS_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any drugs options.
	//   "DRUGS_HR" - Drugs - Exclude High Risk.
	//   "DRUGS_HMR" - Drugs - Exclude High and Moderate Risk.
	ExcludedDrugsRisk string `json:"excludedDrugsRisk,omitempty"`

	// ExcludedGamblingRisk: Brand Safety - **Gambling**.
	//
	// Possible values:
	//   "GAMBLING_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any gambling
	// options.
	//   "GAMBLING_HR" - Gambling - Exclude High Risk.
	//   "GAMBLING_HMR" - Gambling - Exclude High and Moderate Risk.
	ExcludedGamblingRisk string `json:"excludedGamblingRisk,omitempty"`

	// ExcludedHateSpeechRisk: Brand Safety - **Hate speech**.
	//
	// Possible values:
	//   "HATE_SPEECH_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any hate speech
	// options.
	//   "HATE_SPEECH_HR" - Hate Speech - Exclude High Risk.
	//   "HATE_SPEECH_HMR" - Hate Speech - Exclude High and Moderate Risk.
	ExcludedHateSpeechRisk string `json:"excludedHateSpeechRisk,omitempty"`

	// ExcludedIllegalDownloadsRisk: Brand Safety - **Illegal downloads**.
	//
	// Possible values:
	//   "ILLEGAL_DOWNLOADS_UNSPECIFIED" - This enum is only a placeholder
	// and it doesn't specify any illegal
	// downloads options.
	//   "ILLEGAL_DOWNLOADS_HR" - Illegal Downloads - Exclude High Risk.
	//   "ILLEGAL_DOWNLOADS_HMR" - Illegal Downloads - Exclude High and
	// Moderate Risk.
	ExcludedIllegalDownloadsRisk string `json:"excludedIllegalDownloadsRisk,omitempty"`

	// ExcludedOffensiveLanguageRisk: Brand Safety - **Offensive language**.
	//
	// Possible values:
	//   "OFFENSIVE_LANGUAGE_UNSPECIFIED" - This enum is only a placeholder
	// and it doesn't specify any language
	// options.
	//   "OFFENSIVE_LANGUAGE_HR" - Offensive Language - Exclude High Risk.
	//   "OFFENSIVE_LANGUAGE_HMR" - Offensive Language - Exclude High and
	// Moderate Risk.
	ExcludedOffensiveLanguageRisk string `json:"excludedOffensiveLanguageRisk,omitempty"`

	// ExcludedViolenceRisk: Brand Safety - **Violence**.
	//
	// Possible values:
	//   "VIOLENCE_UNSPECIFIED" - This enum is only a placeholder and it
	// doesn't specify any violence
	// options.
	//   "VIOLENCE_HR" - Violence - Exclude High Risk.
	//   "VIOLENCE_HMR" - Violence - Exclude High and Moderate Risk.
	ExcludedViolenceRisk string `json:"excludedViolenceRisk,omitempty"`

	// TraqScoreOption: True advertising quality (applicable to Display line
	// items only).
	//
	// Possible values:
	//   "TRAQ_UNSPECIFIED" - This enum is only a placeholder and it doesn't
	// specify any true
	// advertising quality scores.
	//   "TRAQ_250" - TRAQ score 250-1000.
	//   "TRAQ_500" - TRAQ score 500-1000.
	//   "TRAQ_600" - TRAQ score 600-1000.
	//   "TRAQ_700" - TRAQ score 700-1000.
	//   "TRAQ_750" - TRAQ score 750-1000.
	//   "TRAQ_875" - TRAQ score 875-1000.
	//   "TRAQ_1000" - TRAQ score 1000.
	TraqScoreOption string `json:"traqScoreOption,omitempty"`

	// VideoViewability: Video Viewability Section (applicable to video line
	// items only).
	//
	// Possible values:
	//   "VIDEO_VIEWABILITY_UNSPECIFIED" - This enum is only a placeholder
	// and it doesn't specify any video
	// viewability options.
	//   "VIDEO_VIEWABILITY_40" - 40%+ in view (IAB video viewability
	// standard).
	//   "VIDEO_VIEWABILITY_50" - 50%+ in view (IAB video viewability
	// standard).
	//   "VIDEO_VIEWABILITY_60" - 60%+ in view (IAB video viewability
	// standard).
	//   "VIDEO_VIEWABILITY_70" - 70%+ in view (IAB video viewability
	// standard).
	VideoViewability string `json:"videoViewability,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayViewability")
	// 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. "DisplayViewability") 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 *IntegralAdScience) MarshalJSON() ([]byte, error) {
	type NoMethod IntegralAdScience
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IntegrationDetails: Integration details of an entry.
type IntegrationDetails struct {
	// Details: Additional details of the entry in string format.
	//
	// Must be UTF-8 encoded with a length of no more than 1000 characters.
	Details string `json:"details,omitempty"`

	// IntegrationCode: An external identifier to be associated with the
	// entry.
	// The integration code will show up together with the entry in
	// many
	// places in the system, for example, reporting.
	//
	// Must be UTF-8 encoded with a length of no more than 500 characters.
	IntegrationCode string `json:"integrationCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Details") 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. "Details") 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 *IntegrationDetails) MarshalJSON() ([]byte, error) {
	type NoMethod IntegrationDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InventorySource: An inventory source.
type InventorySource struct {
	// Commitment: Whether the inventory source has a guaranteed or
	// non-guaranteed delivery.
	//
	// Possible values:
	//   "INVENTORY_SOURCE_COMMITMENT_UNSPECIFIED" - The commitment is not
	// specified or is unknown in this version.
	//   "INVENTORY_SOURCE_COMMITMENT_GUARANTEED" - The commitment is
	// guaranteed delivery.
	//   "INVENTORY_SOURCE_COMMITMENT_NON_GUARANTEED" - The commitment is
	// non-guaranteed delivery.
	Commitment string `json:"commitment,omitempty"`

	// CreativeConfigs: The creative requirements of the inventory
	// source.
	//
	// Not applicable for auction packages.
	CreativeConfigs []*CreativeConfig `json:"creativeConfigs,omitempty"`

	// DealId: The ID in the exchange space that uniquely identifies the
	// inventory source.
	//
	// Must be unique across buyers within each exchange but not
	// necessarily
	// unique across exchanges.
	DealId string `json:"dealId,omitempty"`

	// DeliveryMethod: The delivery method of the inventory source.
	//
	// * For non-guaranteed inventory sources, the only acceptable value
	// is
	// `INVENTORY_SOURCE_DELIVERY_METHOD_PROGRAMMATIC`.
	// * For guaranteed inventory sources, acceptable values
	// are
	// `INVENTORY_SOURCE_DELIVERY_METHOD_TAG`
	// and
	// `INVENTORY_SOURCE_DELIVERY_METHOD_PROGRAMMATIC`.
	//
	// Possible values:
	//   "INVENTORY_SOURCE_DELIVERY_METHOD_UNSPECIFIED" - The delivery
	// method is not specified or is unknown in this version.
	//   "INVENTORY_SOURCE_DELIVERY_METHOD_PROGRAMMATIC" - The delivery
	// method is programmatic.
	//   "INVENTORY_SOURCE_DELIVERY_METHOD_TAG" - The delivery method is
	// tag.
	DeliveryMethod string `json:"deliveryMethod,omitempty"`

	// DisplayName: The display name of the inventory source.
	//
	// Must be UTF-8 encoded with a maximum size of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// Exchange: The exchange to which the inventory source belongs.
	//
	// Possible values:
	//   "EXCHANGE_UNSPECIFIED" - Exchange is not specified or is unknown in
	// this version.
	//   "EXCHANGE_GOOGLE_AD_MANAGER" - Google Ad Manager.
	//   "EXCHANGE_APPNEXUS" - AppNexus.
	//   "EXCHANGE_BRIGHTROLL" - BrightRoll Exchange for Video from Yahoo!.
	//   "EXCHANGE_ADFORM" - Adform.
	//   "EXCHANGE_ADMETA" - Admeta.
	//   "EXCHANGE_ADMIXER" - Admixer.
	//   "EXCHANGE_ADSMOGO" - AdsMogo.
	//   "EXCHANGE_ADSWIZZ" - AdsWizz.
	//   "EXCHANGE_BIDSWITCH" - BidSwitch.
	//   "EXCHANGE_BRIGHTROLL_DISPLAY" - BrightRoll Exchange for Display
	// from Yahoo!.
	//   "EXCHANGE_CADREON" - Cadreon.
	//   "EXCHANGE_DAILYMOTION" - Dailymotion.
	//   "EXCHANGE_FIVE" - Five.
	//   "EXCHANGE_FLUCT" - Fluct.
	//   "EXCHANGE_FREEWHEEL" - FreeWheel SSP.
	//   "EXCHANGE_GENIEE" - Geniee.
	//   "EXCHANGE_GUMGUM" - GumGum.
	//   "EXCHANGE_IMOBILE" - i-mobile.
	//   "EXCHANGE_IBILLBOARD" - iBILLBOARD.
	//   "EXCHANGE_IMPROVE_DIGITAL" - Improve Digital.
	//   "EXCHANGE_INDEX" - Index Exchange.
	//   "EXCHANGE_KARGO" - Kargo.
	//   "EXCHANGE_MICROAD" - MicroAd.
	//   "EXCHANGE_MOPUB" - MoPub.
	//   "EXCHANGE_NEND" - Nend.
	//   "EXCHANGE_ONE_BY_AOL_DISPLAY" - ONE by AOL: Display Market Place.
	//   "EXCHANGE_ONE_BY_AOL_MOBILE" - ONE by AOL: Mobile.
	//   "EXCHANGE_ONE_BY_AOL_VIDEO" - ONE by AOL: Video.
	//   "EXCHANGE_OOYALA" - Ooyala.
	//   "EXCHANGE_OPENX" - OpenX.
	//   "EXCHANGE_PERMODO" - Permodo.
	//   "EXCHANGE_PLATFORMONE" - Platform One.
	//   "EXCHANGE_PLATFORMID" - PlatformId.
	//   "EXCHANGE_PUBMATIC" - PubMatic.
	//   "EXCHANGE_PULSEPOINT" - PulsePoint.
	//   "EXCHANGE_REVENUEMAX" - RevenueMax.
	//   "EXCHANGE_RUBICON" - Rubicon.
	//   "EXCHANGE_SMARTCLIP" - SmartClip.
	//   "EXCHANGE_SMARTRTB" - SmartRTB+.
	//   "EXCHANGE_SMARTSTREAMTV" - SmartstreamTv.
	//   "EXCHANGE_SOVRN" - Sovrn.
	//   "EXCHANGE_SPOTXCHANGE" - SpotXchange.
	//   "EXCHANGE_STROER" - Ströer SSP.
	//   "EXCHANGE_TEADSTV" - TeadsTv.
	//   "EXCHANGE_TELARIA" - Telaria.
	//   "EXCHANGE_TVN" - TVN.
	//   "EXCHANGE_UNITED" - United.
	//   "EXCHANGE_YIELDLAB" - Yieldlab.
	//   "EXCHANGE_YIELDMO" - Yieldmo.
	//   "EXCHANGE_TRIPLELIFT" - TripleLift
	//   "EXCHANGE_TABOOLA" - Taboola
	//   "EXCHANGE_INMOBI" - InMobi.
	//   "EXCHANGE_SMAATO" - Smaato
	//   "EXCHANGE_AJA" - Aja.
	//   "EXCHANGE_NEXSTAR_DIGITAL" - Nexstar Digital.
	//   "EXCHANGE_WAZE" - Waze.
	Exchange string `json:"exchange,omitempty"`

	// InventorySourceId: Output only. The unique ID of the inventory
	// source. Assigned by the system.
	InventorySourceId int64 `json:"inventorySourceId,omitempty,string"`

	// InventorySourceType: Denotes the type of the inventory source.
	//
	// Possible values:
	//   "INVENTORY_SOURCE_TYPE_UNSPECIFIED" - The inventory source type is
	// not specified or is unknown in this version.
	//   "INVENTORY_SOURCE_TYPE_PRIVATE" - Private inventory source.
	//   "INVENTORY_SOURCE_TYPE_AUCTION_PACKAGE" - Auction package.
	InventorySourceType string `json:"inventorySourceType,omitempty"`

	// Name: Output only. The resource name of the inventory source.
	Name string `json:"name,omitempty"`

	// PublisherName: The publisher/seller name of the inventory source.
	PublisherName string `json:"publisherName,omitempty"`

	// RateDetails: Required. The rate details of the inventory source.
	RateDetails *RateDetails `json:"rateDetails,omitempty"`

	// Status: The status settings of the inventory source.
	Status *InventorySourceStatus `json:"status,omitempty"`

	// TimeRange: The time range when this inventory source starts and stops
	// serving.
	TimeRange *TimeRange `json:"timeRange,omitempty"`

	// UpdateTime: Output only. The timestamp when the inventory source was
	// last updated. Assigned by the
	// system.
	UpdateTime string `json:"updateTime,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Commitment") 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. "Commitment") 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 *InventorySource) MarshalJSON() ([]byte, error) {
	type NoMethod InventorySource
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InventorySourceAssignedTargetingOptionDetails: Targeting details for
// inventory source. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_INVENTORY_SOURCE`.
type InventorySourceAssignedTargetingOptionDetails struct {
	// InventorySourceId: Required. ID of the inventory source. Should refer
	// to the
	// inventory_source_id field of an
	// InventorySource resource.
	InventorySourceId int64 `json:"inventorySourceId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "InventorySourceId")
	// 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. "InventorySourceId") 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 *InventorySourceAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod InventorySourceAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InventorySourceDisplayCreativeConfig: The configuration for display
// creatives.
type InventorySourceDisplayCreativeConfig struct {
	// CreativeSize: The size requirements for display creatives that can be
	// assigned to the
	// inventory source.
	CreativeSize *Dimensions `json:"creativeSize,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreativeSize") 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. "CreativeSize") 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 *InventorySourceDisplayCreativeConfig) MarshalJSON() ([]byte, error) {
	type NoMethod InventorySourceDisplayCreativeConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InventorySourceFilter: A filtering option for filtering on Inventory
// Source entities.
type InventorySourceFilter struct {
	// InventorySourceIds: Inventory Sources to download by ID. All IDs must
	// belong to the same
	// Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest. Leave empty to download all
	// Inventory
	// Sources for the selected Advertiser or Partner.
	InventorySourceIds googleapi.Int64s `json:"inventorySourceIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InventorySourceIds")
	// 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. "InventorySourceIds") 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 *InventorySourceFilter) MarshalJSON() ([]byte, error) {
	type NoMethod InventorySourceFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InventorySourceGroup: A collection of targetable inventory sources.
type InventorySourceGroup struct {
	// DisplayName: Required. The display name of the inventory source
	// group.
	//
	// Must be UTF-8 encoded with a maximum size of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// InventorySourceGroupId: Output only. The unique ID of the inventory
	// source group. Assigned by the system.
	InventorySourceGroupId int64 `json:"inventorySourceGroupId,omitempty,string"`

	// Name: Output only. The resource name of the inventory source group.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "DisplayName") 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 *InventorySourceGroup) MarshalJSON() ([]byte, error) {
	type NoMethod InventorySourceGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InventorySourceGroupAssignedTargetingOptionDetails: Targeting details
// for inventory source group. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_INVENTORY_SOURCE_GROUP`.
type InventorySourceGroupAssignedTargetingOptionDetails struct {
	// InventorySourceGroupId: Required. ID of the inventory source group.
	// Should refer to the
	// inventory_source_group_id
	// field of an InventorySourceGroup resource.
	InventorySourceGroupId int64 `json:"inventorySourceGroupId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "InventorySourceGroupId") 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. "InventorySourceGroupId")
	// 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 *InventorySourceGroupAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod InventorySourceGroupAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InventorySourceStatus: The status related settings of the inventory
// source.
type InventorySourceStatus struct {
	// ConfigStatus: Output only. The configuration status of the inventory
	// source.
	//
	// Only applicable for guaranteed inventory sources.
	// Acceptable values are `INVENTORY_SOURCE_CONFIG_STATUS_PENDING`
	// and
	// `INVENTORY_SOURCE_CONFIG_STATUS_COMPLETED`.
	//
	// An inventory source must be configured (fill in the required fields,
	// choose
	// creatives, and select a default campaign) before it can serve.
	//
	// Possible values:
	//   "INVENTORY_SOURCE_CONFIG_STATUS_UNSPECIFIED" - The approval status
	// is not specified or is unknown in this version.
	//   "INVENTORY_SOURCE_CONFIG_STATUS_PENDING" - The beginning state of a
	// guaranteed inventory source. The inventory
	// source in this state needs to be configured.
	//   "INVENTORY_SOURCE_CONFIG_STATUS_COMPLETED" - The state after the
	// buyer configures a guaranteed inventory source.
	ConfigStatus string `json:"configStatus,omitempty"`

	// EntityPauseReason: The user-provided reason for pausing this
	// inventory source.
	//
	// Must not exceed 100 characters.
	//
	// Only applicable when entity_status
	// is set to `ENTITY_STATUS_PAUSED`.
	EntityPauseReason string `json:"entityPauseReason,omitempty"`

	// EntityStatus: Whether or not the inventory source is
	// servable.
	//
	// Acceptable values are `ENTITY_STATUS_ACTIVE`,
	// `ENTITY_STATUS_ARCHIVED`, and
	// `ENTITY_STATUS_PAUSED`.
	// Default value is `ENTITY_STATUS_ACTIVE`.
	//
	// Possible values:
	//   "ENTITY_STATUS_UNSPECIFIED" - Default value when status is not
	// specified or is unknown in this version.
	//   "ENTITY_STATUS_ACTIVE" - The entity is enabled to bid and spend
	// budget.
	//   "ENTITY_STATUS_ARCHIVED" - The entity is archived. Bidding and
	// budget spending are disabled. An
	// entity can be deleted after archived. Deleted entities cannot be
	// retrieved.
	//   "ENTITY_STATUS_DRAFT" - The entity is under draft. Bidding and
	// budget spending are disabled.
	//   "ENTITY_STATUS_PAUSED" - Bidding and budget spending are paused for
	// the entity.
	//   "ENTITY_STATUS_SCHEDULED_FOR_DELETION" - The entity is scheduled
	// for deletion.
	EntityStatus string `json:"entityStatus,omitempty"`

	// SellerPauseReason: Output only. The seller-provided reason for
	// pausing this inventory source.
	//
	// Only applicable for inventory sources synced directly from
	// the
	// publishers and when seller_status
	// is set to `ENTITY_STATUS_PAUSED`.
	SellerPauseReason string `json:"sellerPauseReason,omitempty"`

	// SellerStatus: Output only. The status set by the seller for the
	// inventory source.
	//
	// Only applicable for inventory sources synced directly from
	// the
	// publishers.
	// Acceptable values are `ENTITY_STATUS_ACTIVE` and
	// `ENTITY_STATUS_PAUSED`.
	//
	// Possible values:
	//   "ENTITY_STATUS_UNSPECIFIED" - Default value when status is not
	// specified or is unknown in this version.
	//   "ENTITY_STATUS_ACTIVE" - The entity is enabled to bid and spend
	// budget.
	//   "ENTITY_STATUS_ARCHIVED" - The entity is archived. Bidding and
	// budget spending are disabled. An
	// entity can be deleted after archived. Deleted entities cannot be
	// retrieved.
	//   "ENTITY_STATUS_DRAFT" - The entity is under draft. Bidding and
	// budget spending are disabled.
	//   "ENTITY_STATUS_PAUSED" - Bidding and budget spending are paused for
	// the entity.
	//   "ENTITY_STATUS_SCHEDULED_FOR_DELETION" - The entity is scheduled
	// for deletion.
	SellerStatus string `json:"sellerStatus,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ConfigStatus") 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. "ConfigStatus") 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 *InventorySourceStatus) MarshalJSON() ([]byte, error) {
	type NoMethod InventorySourceStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InventorySourceVideoCreativeConfig: The configuration for video
// creatives.
type InventorySourceVideoCreativeConfig struct {
	// Duration: The duration requirements for the video creatives that can
	// be assigned to
	// the inventory source.
	Duration string `json:"duration,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 *InventorySourceVideoCreativeConfig) MarshalJSON() ([]byte, error) {
	type NoMethod InventorySourceVideoCreativeConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// KeywordAssignedTargetingOptionDetails: Details for assigned keyword
// targeting option. This will be populated in the
// details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_KEYWORD`.
type KeywordAssignedTargetingOptionDetails struct {
	// Keyword: Required. The keyword, for example `car
	// insurance`.
	//
	// Positive keyword cannot be offensive word.
	// Must be UTF-8 encoded with a maximum size of 255 bytes. Maximum
	// number
	// of characters is 80. Maximum number of words is 10.
	Keyword string `json:"keyword,omitempty"`

	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Keyword") 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. "Keyword") 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 *KeywordAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod KeywordAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LanguageAssignedTargetingOptionDetails: Details for assigned language
// targeting option. This will be populated in the
// details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_LANGUAGE`.
type LanguageAssignedTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the language (e.g.,
	// "French").
	DisplayName string `json:"displayName,omitempty"`

	// Negative: Indicates if this option is being negatively targeted. All
	// assigned
	// language targeting options on the same line item must have the same
	// value
	// for this field.
	Negative bool `json:"negative,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_LANGUAGE`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *LanguageAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod LanguageAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LanguageTargetingOptionDetails: Represents a targetable language.
// This will be populated in the
// language_details field when
// targeting_type is
// `TARGETING_TYPE_LANGUAGE`.
type LanguageTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the language (e.g.,
	// "French").
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *LanguageTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod LanguageTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineItem: A single line item.
type LineItem struct {
	// AdvertiserId: Output only. The unique ID of the advertiser the line
	// item belongs to.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// BidStrategy: Required. The bidding strategy of the line item.
	BidStrategy *BiddingStrategy `json:"bidStrategy,omitempty"`

	// Budget: Required. The budget allocation setting of the line item.
	Budget *LineItemBudget `json:"budget,omitempty"`

	// CampaignId: Output only. The unique ID of the campaign that the line
	// item belongs to.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// ConversionCounting: The conversion tracking setting of the line item.
	ConversionCounting *ConversionCountingConfig `json:"conversionCounting,omitempty"`

	// CreativeIds: The IDs of the creatives associated with the line item.
	CreativeIds googleapi.Int64s `json:"creativeIds,omitempty"`

	// DisplayName: Required. The display name of the line item.
	//
	// Must be UTF-8 encoded with a maximum size of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// EntityStatus: Required. Controls whether or not the line item can
	// spend its budget and
	// bid on inventory.
	//
	// * For CreateLineItem method, only
	// `ENTITY_STATUS_DRAFT` is allowed. To activate a line item,
	// use
	// UpdateLineItem method and update the
	// status to `ENTITY_STATUS_ACTIVE` after creation.
	// * A line item cannot be changed back to `ENTITY_STATUS_DRAFT` status
	// from
	// any other status.
	// * If the line item's parent insertion order is not active, the line
	// item
	// can't spend its budget even if its own status is
	// `ENTITY_STATUS_ACTIVE`.
	//
	// Possible values:
	//   "ENTITY_STATUS_UNSPECIFIED" - Default value when status is not
	// specified or is unknown in this version.
	//   "ENTITY_STATUS_ACTIVE" - The entity is enabled to bid and spend
	// budget.
	//   "ENTITY_STATUS_ARCHIVED" - The entity is archived. Bidding and
	// budget spending are disabled. An
	// entity can be deleted after archived. Deleted entities cannot be
	// retrieved.
	//   "ENTITY_STATUS_DRAFT" - The entity is under draft. Bidding and
	// budget spending are disabled.
	//   "ENTITY_STATUS_PAUSED" - Bidding and budget spending are paused for
	// the entity.
	//   "ENTITY_STATUS_SCHEDULED_FOR_DELETION" - The entity is scheduled
	// for deletion.
	EntityStatus string `json:"entityStatus,omitempty"`

	// Flight: Required. The start and end time of the line item's flight.
	Flight *LineItemFlight `json:"flight,omitempty"`

	// FrequencyCap: Required. The frequency capping setting of the line
	// item.
	FrequencyCap *FrequencyCap `json:"frequencyCap,omitempty"`

	// InsertionOrderId: Required. Immutable. The unique ID of the insertion
	// order that the line item belongs to.
	InsertionOrderId int64 `json:"insertionOrderId,omitempty,string"`

	// IntegrationDetails: Integration details of the line item.
	IntegrationDetails *IntegrationDetails `json:"integrationDetails,omitempty"`

	// InventorySourceIds: The IDs of the private inventory sources assigned
	// to the line item.
	InventorySourceIds googleapi.Int64s `json:"inventorySourceIds,omitempty"`

	// LineItemId: Output only. The unique ID of the line item. Assigned by
	// the system.
	LineItemId int64 `json:"lineItemId,omitempty,string"`

	// LineItemType: Required. Immutable. The type of the line item.
	//
	// Possible values:
	//   "LINE_ITEM_TYPE_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "LINE_ITEM_TYPE_DISPLAY_DEFAULT" - Image, HTML5, native, or rich
	// media ads.
	//   "LINE_ITEM_TYPE_DISPLAY_MOBILE_APP_INSTALL" - Display ads that
	// drive installs of an app.
	//   "LINE_ITEM_TYPE_VIDEO_DEFAULT" - Video ads sold on a CPM basis for
	// a variety of environments.
	//   "LINE_ITEM_TYPE_VIDEO_MOBILE_APP_INSTALL" - Video ads that drive
	// installs of an app.
	//   "LINE_ITEM_TYPE_DISPLAY_MOBILE_APP_INVENTORY" - Display ads served
	// on mobile app inventory.
	//   "LINE_ITEM_TYPE_VIDEO_MOBILE_APP_INVENTORY" - Video ads served on
	// mobile app inventory.
	LineItemType string `json:"lineItemType,omitempty"`

	// Name: Output only. The resource name of the line item.
	Name string `json:"name,omitempty"`

	// Pacing: Required. The budget spending speed setting of the line item.
	Pacing *Pacing `json:"pacing,omitempty"`

	// PartnerCosts: The partner costs associated with the line item.
	//
	// If absent or empty in CreateLineItem
	// method, the newly created line item will inherit partner costs from
	// its
	// parent insertion order.
	PartnerCosts []*PartnerCost `json:"partnerCosts,omitempty"`

	// PartnerRevenueModel: Required. The partner revenue model setting of
	// the line item.
	PartnerRevenueModel *PartnerRevenueModel `json:"partnerRevenueModel,omitempty"`

	// UpdateTime: Output only. The timestamp when the line item was last
	// updated. Assigned by the system.
	UpdateTime string `json:"updateTime,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "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 *LineItem) MarshalJSON() ([]byte, error) {
	type NoMethod LineItem
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineItemBudget: Settings that control how budget is allocated.
type LineItemBudget struct {
	// BudgetAllocationType: Required. The type of the budget
	// allocation.
	//
	// `LINE_ITEM_BUDGET_ALLOCATION_TYPE_AUTOMATIC` is only applicable
	// when
	// automatic budget allocation is enabled for the parent insertion
	// order.
	//
	// Possible values:
	//   "LINE_ITEM_BUDGET_ALLOCATION_TYPE_UNSPECIFIED" - Type value is not
	// specified or is unknown in this version.
	//   "LINE_ITEM_BUDGET_ALLOCATION_TYPE_AUTOMATIC" - Automatic budget
	// allocation is enabled for the line item.
	//   "LINE_ITEM_BUDGET_ALLOCATION_TYPE_FIXED" - A fixed max budget
	// amount is allocated for the line item.
	//   "LINE_ITEM_BUDGET_ALLOCATION_TYPE_UNLIMITED" - No budget limit is
	// applied to the line item.
	BudgetAllocationType string `json:"budgetAllocationType,omitempty"`

	// BudgetUnit: Output only. The budget unit specifies whether the budget
	// is currency based
	// or impression based. This value is inherited from the parent
	// insertion
	// order.
	//
	// Possible values:
	//   "BUDGET_UNIT_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "BUDGET_UNIT_CURRENCY" - Budgeting in currency amounts.
	//   "BUDGET_UNIT_IMPRESSIONS" - Budgeting in impression amounts.
	BudgetUnit string `json:"budgetUnit,omitempty"`

	// MaxAmount: The maximum budget amount the line item will spend. Must
	// be greater than 0.
	//
	// When budget_allocation_type is:
	//
	// * `LINE_ITEM_BUDGET_ALLOCATION_TYPE_AUTOMATIC`, this field is
	// immutable
	// and is set by the system.
	// * `LINE_ITEM_BUDGET_ALLOCATION_TYPE_FIXED`, if
	// budget_unit is:
	//     - `BUDGET_UNIT_CURRENCY`, this field represents maximum budget
	// amount
	//     to spend, in micros of the advertiser's currency. For example,
	// 1500000
	//     represents 1.5 standard units of the currency.
	//     - `BUDGET_UNIT_IMPRESSIONS`, this field represents the maximum
	// number
	//     of impressions to serve.
	// * `LINE_ITEM_BUDGET_ALLOCATION_TYPE_UNLIMITED`, this field is
	// not
	// applicable and will be ignored by the system.
	MaxAmount int64 `json:"maxAmount,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "BudgetAllocationType") 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. "BudgetAllocationType") 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 *LineItemBudget) MarshalJSON() ([]byte, error) {
	type NoMethod LineItemBudget
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineItemFlight: Settings that control the active duration of a line
// item.
type LineItemFlight struct {
	// DateRange: The flight start and end dates of the line item. They are
	// resolved
	// relative to the parent advertiser's time zone.
	//
	// * Required when
	// flight_date_type is
	// `LINE_ITEM_FLIGHT_DATE_TYPE_CUSTOM`. Output only otherwise.
	// * When creating a new flight, both `start_date` and `end_date` must
	// be in
	// the future.
	// * An existing flight with a `start_date` in the past has a
	// mutable
	// `end_date` but an immutable `start_date`.
	// * `end_date` must be the `start_date` or later, both before the year
	// 2037.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// FlightDateType: Required. The type of the line item's flight dates.
	//
	// Possible values:
	//   "LINE_ITEM_FLIGHT_DATE_TYPE_UNSPECIFIED" - Type value is not
	// specified or is unknown in this version.
	//   "LINE_ITEM_FLIGHT_DATE_TYPE_INHERITED" - The line item's flight
	// dates are inherited from its parent insertion order.
	//   "LINE_ITEM_FLIGHT_DATE_TYPE_CUSTOM" - The line item uses its own
	// custom flight dates.
	FlightDateType string `json:"flightDateType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DateRange") 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. "DateRange") 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 *LineItemFlight) MarshalJSON() ([]byte, error) {
	type NoMethod LineItemFlight
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListAdvertiserAssignedTargetingOptionsResponse: Response message
// for
// ListAdvertiserAssignedTargetingOptions.
type ListAdvertiserAssignedTargetingOptionsResponse struct {
	// AssignedTargetingOptions: The list of assigned targeting
	// options.
	//
	// This list will be absent if empty.
	AssignedTargetingOptions []*AssignedTargetingOption `json:"assignedTargetingOptions,omitempty"`

	// NextPageToken: A token identifying the next page of results. This
	// value should be
	// specified as the
	// pageToken in a
	// subsequent ListAdvertiserAssignedTargetingOptionsRequest to fetch
	// the
	// next page of results. This token will be absent if there are no
	// more
	// assigned_targeting_options
	// to return.
	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.
	// "AssignedTargetingOptions") 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. "AssignedTargetingOptions")
	// 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 *ListAdvertiserAssignedTargetingOptionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListAdvertiserAssignedTargetingOptionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListAdvertisersResponse struct {
	// Advertisers: The list of advertisers.
	//
	// This list will be absent if empty.
	Advertisers []*Advertiser `json:"advertisers,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListAdvertisers` 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. "Advertisers") 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. "Advertisers") 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 *ListAdvertisersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListAdvertisersResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListCampaignsResponse struct {
	// Campaigns: The list of campaigns.
	//
	// This list will be absent if empty.
	Campaigns []*Campaign `json:"campaigns,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the page_token field
	// in the subsequent call to `ListCampaigns` 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. "Campaigns") 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. "Campaigns") 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 *ListCampaignsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListCampaignsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListChannelsResponse struct {
	// Channels: The list of channels.
	//
	// This list will be absent if empty.
	Channels []*Channel `json:"channels,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the page_token field
	// in the subsequent call to `ListChannels` 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. "Channels") 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. "Channels") 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 *ListChannelsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListChannelsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListCombinedAudiencesResponse struct {
	// CombinedAudiences: The list of combined audiences.
	//
	// This list will be absent if empty.
	CombinedAudiences []*CombinedAudience `json:"combinedAudiences,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListCombinedAudiences` 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. "CombinedAudiences")
	// 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. "CombinedAudiences") 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 *ListCombinedAudiencesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListCombinedAudiencesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListCreativesResponse struct {
	// Creatives: The list of creatives.
	//
	// This list will be absent if empty.
	Creatives []*Creative `json:"creatives,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the page_token field
	// in the subsequent call to `ListCreativesRequest` method to retrieve
	// the
	// next page of results.
	// If this field is null, it means this is the last page.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "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)
}

type ListCustomListsResponse struct {
	// CustomLists: The list of custom lists.
	//
	// This list will be absent if empty.
	CustomLists []*CustomList `json:"customLists,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListCustomLists` 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. "CustomLists") 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. "CustomLists") 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 *ListCustomListsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListCustomListsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListFirstAndThirdPartyAudiencesResponse struct {
	// FirstAndThirdPartyAudiences: The list of first and third party
	// audiences. Audience size properties will
	// not be included.
	//
	// This list will be absent if empty.
	FirstAndThirdPartyAudiences []*FirstAndThirdPartyAudience `json:"firstAndThirdPartyAudiences,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListFirstAndThirdPartyAudiences`
	// 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.
	// "FirstAndThirdPartyAudiences") 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.
	// "FirstAndThirdPartyAudiences") 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 *ListFirstAndThirdPartyAudiencesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListFirstAndThirdPartyAudiencesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListGoogleAudiencesResponse struct {
	// GoogleAudiences: The list of Google audiences.
	//
	// This list will be absent if empty.
	GoogleAudiences []*GoogleAudience `json:"googleAudiences,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListGoogleAudiences` 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. "GoogleAudiences") 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. "GoogleAudiences") 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 *ListGoogleAudiencesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListGoogleAudiencesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListInsertionOrdersResponse struct {
	// InsertionOrders: The list of insertion orders.
	//
	// This list will be absent if empty.
	InsertionOrders []*InsertionOrder `json:"insertionOrders,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the page_token
	// field in the subsequent call to `ListInsertionOrders` 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. "InsertionOrders") 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. "InsertionOrders") 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 *ListInsertionOrdersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListInsertionOrdersResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListInventorySourceGroupsResponse: Response message for
// InventorySourceGroupService.ListInventorySourceGroups.
type ListInventorySourceGroupsResponse struct {
	// InventorySourceGroups: The list of inventory source groups.
	//
	// This list will be absent if empty.
	InventorySourceGroups []*InventorySourceGroup `json:"inventorySourceGroups,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListInventorySourceGroups` 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.
	// "InventorySourceGroups") 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. "InventorySourceGroups") 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 *ListInventorySourceGroupsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListInventorySourceGroupsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListInventorySourcesResponse struct {
	// InventorySources: The list of inventory sources.
	//
	// This list will be absent if empty.
	InventorySources []*InventorySource `json:"inventorySources,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListInventorySources` 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. "InventorySources") 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. "InventorySources") 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 *ListInventorySourcesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListInventorySourcesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListLineItemAssignedTargetingOptionsResponse: Response message
// for
// ListLineItemAssignedTargetingOptions.
type ListLineItemAssignedTargetingOptionsResponse struct {
	// AssignedTargetingOptions: The list of assigned targeting
	// options.
	//
	// This list will be absent if empty.
	AssignedTargetingOptions []*AssignedTargetingOption `json:"assignedTargetingOptions,omitempty"`

	// NextPageToken: A token identifying the next page of results. This
	// value should be
	// specified as the
	// pageToken in a
	// subsequent ListLineItemAssignedTargetingOptionsRequest to fetch
	// the
	// next page of results. This token will be absent if there are no
	// more
	// assigned_targeting_options
	// to return.
	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.
	// "AssignedTargetingOptions") 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. "AssignedTargetingOptions")
	// 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 *ListLineItemAssignedTargetingOptionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListLineItemAssignedTargetingOptionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListLineItemsResponse struct {
	// LineItems: The list of line items.
	//
	// This list will be absent if empty.
	LineItems []*LineItem `json:"lineItems,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListLineItems` 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. "LineItems") 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. "LineItems") 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 *ListLineItemsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListLineItemsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListLocationListsResponse struct {
	// LocationLists: The list of location lists.
	//
	// This list will be absent if empty.
	LocationLists []*LocationList `json:"locationLists,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	//
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListLocationLists` 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. "LocationLists") 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. "LocationLists") 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 *ListLocationListsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListLocationListsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListNegativeKeywordListsResponse: Response message for
// NegativeKeywordListService.ListNegativeKeywordLists.
type ListNegativeKeywordListsResponse struct {
	// NegativeKeywordLists: The list of negative keyword lists.
	//
	// This list will be absent if empty.
	NegativeKeywordLists []*NegativeKeywordList `json:"negativeKeywordLists,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	//
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListNegativeKeywordLists` 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.
	// "NegativeKeywordLists") 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. "NegativeKeywordLists") 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 *ListNegativeKeywordListsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListNegativeKeywordListsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListTargetingOptionsResponse: Response message
// for
// ListTargetingOptions.
type ListTargetingOptionsResponse struct {
	// NextPageToken: A token to retrieve the next page of results.
	// Pass this value in the
	// page_token
	// field in the subsequent call to `ListTargetingOptions` method to
	// retrieve
	// the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TargetingOptions: The list of targeting options.
	//
	// This list will be absent if empty.
	TargetingOptions []*TargetingOption `json:"targetingOptions,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 *ListTargetingOptionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListTargetingOptionsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LocationList: A list of locations used for targeting.
type LocationList struct {
	// AdvertiserId: Required. Immutable. The unique ID of the advertiser
	// the location list belongs to.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// DisplayName: Required. The display name of the location list.
	// Must be UTF-8 encoded with a maximum size of 240 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// LocationListId: Output only. The unique ID of the location list.
	// Assigned by the system.
	LocationListId int64 `json:"locationListId,omitempty,string"`

	// LocationType: Required. Immutable. The type of location. All
	// locations in the list will share this type.
	//
	// Possible values:
	//   "TARGETING_LOCATION_TYPE_UNSPECIFIED" - Default value when type is
	// not specified or is unknown.
	//   "TARGETING_LOCATION_TYPE_PROXIMITY" - The type for proximity geo
	// location.
	//   "TARGETING_LOCATION_TYPE_REGIONAL" - The type for regional geo
	// location.
	LocationType string `json:"locationType,omitempty"`

	// Name: Output only. The resource name of the location list.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "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 *LocationList) MarshalJSON() ([]byte, error) {
	type NoMethod LocationList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LookbackWindow: Specifies how many days into the past to look when
// determining whether to
// record a conversion.
type LookbackWindow struct {
	// ClickDays: Lookback window, in days, from the last time a given user
	// clicked on one of
	// your ads.
	ClickDays int64 `json:"clickDays,omitempty"`

	// ImpressionDays: Lookback window, in days, from the last time a given
	// user viewed one of
	// your ads.
	ImpressionDays int64 `json:"impressionDays,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ClickDays") 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. "ClickDays") 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 *LookbackWindow) MarshalJSON() ([]byte, error) {
	type NoMethod LookbackWindow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MaximizeSpendBidStrategy: A strategy that automatically adjusts the
// bid to optimize a specified
// performance goal while spending the full budget.
type MaximizeSpendBidStrategy struct {
	// MaxAverageCpmBidAmountMicros: The maximum average CPM that may be
	// bid, in micros of the advertiser's
	// currency. Must be greater than or equal to a billable unit of the
	// given
	// currency.
	//
	// For example, 1500000 represents 1.5 standard units of the currency.
	MaxAverageCpmBidAmountMicros int64 `json:"maxAverageCpmBidAmountMicros,omitempty,string"`

	// PerformanceGoalType: Required. The type of the performance goal that
	// the bidding strategy
	// tries to minimize while spending the full
	// budget.
	// `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM` is not
	// supported for
	// this strategy.
	//
	// Possible values:
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_UNSPECIFIED" - Type value
	// is not specified or is unknown in this version.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPA" - Cost per action.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPC" - Cost per click.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM" - Viewable
	// CPM.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CIVA" - Completed inview
	// and audible views.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_IVO_TEN" - Inview time over
	// 10 secs views.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_AV_VIEWED" - Viewable
	// impressions.
	PerformanceGoalType string `json:"performanceGoalType,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "MaxAverageCpmBidAmountMicros") 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.
	// "MaxAverageCpmBidAmountMicros") 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 *MaximizeSpendBidStrategy) MarshalJSON() ([]byte, error) {
	type NoMethod MaximizeSpendBidStrategy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Money: Represents an amount of money with its currency type.
type Money struct {
	// CurrencyCode: The 3-letter currency code defined in ISO 4217.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// Nanos: Number of nano (10^-9) units of the amount.
	// The value must be between -999,999,999 and +999,999,999 inclusive.
	// If `units` is positive, `nanos` must be positive or zero.
	// If `units` is zero, `nanos` can be positive, zero, or negative.
	// If `units` is negative, `nanos` must be negative or zero.
	// For example $-1.75 is represented as `units`=-1 and
	// `nanos`=-750,000,000.
	Nanos int64 `json:"nanos,omitempty"`

	// Units: The whole units of the amount.
	// For example if `currencyCode` is "USD", then 1 unit is one US
	// dollar.
	Units int64 `json:"units,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CurrencyCode") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "CurrencyCode") 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 *Money) MarshalJSON() ([]byte, error) {
	type NoMethod Money
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NegativeKeywordList: A list of negative keywords used for targeting.
type NegativeKeywordList struct {
	// AdvertiserId: Output only. The unique ID of the advertiser the
	// negative keyword list belongs to.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// DisplayName: Required. The display name of the negative keyword
	// list.
	// Must be UTF-8 encoded with a maximum size of 255 bytes.
	DisplayName string `json:"displayName,omitempty"`

	// Name: Output only. The resource name of the negative keyword list.
	Name string `json:"name,omitempty"`

	// NegativeKeywordListId: Output only. The unique ID of the negative
	// keyword list. Assigned by the system.
	NegativeKeywordListId int64 `json:"negativeKeywordListId,omitempty,string"`

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

	// 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 *NegativeKeywordList) MarshalJSON() ([]byte, error) {
	type NoMethod NegativeKeywordList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NegativeKeywordListAssignedTargetingOptionDetails: Targeting details
// for negative keyword list. This will be populated in the
// details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_NEGATIVE_KEYWORD_LIST`.
type NegativeKeywordListAssignedTargetingOptionDetails struct {
	// NegativeKeywordListId: Required. ID of the negative keyword list.
	// Should refer to the
	// negative_keyword_list_id
	// field of a NegativeKeywordList resource.
	NegativeKeywordListId int64 `json:"negativeKeywordListId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "NegativeKeywordListId") 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. "NegativeKeywordListId") 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 *NegativeKeywordListAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod NegativeKeywordListAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ObaIcon: OBA Icon for a Creative
type ObaIcon struct {
	// ClickTrackingUrl: Required. The click tracking URL of the OBA
	// icon.
	//
	// Only URLs of the following domains are allowed:
	//
	// * https://info.evidon.com
	// * https://l.betrad.com
	ClickTrackingUrl string `json:"clickTrackingUrl,omitempty"`

	// Dimensions: The dimensions of the OBA icon.
	Dimensions *Dimensions `json:"dimensions,omitempty"`

	// LandingPageUrl: Required. The landing page URL of the OBA icon.
	//
	// Only URLs of the following domains are allowed:
	//
	// * https://info.evidon.com
	// * https://l.betrad.com
	LandingPageUrl string `json:"landingPageUrl,omitempty"`

	// Position: The position of the OBA icon on the creative.
	//
	// Possible values:
	//   "OBA_ICON_POSITION_UNSPECIFIED" - The OBA icon position is not
	// specified.
	//   "OBA_ICON_POSITION_UPPER_RIGHT" - At the upper right side of the
	// creative.
	//   "OBA_ICON_POSITION_UPPER_LEFT" - At the upper left side of the
	// creative.
	//   "OBA_ICON_POSITION_LOWER_RIGHT" - At the lower right side of the
	// creative.
	//   "OBA_ICON_POSITION_LOWER_LEFT" - At the lower left side of the
	// creative.
	Position string `json:"position,omitempty"`

	// Program: The program of the OBA icon. For example: “AdChoices”.
	Program string `json:"program,omitempty"`

	// ResourceMimeType: The MIME type of the OBA icon resource.
	ResourceMimeType string `json:"resourceMimeType,omitempty"`

	// ResourceUrl: The URL of the OBA icon resource.
	ResourceUrl string `json:"resourceUrl,omitempty"`

	// ViewTrackingUrl: Required. The view tracking URL of the OBA
	// icon.
	//
	// Only URLs of the following domains are allowed:
	//
	// * https://info.evidon.com
	// * https://l.betrad.com
	ViewTrackingUrl string `json:"viewTrackingUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ClickTrackingUrl") 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. "ClickTrackingUrl") 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 *ObaIcon) MarshalJSON() ([]byte, error) {
	type NoMethod ObaIcon
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OnScreenPositionAssignedTargetingOptionDetails: On screen position
// targeting option details. This will be
// populated in the
// on_screen_position_details
// field when
// targeting_type is
// `TARGETING_TYPE_ON_SCREEN_POSITION`.
type OnScreenPositionAssignedTargetingOptionDetails struct {
	// OnScreenPosition: Output only. The on screen position.
	//
	// Possible values:
	//   "ON_SCREEN_POSITION_UNSPECIFIED" - On screen position is not
	// specified in this version. This enum is a place
	// holder for a default value and does not represent a real on
	// screen
	// position.
	//   "ON_SCREEN_POSITION_UNKNOWN" - The ad position is unknown on the
	// screen.
	//   "ON_SCREEN_POSITION_ABOVE_THE_FOLD" - The ad is located above the
	// fold.
	//   "ON_SCREEN_POSITION_BELOW_THE_FOLD" - The ad is located below the
	// fold.
	OnScreenPosition string `json:"onScreenPosition,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id field
	// when
	// targeting_type is
	// `TARGETING_TYPE_ON_SCREEN_POSITION`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OnScreenPosition") 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. "OnScreenPosition") 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 *OnScreenPositionAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod OnScreenPositionAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OnScreenPositionTargetingOptionDetails: Represents a targetable on
// screen position, which could be used by display
// and video ads. This will be populated in
// the
// on_screen_position_details
// field when
// targeting_type is
// `TARGETING_TYPE_ON_SCREEN_POSITION`.
type OnScreenPositionTargetingOptionDetails struct {
	// OnScreenPosition: Output only. The on screen position.
	//
	// Possible values:
	//   "ON_SCREEN_POSITION_UNSPECIFIED" - On screen position is not
	// specified in this version. This enum is a place
	// holder for a default value and does not represent a real on
	// screen
	// position.
	//   "ON_SCREEN_POSITION_UNKNOWN" - The ad position is unknown on the
	// screen.
	//   "ON_SCREEN_POSITION_ABOVE_THE_FOLD" - The ad is located above the
	// fold.
	//   "ON_SCREEN_POSITION_BELOW_THE_FOLD" - The ad is located below the
	// fold.
	OnScreenPosition string `json:"onScreenPosition,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OnScreenPosition") 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. "OnScreenPosition") 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 *OnScreenPositionTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod OnScreenPositionTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OperatingSystemAssignedTargetingOptionDetails: Assigned operating
// system targeting option details. This will be
// populated in the
// operating_system_details
// field when
// targeting_type is
// `TARGETING_TYPE_OPERATING_SYSTEM`.
type OperatingSystemAssignedTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the operating system.
	DisplayName string `json:"displayName,omitempty"`

	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// TargetingOptionId: Required. The targeting option ID populated
	// in
	// targeting_option_id field when
	// targeting_type is
	// `TARGETING_TYPE_OPERATING_SYSTEM`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *OperatingSystemAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod OperatingSystemAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OperatingSystemTargetingOptionDetails: Represents a targetable
// operating system. This will be populated in
// the
// operating_system_details field
// of a TargetingOption when
// targeting_type is
// `TARGETING_TYPE_OPERATING_SYSTEM`.
type OperatingSystemTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the operating system.
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *OperatingSystemTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod OperatingSystemTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Operation: This resource represents a long-running operation that is
// the result of a
// network API call.
type Operation struct {
	// Done: If the value is `false`, it means the operation is still in
	// progress.
	// If `true`, the operation is completed, and either `error` or
	// `response` is
	// available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *Status `json:"error,omitempty"`

	// Metadata: Service-specific metadata associated with the operation.
	// It typically
	// contains progress information and common metadata such as create
	// time.
	// Some services might not provide such metadata.  Any method that
	// returns a
	// long-running operation should document the metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that
	// originally returns it. If you use the default HTTP mapping,
	// the
	// `name` should be a resource name ending with
	// `operations/{unique_id}`.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success.
	// If the original
	// method returns no data on success, such as `Delete`, the response
	// is
	// `google.protobuf.Empty`.  If the original method is
	// standard
	// `Get`/`Create`/`Update`, the response should be the resource.  For
	// other
	// methods, the response should have the type `XxxResponse`, where
	// `Xxx`
	// is the original method name.  For example, if the original method
	// name
	// is `TakeSnapshot()`, the inferred response type
	// is
	// `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Done") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Done") 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 *Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Pacing: Settings that control the rate at which a budget is spent.
type Pacing struct {
	// DailyMaxImpressions: Maximum number of impressions to serve every
	// day.
	//
	// Applicable when the budget is impression based. Must be greater than
	// 0.
	DailyMaxImpressions int64 `json:"dailyMaxImpressions,omitempty,string"`

	// DailyMaxMicros: Maximum currency amount to spend every day in micros
	// of
	// advertiser's currency.
	//
	// Applicable when the budget is currency based. Must be greater than
	// 0.
	// For example, for 1.5 standard unit of the currency, set this field
	// to
	// 1500000.
	//
	// The value assigned will be rounded to whole billable units for
	// the
	// relevant currency by the following rules: any positive value less
	// than a
	// single billable unit will be rounded up to one billable unit and
	// any
	// value larger than a single billable unit will be rounded down to
	// the
	// nearest billable value. For example, if the currency's billable unit
	// is
	// 0.01, and this field is set to 10257770, it will round down to
	// 10250000,
	// a value of 10.25. If set to 505, it will round up to 10000, a value
	// of
	// 0.01.
	DailyMaxMicros int64 `json:"dailyMaxMicros,omitempty,string"`

	// PacingPeriod: Required. The time period in which the pacing budget
	// will be spent.
	//
	// When automatic budget allocation is enabled at the insertion order
	// via
	// auto_budget_allocation, this
	// field is output only and defaults to `PACING_PERIOD_FLIGHT`.
	//
	// Possible values:
	//   "PACING_PERIOD_UNSPECIFIED" - Period value is not specified or is
	// unknown in this version.
	//   "PACING_PERIOD_DAILY" - The pacing setting will be applied on daily
	// basis.
	//   "PACING_PERIOD_FLIGHT" - The pacing setting will be applied to the
	// whole flight duration.
	PacingPeriod string `json:"pacingPeriod,omitempty"`

	// PacingType: Required. The type of pacing that defines how the budget
	// amount will be
	// spent across the pacing_period.
	//
	// Possible values:
	//   "PACING_TYPE_UNSPECIFIED" - Pacing mode value is not specified or
	// is unknown in this version.
	//   "PACING_TYPE_AHEAD" - Only applicable to `PACING_PERIOD_FLIGHT`
	// pacing period.
	// Ahead pacing attempts to spend faster than evenly, to make sure
	// the
	// entire budget is spent by the end of the flight.
	//   "PACING_TYPE_ASAP" - Spend all of pacing budget amount as quick as
	// possible.
	//   "PACING_TYPE_EVEN" - Spend a consistent budget amount every period
	// of time.
	PacingType string `json:"pacingType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DailyMaxImpressions")
	// 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. "DailyMaxImpressions") 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 *Pacing) MarshalJSON() ([]byte, error) {
	type NoMethod Pacing
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ParentEntityFilter: A filtering option that filters on selected file
// types belonging to a chosen
// set of filter entities.
type ParentEntityFilter struct {
	// FileType: Required. File types that will be returned.
	//
	// Possible values:
	//   "FILE_TYPE_UNSPECIFIED" - Default value when type is unspecified or
	// is unknown in this version.
	//   "FILE_TYPE_CAMPAIGN" - Campaign.
	//   "FILE_TYPE_MEDIA_PRODUCT" - Media Product.
	//   "FILE_TYPE_INSERTION_ORDER" - Insertion Order.
	//   "FILE_TYPE_LINE_ITEM" - Line Item.
	//   "FILE_TYPE_AD_GROUP" - TrueView Ad Group.
	//   "FILE_TYPE_AD" - TrueView Ad.
	FileType []string `json:"fileType,omitempty"`

	// FilterIds: The IDs of the specified filter type. This is used to
	// filter entities to
	// fetch. If filter type is not `FILTER_TYPE_NONE`, at least one ID must
	// be
	// specified.
	FilterIds googleapi.Int64s `json:"filterIds,omitempty"`

	// FilterType: Required. Filter type used to filter fetched entities.
	//
	// Possible values:
	//   "FILTER_TYPE_UNSPECIFIED" - Default value when type is unspecified
	// or is unknown in this version.
	//   "FILTER_TYPE_NONE" - If selected, no filter will be applied to the
	// download. Can only be used if
	// an Advertiser is specified
	// in CreateSdfDownloadTaskRequest.
	//   "FILTER_TYPE_ADVERTISER_ID" - Advertiser ID. If selected, all
	// filter IDs must be Advertiser IDs that
	// belong to the Partner specified
	// in CreateSdfDownloadTaskRequest.
	//   "FILTER_TYPE_CAMPAIGN_ID" - Campaign ID. If selected, all filter
	// IDs must be Campaign IDs that belong
	// to the Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest.
	//   "FILTER_TYPE_MEDIA_PRODUCT_ID" - Media Product ID. If selected, all
	// filter IDs must be Media Product IDs
	// that belong to the Advertiser
	// or Partner specified in
	// CreateSdfDownloadTaskRequest. Can only be used for
	// downloading
	// `FILE_TYPE_MEDIA_PRODUCT`.
	//   "FILTER_TYPE_INSERTION_ORDER_ID" - Insertion Order ID. If selected,
	// all filter IDs must be Insertion Order IDs
	// that belong to the Advertiser
	// or Partner specified in
	// CreateSdfDownloadTaskRequest. Can only be used for
	// downloading
	// `FILE_TYPE_INSERTION_ORDER`, `FILE_TYPE_LINE_ITEM`,
	// `FILE_TYPE_AD_GROUP`,
	// and `FILE_TYPE_AD`.
	//   "FILTER_TYPE_LINE_ITEM_ID" - Line Item ID. If selected, all filter
	// IDs must be Line Item IDs that belong
	// to the Advertiser or
	// Partner specified in
	// CreateSdfDownloadTaskRequest. Can only be used for
	// downloading
	// `FILE_TYPE_LINE_ITEM`, `FILE_TYPE_AD_GROUP`, and `FILE_TYPE_AD`.
	FilterType string `json:"filterType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FileType") 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. "FileType") 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 *ParentEntityFilter) MarshalJSON() ([]byte, error) {
	type NoMethod ParentEntityFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ParentalStatusAssignedTargetingOptionDetails: Details for assigned
// parental status targeting option. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARTGETING_TYPE_PARENTAL_STATUS`.
type ParentalStatusAssignedTargetingOptionDetails struct {
	// ParentalStatus: Output only. The parental status of the audience.
	//
	// Possible values:
	//   "PARENTAL_STATUS_UNSPECIFIED" - Default value when parental status
	// is not specified in this version. This
	// enum is a place holder for default value and does not represent a
	// real
	// parental status option.
	//   "PARENTAL_STATUS_PARENT" - The audience is a parent.
	//   "PARENTAL_STATUS_NOT_A_PARENT" - The audience is not a parent.
	//   "PARENTAL_STATUS_UNKNOWN" - The parental status of the audience is
	// unknown.
	ParentalStatus string `json:"parentalStatus,omitempty"`

	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_PARENTAL_STATUS`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ParentalStatus") 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. "ParentalStatus") 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 *ParentalStatusAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ParentalStatusAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ParentalStatusTargetingOptionDetails: Represents a targetable
// parental status. This will be populated in
// the
// parental_status_details field of a
// TargetingOption when targeting_type
// is
// `TARGETING_TYPE_PARENTAL_STATUS`.
type ParentalStatusTargetingOptionDetails struct {
	// ParentalStatus: Output only. The parental status of an audience.
	//
	// Possible values:
	//   "PARENTAL_STATUS_UNSPECIFIED" - Default value when parental status
	// is not specified in this version. This
	// enum is a place holder for default value and does not represent a
	// real
	// parental status option.
	//   "PARENTAL_STATUS_PARENT" - The audience is a parent.
	//   "PARENTAL_STATUS_NOT_A_PARENT" - The audience is not a parent.
	//   "PARENTAL_STATUS_UNKNOWN" - The parental status of the audience is
	// unknown.
	ParentalStatus string `json:"parentalStatus,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ParentalStatus") 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. "ParentalStatus") 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 *ParentalStatusTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ParentalStatusTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PartnerCost: Settings that control a partner cost.
//
// A partner cost is any type of expense involved in running a campaign,
// other
// than the costs of purchasing impressions (which is called the media
// cost)
// and using third-party audience segment data (data fee). Some examples
// of
// partner costs include the fees for using DV360, a third-party ad
// server,
// or a third-party ad serving verification service.
type PartnerCost struct {
	// CostType: Required. The type of the partner cost.
	//
	// Possible values:
	//   "PARTNER_COST_TYPE_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "PARTNER_COST_TYPE_ADLOOX" - The cost is charged for using Adloox.
	//   "PARTNER_COST_TYPE_ADLOOX_PREBID" - The cost is charged for using
	// Adloox Pre-Bid.
	//   "PARTNER_COST_TYPE_ADSAFE" - The cost is charged for using AdSafe.
	//   "PARTNER_COST_TYPE_ADXPOSE" - The cost is charged for using
	// AdExpose.
	//   "PARTNER_COST_TYPE_AGGREGATE_KNOWLEDGE" - The cost is charged for
	// using Aggregate Knowledge.
	//   "PARTNER_COST_TYPE_AGENCY_TRADING_DESK" - The cost is charged for
	// using an Agency Trading Desk.
	//   "PARTNER_COST_TYPE_DV360_FEE" - The cost is charged for using
	// DV360.
	//   "PARTNER_COST_TYPE_COMSCORE_VCE" - The cost is charged for using
	// comScore vCE.
	//   "PARTNER_COST_TYPE_DATA_MANAGEMENT_PLATFORM" - The cost is charged
	// for using a Data Management Platform.
	//   "PARTNER_COST_TYPE_DEFAULT" - The default cost type.
	//   "PARTNER_COST_TYPE_DOUBLE_VERIFY" - The cost is charged for using
	// DoubleVerify.
	//   "PARTNER_COST_TYPE_DOUBLE_VERIFY_PREBID" - The cost is charged for
	// using DoubleVerify Pre-Bid.
	//   "PARTNER_COST_TYPE_EVIDON" - The cost is charged for using Evidon.
	//   "PARTNER_COST_TYPE_INTEGRAL_AD_SCIENCE_VIDEO" - The cost is charged
	// for using Integral Ad Science Video.
	//   "PARTNER_COST_TYPE_INTEGRAL_AD_SCIENCE_PREBID" - The cost is
	// charged for using Integral Ad Science Pre-Bid.
	//   "PARTNER_COST_TYPE_MEDIA_COST_DATA" - The cost is charged for using
	// media cost data.
	//   "PARTNER_COST_TYPE_MOAT_VIDEO" - The cost is charged for using MOAT
	// Video.
	//   "PARTNER_COST_TYPE_NIELSEN_DAR" - The cost is charged for using
	// Nielsen Digital Ad Ratings.
	//   "PARTNER_COST_TYPE_SHOP_LOCAL" - The cost is charged for using
	// ShopLocal.
	//   "PARTNER_COST_TYPE_TERACENT" - The cost is charged for using
	// Teracent.
	//   "PARTNER_COST_TYPE_THIRD_PARTY_AD_SERVER" - The cost is charged for
	// using a third-party ad server.
	//   "PARTNER_COST_TYPE_TRUST_METRICS" - The cost is charged for using
	// TrustMetrics.
	//   "PARTNER_COST_TYPE_VIZU" - The cost is charged for using Vizu.
	//   "PARTNER_COST_TYPE_ADLINGO_FEE" - The cost is charged for using
	// AdLingo.
	//   "PARTNER_COST_TYPE_CUSTOM_FEE_1" - The cost is charged as custom
	// fee 1.
	//   "PARTNER_COST_TYPE_CUSTOM_FEE_2" - The cost is charged as custom
	// fee 2.
	//   "PARTNER_COST_TYPE_CUSTOM_FEE_3" - The cost is charged as custom
	// fee 3.
	//   "PARTNER_COST_TYPE_CUSTOM_FEE_4" - The cost is charged as custom
	// fee 4.
	//   "PARTNER_COST_TYPE_CUSTOM_FEE_5" - The cost is charged as custom
	// fee 5.
	CostType string `json:"costType,omitempty"`

	// FeeAmount: The CPM fee amount in micros of advertiser's
	// currency.
	//
	// Applicable when the fee_type is
	// `PARTNER_FEE_TYPE_CPM_FEE`. Must be greater than or equal to 0.
	//
	// For example, for 1.5 standard unit of the advertiser's currency,
	// set
	// this field to 1500000.
	FeeAmount int64 `json:"feeAmount,omitempty,string"`

	// FeePercentageMillis: The media fee percentage in millis (1/1000 of a
	// percent).
	//
	// Applicable when the fee_type is
	// `PARTNER_FEE_TYPE_MEDIA_FEE`. Must be greater than or equal to
	// 0.
	//
	// For example: 100 represents 0.1%.
	FeePercentageMillis int64 `json:"feePercentageMillis,omitempty,string"`

	// FeeType: Required. The fee type for this partner cost.
	//
	// Possible values:
	//   "PARTNER_COST_FEE_TYPE_UNSPECIFIED" - Value is not specified or is
	// unknown in this version.
	//   "PARTNER_COST_FEE_TYPE_CPM_FEE" - The partner cost is a fixed CPM
	// fee.
	//
	// Not applicable when the partner cost cost_type
	// is one of:
	//
	// * `PARTNER_COST_TYPE_MEDIA_COST_DATA`
	// * `PARTNER_COST_TYPE_DV360_FEE`.
	//   "PARTNER_COST_FEE_TYPE_MEDIA_FEE" - The partner cost is a
	// percentage surcharge based on the media cost.
	//
	// Not applicable when the partner cost_type is one
	// of:
	//
	// * `PARTNER_COST_TYPE_SHOP_LOCAL`
	// * `PARTNER_COST_TYPE_TRUST_METRICS`
	// * `PARTNER_COST_TYPE_INTEGRAL_AD_SCIENCE_VIDEO`
	// * `PARTNER_COST_TYPE_MOAT_VIDEO`.
	FeeType string `json:"feeType,omitempty"`

	// InvoiceType: The invoice type for this partner cost.
	//
	// * Required when cost_type is one of:
	//     - `PARTNER_COST_TYPE_ADLOOX`
	//     - `PARTNER_COST_TYPE_DOUBLE_VERIFY`
	//     - `PARTNER_COST_TYPE_INTEGRAL_AD_SCIENCE`.
	// * Output only for other types.
	//
	// Possible values:
	//   "PARTNER_COST_INVOICE_TYPE_UNSPECIFIED" - Type value is not
	// specified or is unknown in this version.
	//   "PARTNER_COST_INVOICE_TYPE_DV360" - Partner cost is billed through
	// DV360.
	//   "PARTNER_COST_INVOICE_TYPE_PARTNER" - Partner cost is billed by the
	// partner.
	InvoiceType string `json:"invoiceType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CostType") 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. "CostType") 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 *PartnerCost) MarshalJSON() ([]byte, error) {
	type NoMethod PartnerCost
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PartnerRevenueModel: Settings that control how partner revenue is
// calculated.
type PartnerRevenueModel struct {
	// MarkupAmount: Required. The markup amount of the partner revenue
	// model.
	// Must be greater than or equal to 0.
	//
	// * When the markup_type is set to
	// be
	// `PARTNER_REVENUE_MODEL_MARKUP_TYPE_CPM`, this field represents the
	// CPM
	// markup in micros of advertiser's currency. For example,
	// 1500000
	// represents 1.5 standard units of the currency.
	// * When the markup_type is set to
	// be
	// `PARTNER_REVENUE_MODEL_MARKUP_TYPE_MEDIA_COST_MARKUP`, this
	// field
	// represents the media cost percent markup in millis. For example,
	// 100 represents 0.1% (decimal 0.001).
	// * When the markup_type is set to
	// be
	// `PARTNER_REVENUE_MODEL_MARKUP_TYPE_TOTAL_MEDIA_COST_MARKUP`, this
	// field
	// represents the total media cost percent markup in millis. For
	// example,
	// 100 represents 0.1% (decimal 0.001).
	MarkupAmount int64 `json:"markupAmount,omitempty,string"`

	// MarkupType: Required. The markup type of the partner revenue model.
	//
	// Possible values:
	//   "PARTNER_REVENUE_MODEL_MARKUP_TYPE_UNSPECIFIED" - Type value is not
	// specified or is unknown in this version.
	//   "PARTNER_REVENUE_MODEL_MARKUP_TYPE_CPM" - Calculate the partner
	// revenue based on a fixed CPM.
	//   "PARTNER_REVENUE_MODEL_MARKUP_TYPE_MEDIA_COST_MARKUP" - Calculate
	// the partner revenue based on a percentage surcharge of its
	// media cost.
	//   "PARTNER_REVENUE_MODEL_MARKUP_TYPE_TOTAL_MEDIA_COST_MARKUP" -
	// Calculate the partner revenue based on a percentage surcharge of
	// its
	// total media cost, which includes all partner costs and data costs.
	MarkupType string `json:"markupType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MarkupAmount") 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. "MarkupAmount") 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 *PartnerRevenueModel) MarshalJSON() ([]byte, error) {
	type NoMethod PartnerRevenueModel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PerformanceGoal: Settings that control the performance goal of a
// campaign or insertion order.
type PerformanceGoal struct {
	// PerformanceGoalAmountMicros: The goal amount, in micros of the
	// advertiser's currency.
	//
	// Applicable when
	// performance_goal_type is one of:
	//
	// * `PERFORMANCE_GOAL_TYPE_CPM`
	// * `PERFORMANCE_GOAL_TYPE_CPC`
	// * `PERFORMANCE_GOAL_TYPE_CPA`
	// * `PERFORMANCE_GOAL_TYPE_CPIAVC`
	//
	// For example 1500000 represents 1.5 standard units of the currency.
	PerformanceGoalAmountMicros int64 `json:"performanceGoalAmountMicros,omitempty,string"`

	// PerformanceGoalPercentageMicros: The decimal representation of the
	// goal percentage in micros.
	//
	// Applicable when
	// performance_goal_type is one of:
	//
	// * `PERFORMANCE_GOAL_TYPE_CTR`
	// * `PERFORMANCE_GOAL_TYPE_VIEWABILITY`
	//
	// For example, 70000 represents 7% (decimal 0.07).
	PerformanceGoalPercentageMicros int64 `json:"performanceGoalPercentageMicros,omitempty,string"`

	// PerformanceGoalString: A key performance indicator (KPI) string,
	// which can be empty.
	// Must be UTF-8 encoded with a length of no more than 100
	// characters.
	//
	// Applicable when
	// performance_goal_type is set to
	// `PERFORMANCE_GOAL_TYPE_OTHER`.
	PerformanceGoalString string `json:"performanceGoalString,omitempty"`

	// PerformanceGoalType: Required. The type of the performance goal.
	//
	// Possible values:
	//   "PERFORMANCE_GOAL_TYPE_UNSPECIFIED" - Performance goal type is not
	// specified or is unknown in this version.
	//   "PERFORMANCE_GOAL_TYPE_CPM" - The performance goal is set in CPM
	// (cost per mille).
	//   "PERFORMANCE_GOAL_TYPE_CPC" - The performance goal is set in CPC
	// (cost per click).
	//   "PERFORMANCE_GOAL_TYPE_CPA" - The performance goal is set in CPA
	// (cost per action).
	//   "PERFORMANCE_GOAL_TYPE_VIEWABILITY" - The performance goal is set
	// in Viewability percentage.
	//   "PERFORMANCE_GOAL_TYPE_CPIAVC" - The performance goal is set as
	// CPIAVC (cost per impression audible and
	// visible at completion).
	//   "PERFORMANCE_GOAL_TYPE_CPE" - The performance goal is set in CPE
	// (cost per engagement).
	//   "PERFORMANCE_GOAL_TYPE_OTHER" - The performance goal is set to
	// Other.
	PerformanceGoalType string `json:"performanceGoalType,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PerformanceGoalAmountMicros") 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.
	// "PerformanceGoalAmountMicros") 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 *PerformanceGoal) MarshalJSON() ([]byte, error) {
	type NoMethod PerformanceGoal
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PerformanceGoalBidStrategy: A strategy that automatically adjusts the
// bid to meet or beat a specified
// performance goal.
type PerformanceGoalBidStrategy struct {
	// MaxAverageCpmBidAmountMicros: The maximum average CPM that may be
	// bid, in micros of the advertiser's
	// currency. Must be greater than or equal to a billable unit of the
	// given
	// currency. Not applicable when
	// performance_goal_type
	// is set to `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM`.
	//
	// For example, 1500000 represents 1.5 standard units of the currency.
	MaxAverageCpmBidAmountMicros int64 `json:"maxAverageCpmBidAmountMicros,omitempty,string"`

	// PerformanceGoalAmountMicros: Required. The performance goal the
	// bidding strategy will attempt to
	// meet or beat, in micros of the advertiser's currency.
	// Must be greater than or equal to a billable unit of the given
	// currency and
	// smaller or equal to upper bounds. Each
	// performance_goal_type
	// has its upper bound:
	//
	// * when
	// performance_goal_type
	// is `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPA`,
	// upper bound is 10000.00 USD.
	// * when
	// performance_goal_type
	// is `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPC`,
	// upper bound is 1000.00 USD.
	// * when
	// performance_goal_type
	// is `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM`, upper bound
	// is
	// 1000.00 USD.
	//
	// Example: If set
	// to
	// `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM`, the bid price
	// will
	// be based on the probability that each available impression will
	// be
	// viewable. For example, if viewable CPM target is $2 and an impression
	// is
	// 40% likely to be viewable, the bid price will be $0.80 CPM (40% of
	// $2).
	//
	// For example, 1500000 represents 1.5 standard units of the currency.
	PerformanceGoalAmountMicros int64 `json:"performanceGoalAmountMicros,omitempty,string"`

	// PerformanceGoalType: Required. The type of the performance goal that
	// the bidding strategy
	// will try to meet or beat.
	//
	// For line item level usage, the value must be one of:
	//
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPA`
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPC`
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM`.
	//
	// Possible values:
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_UNSPECIFIED" - Type value
	// is not specified or is unknown in this version.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPA" - Cost per action.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPC" - Cost per click.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM" - Viewable
	// CPM.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CIVA" - Completed inview
	// and audible views.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_IVO_TEN" - Inview time over
	// 10 secs views.
	//   "BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_AV_VIEWED" - Viewable
	// impressions.
	PerformanceGoalType string `json:"performanceGoalType,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "MaxAverageCpmBidAmountMicros") 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.
	// "MaxAverageCpmBidAmountMicros") 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 *PerformanceGoalBidStrategy) MarshalJSON() ([]byte, error) {
	type NoMethod PerformanceGoalBidStrategy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ProximityLocationListAssignedTargetingOptionDetails: Targeting
// details for proximity location list. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_PROXIMITY_LOCATION_LIST`.
type ProximityLocationListAssignedTargetingOptionDetails struct {
	// ProximityLocationListId: Required. ID of the proximity location list.
	// Should refer to the
	// location_list_id field of a
	// LocationList resource whose type
	// is
	// `TARGETING_LOCATION_TYPE_PROXIMITY`.
	ProximityLocationListId int64 `json:"proximityLocationListId,omitempty,string"`

	// ProximityRadiusRange: Required. Radius range for proximity location
	// list.
	// This represents the size of the area around a chosen location that
	// will be
	// targeted.
	//
	// `All` proximity location targeting under a single line item must have
	// the
	// same radius range value. Set this value to match any existing
	// targeting.
	// If updated, this field will change the radius range for all
	// proximity
	// targeting under the line item.
	//
	// Possible values:
	//   "PROXIMITY_RADIUS_RANGE_UNSPECIFIED" - The targeted radius range is
	// not specified or is unknown.
	// Default value when radius range is not specified in this
	// version.
	// This enum is a placeholder for default value and does not represent a
	// real
	// radius range option.
	//   "PROXIMITY_RADIUS_RANGE_SMALL" - The targeted radius range is
	// small.
	//   "PROXIMITY_RADIUS_RANGE_MEDIUM" - The targeted radius range is
	// medium.
	//   "PROXIMITY_RADIUS_RANGE_LARGE" - The targeted radius range is
	// large.
	ProximityRadiusRange string `json:"proximityRadiusRange,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ProximityLocationListId") 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. "ProximityLocationListId")
	// 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 *ProximityLocationListAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ProximityLocationListAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PublisherReviewStatus: Publisher review status for the creative.
type PublisherReviewStatus struct {
	// PublisherName: The publisher reviewing the creative.
	PublisherName string `json:"publisherName,omitempty"`

	// Status: Status of the publisher review.
	//
	// Possible values:
	//   "REVIEW_STATUS_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "REVIEW_STATUS_APPROVED" - The creative is approved.
	//   "REVIEW_STATUS_REJECTED" - The creative is rejected.
	//   "REVIEW_STATUS_PENDING" - The creative is pending review.
	Status string `json:"status,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PublisherName") 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. "PublisherName") 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 *PublisherReviewStatus) MarshalJSON() ([]byte, error) {
	type NoMethod PublisherReviewStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RateDetails: The rate related settings of the inventory source.
type RateDetails struct {
	// InventorySourceRateType: The rate type.
	//
	// Acceptable values are
	// `INVENTORY_SOURCE_RATE_TYPE_CPM_FIXED`,
	// `INVENTORY_SOURCE_RATE_TYPE_CP
	// M_FLOOR`, and
	// `INVENTORY_SOURCE_RATE_TYPE_CPD`.
	//
	// Possible values:
	//   "INVENTORY_SOURCE_RATE_TYPE_UNSPECIFIED" - The rate type is not
	// specified or is unknown in this version.
	//   "INVENTORY_SOURCE_RATE_TYPE_CPM_FIXED" - The rate type is CPM
	// (Fixed).
	//   "INVENTORY_SOURCE_RATE_TYPE_CPM_FLOOR" - The rate type is CPM
	// (Floor).
	//   "INVENTORY_SOURCE_RATE_TYPE_CPD" - The rate type is Cost per Day.
	//   "INVENTORY_SOURCE_RATE_TYPE_FLAT" - The rate type is Flat.
	InventorySourceRateType string `json:"inventorySourceRateType,omitempty"`

	// MinimumSpend: Output only. The amount that the buyer has committed to
	// spending on the inventory source
	// up front.
	//
	// Only applicable for guaranteed inventory sources.
	MinimumSpend *Money `json:"minimumSpend,omitempty"`

	// Rate: The rate for the inventory source.
	Rate *Money `json:"rate,omitempty"`

	// UnitsPurchased: Required for guaranteed inventory sources.
	// The number of impressions guaranteed by the seller.
	UnitsPurchased int64 `json:"unitsPurchased,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "InventorySourceRateType") 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. "InventorySourceRateType")
	// 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 *RateDetails) MarshalJSON() ([]byte, error) {
	type NoMethod RateDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegionalLocationListAssignedTargetingOptionDetails: Targeting details
// for regional location list. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_REGIONAL_LOCATION_LIST`.
type RegionalLocationListAssignedTargetingOptionDetails struct {
	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// RegionalLocationListId: Required. ID of the regional location list.
	// Should refer to the
	// location_list_id field of a
	// LocationList resource whose type is
	// `TARGETING_LOCATION_TYPE_REGIONAL`.
	RegionalLocationListId int64 `json:"regionalLocationListId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Negative") 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. "Negative") 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 *RegionalLocationListAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod RegionalLocationListAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReviewStatusInfo: Review statuses for the creative.
type ReviewStatusInfo struct {
	// ApprovalStatus: Represents the basic approval needed for a creative
	// to begin serving.
	// Summary
	// of
	// creative_and_landing_page_review_status
	// and
	// content_and_policy_revi
	// ew_status.
	//
	// Possible values:
	//   "APPROVAL_STATUS_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "APPROVAL_STATUS_PENDING_NOT_SERVABLE" - The creative is still
	// under review and not servable.
	//   "APPROVAL_STATUS_PENDING_SERVABLE" - The creative has passed
	// creative & landing page
	// review and is servable, but is awaiting additional
	// content & policy review.
	//   "APPROVAL_STATUS_APPROVED_SERVABLE" - Both creative & landing page
	// review and
	// content & policy review are approved. The creative is servable.
	//   "APPROVAL_STATUS_REJECTED_NOT_SERVABLE" - There is an issue with
	// the creative that must be fixed before it can serve.
	ApprovalStatus string `json:"approvalStatus,omitempty"`

	// ContentAndPolicyReviewStatus: Content and policy review status for
	// the creative.
	//
	// Possible values:
	//   "REVIEW_STATUS_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "REVIEW_STATUS_APPROVED" - The creative is approved.
	//   "REVIEW_STATUS_REJECTED" - The creative is rejected.
	//   "REVIEW_STATUS_PENDING" - The creative is pending review.
	ContentAndPolicyReviewStatus string `json:"contentAndPolicyReviewStatus,omitempty"`

	// CreativeAndLandingPageReviewStatus: Creative and landing page review
	// status for the creative.
	//
	// Possible values:
	//   "REVIEW_STATUS_UNSPECIFIED" - Type value is not specified or is
	// unknown in this version.
	//   "REVIEW_STATUS_APPROVED" - The creative is approved.
	//   "REVIEW_STATUS_REJECTED" - The creative is rejected.
	//   "REVIEW_STATUS_PENDING" - The creative is pending review.
	CreativeAndLandingPageReviewStatus string `json:"creativeAndLandingPageReviewStatus,omitempty"`

	// ExchangeReviewStatuses: Exchange review statuses for the creative.
	ExchangeReviewStatuses []*ExchangeReviewStatus `json:"exchangeReviewStatuses,omitempty"`

	// PublisherReviewStatuses: Publisher review statuses for the creative.
	PublisherReviewStatuses []*PublisherReviewStatus `json:"publisherReviewStatuses,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApprovalStatus") 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. "ApprovalStatus") 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 *ReviewStatusInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ReviewStatusInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SdfConfig: Structured Data File (SDF) related settings.
type SdfConfig struct {
	// AdminEmail: An administrator email address to which the SDF
	// processing status reports
	// will be sent.
	AdminEmail string `json:"adminEmail,omitempty"`

	// Version: Required. The version of SDF being used.
	//
	// Possible values:
	//   "SDF_VERSION_UNSPECIFIED" - SDF version value is not specified or
	// is unknown in this version.
	//   "SDF_VERSION_3_1" - SDF version 3.1
	//   "SDF_VERSION_4" - SDF version 4
	//   "SDF_VERSION_4_1" - SDF version 4.1
	//   "SDF_VERSION_4_2" - SDF version 4.2
	//   "SDF_VERSION_5" - SDF version 5.
	//   "SDF_VERSION_5_1" - SDF version 5.1
	Version string `json:"version,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdminEmail") 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. "AdminEmail") 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 *SdfConfig) MarshalJSON() ([]byte, error) {
	type NoMethod SdfConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SdfDownloadTask: Type for the response returned
// by [SdfDownloadTaskService.CreateSdfDownloadTask].
type SdfDownloadTask struct {
	// ResourceName: A resource name to be used in
	// media.download to Download the prepared
	// files. Resource names have the
	// format
	// `download/sdfdownloadtasks/media/{media_id}`. `media_id` will be
	// made
	// available by the long running operation service once the task status
	// is
	// done.
	ResourceName string `json:"resourceName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ResourceName") 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. "ResourceName") 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 *SdfDownloadTask) MarshalJSON() ([]byte, error) {
	type NoMethod SdfDownloadTask
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SdfDownloadTaskMetadata: Type for the metadata returned
// by [SdfDownloadTaskService.CreateSdfDownloadTask].
type SdfDownloadTaskMetadata struct {
	// CreateTime: The time when the operation was created.
	CreateTime string `json:"createTime,omitempty"`

	// EndTime: The time when execution was completed.
	EndTime string `json:"endTime,omitempty"`

	// Version: The SDF version used to execute this download task.
	//
	// Possible values:
	//   "SDF_VERSION_UNSPECIFIED" - SDF version value is not specified or
	// is unknown in this version.
	//   "SDF_VERSION_3_1" - SDF version 3.1
	//   "SDF_VERSION_4" - SDF version 4
	//   "SDF_VERSION_4_1" - SDF version 4.1
	//   "SDF_VERSION_4_2" - SDF version 4.2
	//   "SDF_VERSION_5" - SDF version 5.
	//   "SDF_VERSION_5_1" - SDF version 5.1
	Version string `json:"version,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateTime") 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. "CreateTime") 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 *SdfDownloadTaskMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod SdfDownloadTaskMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SensitiveCategoryAssignedTargetingOptionDetails: Targeting details
// for sensitive category. This will be populated in the
// details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION`.
type SensitiveCategoryAssignedTargetingOptionDetails struct {
	// ExcludedTargetingOptionId: Required. ID of the sensitive category to
	// be EXCLUDED.
	ExcludedTargetingOptionId string `json:"excludedTargetingOptionId,omitempty"`

	// SensitiveCategory: Output only. An enum for the DV360 Sensitive
	// category content classifier.
	//
	// Possible values:
	//   "SENSITIVE_CATEGORY_UNSPECIFIED" - This enum is only a placeholder
	// and doesn't specify a DV360 sensitive
	// category.
	//   "SENSITIVE_CATEGORY_ADULT" - Adult or pornographic text, image, or
	// video content.
	//   "SENSITIVE_CATEGORY_DEROGATORY" - Content that may be construed as
	// biased against individuals, groups, or
	// organizations based on criteria such as race, religion, disability,
	// sex,
	// age, veteran status, sexual orientation, gender identity, or
	// political
	// affiliation. May also indicate discussion of such content, for
	// instance,
	// in an academic or journalistic context.
	//   "SENSITIVE_CATEGORY_DOWNLOADS_SHARING" - Content related to audio,
	// video, or software downloads.
	//   "SENSITIVE_CATEGORY_WEAPONS" - Contains content related to personal
	// weapons, including knives, guns,
	// small firearms, and ammunition. Selecting either "weapons"
	// or
	// "sensitive social issues" will result in selecting both.
	//   "SENSITIVE_CATEGORY_GAMBLING" - Contains content related to betting
	// or wagering in a real-world or
	// online setting.
	//   "SENSITIVE_CATEGORY_VIOLENCE" - Content which may be considered
	// graphically violent, gory, gruesome, or
	// shocking, such as street fighting videos, accident photos,
	// descriptions
	// of torture, etc.
	//   "SENSITIVE_CATEGORY_SUGGESTIVE" - Adult content, as well as
	// suggestive content that's not explicitly
	// pornographic. This category includes all pages categorized as adult.
	//   "SENSITIVE_CATEGORY_PROFANITY" - Prominent use of words considered
	// indecent, such as curse words and
	// sexual slang. Pages with only very occasional usage, such as news
	// sites
	// that might include such words in a quotation, are not included.
	//   "SENSITIVE_CATEGORY_ALCOHOL" - Contains content related to
	// alcoholic beverages, alcohol brands,
	// recipes, etc.
	//   "SENSITIVE_CATEGORY_DRUGS" - Contains content related to the
	// recreational use of legal or illegal
	// drugs, as well as to drug paraphernalia or cultivation.
	//   "SENSITIVE_CATEGORY_TOBACCO" - Contains content related to tobacco
	// and tobacco accessories, including
	// lighters, humidors, ashtrays, etc.
	//   "SENSITIVE_CATEGORY_POLITICS" - Political news and media, including
	// discussions of social, governmental,
	// and public policy.
	//   "SENSITIVE_CATEGORY_RELIGION" - Content related to religious
	// thought or beliefs.
	//   "SENSITIVE_CATEGORY_TRAGEDY" - Content related to death, disasters,
	// accidents, war, etc.
	//   "SENSITIVE_CATEGORY_TRANSPORTATION_ACCIDENTS" - Content related to
	// motor vehicle, aviation or other transportation
	// accidents.
	//   "SENSITIVE_CATEGORY_SENSITIVE_SOCIAL_ISSUES" - Issues that evoke
	// strong, opposing views and spark debate. These include
	// issues that are controversial in most countries and markets (such
	// as
	// abortion), as well as those that are controversial in specific
	// countries
	// and markets (such as immigration reform in the United States).
	//   "SENSITIVE_CATEGORY_SHOCKING" - Content which may be considered
	// shocking or disturbing, such as violent
	// news stories, stunts, or toilet humor.
	SensitiveCategory string `json:"sensitiveCategory,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ExcludedTargetingOptionId") 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.
	// "ExcludedTargetingOptionId") 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 *SensitiveCategoryAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod SensitiveCategoryAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SensitiveCategoryTargetingOptionDetails: Represents a targetable
// sensitive category. This will be
// populated in the
// sensitive_category_details
// field of the TargetingOption when
// targeting_type is
// `TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION`.
type SensitiveCategoryTargetingOptionDetails struct {
	// SensitiveCategory: Output only. An enum for the DV360 Sensitive
	// category content classifier.
	//
	// Possible values:
	//   "SENSITIVE_CATEGORY_UNSPECIFIED" - This enum is only a placeholder
	// and doesn't specify a DV360 sensitive
	// category.
	//   "SENSITIVE_CATEGORY_ADULT" - Adult or pornographic text, image, or
	// video content.
	//   "SENSITIVE_CATEGORY_DEROGATORY" - Content that may be construed as
	// biased against individuals, groups, or
	// organizations based on criteria such as race, religion, disability,
	// sex,
	// age, veteran status, sexual orientation, gender identity, or
	// political
	// affiliation. May also indicate discussion of such content, for
	// instance,
	// in an academic or journalistic context.
	//   "SENSITIVE_CATEGORY_DOWNLOADS_SHARING" - Content related to audio,
	// video, or software downloads.
	//   "SENSITIVE_CATEGORY_WEAPONS" - Contains content related to personal
	// weapons, including knives, guns,
	// small firearms, and ammunition. Selecting either "weapons"
	// or
	// "sensitive social issues" will result in selecting both.
	//   "SENSITIVE_CATEGORY_GAMBLING" - Contains content related to betting
	// or wagering in a real-world or
	// online setting.
	//   "SENSITIVE_CATEGORY_VIOLENCE" - Content which may be considered
	// graphically violent, gory, gruesome, or
	// shocking, such as street fighting videos, accident photos,
	// descriptions
	// of torture, etc.
	//   "SENSITIVE_CATEGORY_SUGGESTIVE" - Adult content, as well as
	// suggestive content that's not explicitly
	// pornographic. This category includes all pages categorized as adult.
	//   "SENSITIVE_CATEGORY_PROFANITY" - Prominent use of words considered
	// indecent, such as curse words and
	// sexual slang. Pages with only very occasional usage, such as news
	// sites
	// that might include such words in a quotation, are not included.
	//   "SENSITIVE_CATEGORY_ALCOHOL" - Contains content related to
	// alcoholic beverages, alcohol brands,
	// recipes, etc.
	//   "SENSITIVE_CATEGORY_DRUGS" - Contains content related to the
	// recreational use of legal or illegal
	// drugs, as well as to drug paraphernalia or cultivation.
	//   "SENSITIVE_CATEGORY_TOBACCO" - Contains content related to tobacco
	// and tobacco accessories, including
	// lighters, humidors, ashtrays, etc.
	//   "SENSITIVE_CATEGORY_POLITICS" - Political news and media, including
	// discussions of social, governmental,
	// and public policy.
	//   "SENSITIVE_CATEGORY_RELIGION" - Content related to religious
	// thought or beliefs.
	//   "SENSITIVE_CATEGORY_TRAGEDY" - Content related to death, disasters,
	// accidents, war, etc.
	//   "SENSITIVE_CATEGORY_TRANSPORTATION_ACCIDENTS" - Content related to
	// motor vehicle, aviation or other transportation
	// accidents.
	//   "SENSITIVE_CATEGORY_SENSITIVE_SOCIAL_ISSUES" - Issues that evoke
	// strong, opposing views and spark debate. These include
	// issues that are controversial in most countries and markets (such
	// as
	// abortion), as well as those that are controversial in specific
	// countries
	// and markets (such as immigration reform in the United States).
	//   "SENSITIVE_CATEGORY_SHOCKING" - Content which may be considered
	// shocking or disturbing, such as violent
	// news stories, stunts, or toilet humor.
	SensitiveCategory string `json:"sensitiveCategory,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SensitiveCategory")
	// 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. "SensitiveCategory") 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 *SensitiveCategoryTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod SensitiveCategoryTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Status: The `Status` type defines a logical error model that is
// suitable for
// different programming environments, including REST APIs and RPC APIs.
// It is
// used by [gRPC](https://github.com/grpc). Each `Status` message
// contains
// three pieces of data: error code, error message, and error
// details.
//
// You can find out more about this error model and how to work with it
// in the
// [API Design Guide](https://cloud.google.com/apis/design/errors).
type Status struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details.  There is a
	// common set of
	// message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any
	// user-facing error message should be localized and sent in
	// the
	// google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "Code") 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 *Status) MarshalJSON() ([]byte, error) {
	type NoMethod Status
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubExchangeAssignedTargetingOptionDetails: Details for assigned
// sub-exchange targeting option. This will be populated in
// the details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_SUB_EXCHANGE`.
type SubExchangeAssignedTargetingOptionDetails struct {
	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_SUB_EXCHANGE`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetingOptionId")
	// 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. "TargetingOptionId") 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 *SubExchangeAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod SubExchangeAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubExchangeTargetingOptionDetails: Represents a targetable
// sub-exchange. This will be populated in the
// sub_exchange_details field
// of a TargetingOption when
// targeting_type is
// `TARGETING_TYPE_SUB_EXCHANGE`.
type SubExchangeTargetingOptionDetails struct {
	// DisplayName: Output only. The display name of the sub-exchange.
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") 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. "DisplayName") 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 *SubExchangeTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod SubExchangeTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TargetingOption: Represents a single targeting option, which is a
// targetable concept in
// DV360.
type TargetingOption struct {
	// AgeRangeDetails: Age range details.
	AgeRangeDetails *AgeRangeTargetingOptionDetails `json:"ageRangeDetails,omitempty"`

	// AppCategoryDetails: App category details.
	AppCategoryDetails *AppCategoryTargetingOptionDetails `json:"appCategoryDetails,omitempty"`

	// AuthorizedSellerStatusDetails: Authorized seller status resource
	// details.
	AuthorizedSellerStatusDetails *AuthorizedSellerStatusTargetingOptionDetails `json:"authorizedSellerStatusDetails,omitempty"`

	// BrowserDetails: Browser details.
	BrowserDetails *BrowserTargetingOptionDetails `json:"browserDetails,omitempty"`

	// CarrierAndIspDetails: Carrier and ISP details.
	CarrierAndIspDetails *CarrierAndIspTargetingOptionDetails `json:"carrierAndIspDetails,omitempty"`

	// CategoryDetails: Category resource details.
	CategoryDetails *CategoryTargetingOptionDetails `json:"categoryDetails,omitempty"`

	// ContentInstreamPositionDetails: Content instream position details.
	ContentInstreamPositionDetails *ContentInstreamPositionTargetingOptionDetails `json:"contentInstreamPositionDetails,omitempty"`

	// ContentOutstreamPositionDetails: Content outstream position details.
	ContentOutstreamPositionDetails *ContentOutstreamPositionTargetingOptionDetails `json:"contentOutstreamPositionDetails,omitempty"`

	// DeviceMakeModelDetails: Device make and model resource details.
	DeviceMakeModelDetails *DeviceMakeModelTargetingOptionDetails `json:"deviceMakeModelDetails,omitempty"`

	// DeviceTypeDetails: Device type details.
	DeviceTypeDetails *DeviceTypeTargetingOptionDetails `json:"deviceTypeDetails,omitempty"`

	// DigitalContentLabelDetails: Digital content label details.
	DigitalContentLabelDetails *DigitalContentLabelTargetingOptionDetails `json:"digitalContentLabelDetails,omitempty"`

	// EnvironmentDetails: Environment details.
	EnvironmentDetails *EnvironmentTargetingOptionDetails `json:"environmentDetails,omitempty"`

	// ExchangeDetails: Exchange details.
	ExchangeDetails *ExchangeTargetingOptionDetails `json:"exchangeDetails,omitempty"`

	// GenderDetails: Gender details.
	GenderDetails *GenderTargetingOptionDetails `json:"genderDetails,omitempty"`

	// GeoRegionDetails: Geographic region resource details.
	GeoRegionDetails *GeoRegionTargetingOptionDetails `json:"geoRegionDetails,omitempty"`

	// HouseholdIncomeDetails: Household income details.
	HouseholdIncomeDetails *HouseholdIncomeTargetingOptionDetails `json:"householdIncomeDetails,omitempty"`

	// LanguageDetails: Language resource details.
	LanguageDetails *LanguageTargetingOptionDetails `json:"languageDetails,omitempty"`

	// Name: Output only. The resource name for this targeting option.
	Name string `json:"name,omitempty"`

	// OnScreenPositionDetails: On screen position details.
	OnScreenPositionDetails *OnScreenPositionTargetingOptionDetails `json:"onScreenPositionDetails,omitempty"`

	// OperatingSystemDetails: Operating system resources details.
	OperatingSystemDetails *OperatingSystemTargetingOptionDetails `json:"operatingSystemDetails,omitempty"`

	// ParentalStatusDetails: Parental status details.
	ParentalStatusDetails *ParentalStatusTargetingOptionDetails `json:"parentalStatusDetails,omitempty"`

	// SensitiveCategoryDetails: Sensitive Category details.
	SensitiveCategoryDetails *SensitiveCategoryTargetingOptionDetails `json:"sensitiveCategoryDetails,omitempty"`

	// SubExchangeDetails: Sub-exchange details.
	SubExchangeDetails *SubExchangeTargetingOptionDetails `json:"subExchangeDetails,omitempty"`

	// TargetingOptionId: Output only. A unique identifier for this
	// targeting option. The tuple
	// {`targeting_type`, `targeting_option_id`} will be unique.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// TargetingType: Output only. The type of this targeting option.
	//
	// Possible values:
	//   "TARGETING_TYPE_UNSPECIFIED" - Default value when type is not
	// specified or is unknown in this version.
	//   "TARGETING_TYPE_CHANNEL" - Target a channel (a custom group of
	// related websites or apps).
	//   "TARGETING_TYPE_APP_CATEGORY" - Target an app category (for
	// example, education or puzzle games).
	//   "TARGETING_TYPE_APP" - Target a specific app (for example, Angry
	// Birds).
	//   "TARGETING_TYPE_URL" - Target a specific url (for example,
	// quora.com).
	//   "TARGETING_TYPE_DAY_AND_TIME" - Target ads during a chosen time
	// period on a specific day.
	//   "TARGETING_TYPE_AGE_RANGE" - Target ads to a specific age range
	// (for example, 18-24).
	//   "TARGETING_TYPE_REGIONAL_LOCATION_LIST" - Target ads to the
	// specified regions on a regional location list.
	//   "TARGETING_TYPE_PROXIMITY_LOCATION_LIST" - Target ads to the
	// specified points of interest on a proximity location
	// list.
	//   "TARGETING_TYPE_GENDER" - Target ads to a specific gender (for
	// example, female or male).
	//   "TARGETING_TYPE_VIDEO_PLAYER_SIZE" - Target a specific video player
	// size for video ads.
	//   "TARGETING_TYPE_USER_REWARDED_CONTENT" - Target user rewarded
	// content for video ads.
	//   "TARGETING_TYPE_PARENTAL_STATUS" - Target ads to a specific
	// parental status (for example, parent or not a
	// parent).
	//   "TARGETING_TYPE_CONTENT_INSTREAM_POSITION" - Target video or audio
	// ads in a specific content instream position (for
	// example, pre-roll, mid-roll, or post-roll).
	//   "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION" - Target ads in a
	// specific content outstream position.
	//   "TARGETING_TYPE_DEVICE_TYPE" - Target ads to a specific device type
	// (for example, tablet or connected TV).
	//   "TARGETING_TYPE_AUDIENCE_GROUP" - Target ads to an audience or
	// groups of audiences.
	// Singleton field, at most one can exist on a single Lineitem at a
	// time.
	//   "TARGETING_TYPE_BROWSER" - Target ads to specific web browsers (for
	// example, Chrome).
	//   "TARGETING_TYPE_HOUSEHOLD_INCOME" - Target ads to a specific
	// household income range (for example, top 10%).
	//   "TARGETING_TYPE_ON_SCREEN_POSITION" - Target ads in a specific on
	// screen position.
	//   "TARGETING_TYPE_THIRD_PARTY_VERIFIER" - Filter web sites through
	// third party verification (for example, IAS or
	// DoubleVerify).
	//   "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION" - Filter web sites
	// by specific digital content label ratings (for example,
	// DL-MA: suitable only for mature audiences).
	//   "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION" - Filter website
	// content by sensitive categories (for example, adult).
	//   "TARGETING_TYPE_ENVIRONMENT" - Target ads to a specific environment
	// (for example, web or app).
	//   "TARGETING_TYPE_CARRIER_AND_ISP" - Target ads to a specific network
	// carrier or internet service provider
	// (ISP) (for example, Comcast or Orange).
	//   "TARGETING_TYPE_OPERATING_SYSTEM" - Target ads to a specific
	// operating system (for example, macOS).
	//   "TARGETING_TYPE_DEVICE_MAKE_MODEL" - Target ads to a specific
	// device make or model (for example, Roku or
	// Samsung).
	//   "TARGETING_TYPE_KEYWORD" - Target ads to a specific keyword (for
	// example, dog or retriever).
	//   "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST" - Target ads to a specific
	// negative keyword list.
	//   "TARGETING_TYPE_VIEWABILITY" - Target ads to a specific viewability
	// (for example, 80% viewable).
	//   "TARGETING_TYPE_CATEGORY" - Target ads to a specific content
	// category (for example, arts &
	// entertainment).
	//   "TARGETING_TYPE_INVENTORY_SOURCE" - Purchase impressions from
	// specific deals and auction packages.
	//   "TARGETING_TYPE_LANGUAGE" - Target ads to a specific language (for
	// example, English or Japanese).
	//   "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS" - Target ads to ads.txt
	// authorized sellers.
	//   "TARGETING_TYPE_GEO_REGION" - Target ads to a specific regional
	// location (for example, a city or state).
	//   "TARGETING_TYPE_INVENTORY_SOURCE_GROUP" - Purchase impressions from
	// a group of deals and auction packages.
	//   "TARGETING_TYPE_EXCHANGE" - Purchase impressions from specific
	// exchanges.
	//   "TARGETING_TYPE_SUB_EXCHANGE" - Purchase impressions from specific
	// sub-exchanges.
	TargetingType string `json:"targetingType,omitempty"`

	// UserRewardedContentDetails: User rewarded content details.
	UserRewardedContentDetails *UserRewardedContentTargetingOptionDetails `json:"userRewardedContentDetails,omitempty"`

	// VideoPlayerSizeDetails: Video player size details.
	VideoPlayerSizeDetails *VideoPlayerSizeTargetingOptionDetails `json:"videoPlayerSizeDetails,omitempty"`

	// ViewabilityDetails: Viewability resource details.
	ViewabilityDetails *ViewabilityTargetingOptionDetails `json:"viewabilityDetails,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "AgeRangeDetails") 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. "AgeRangeDetails") 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 *TargetingOption) MarshalJSON() ([]byte, error) {
	type NoMethod TargetingOption
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ThirdPartyOnlyConfig: Settings for advertisers that use third-party
// ad servers only.
type ThirdPartyOnlyConfig struct {
	// PixelOrderIdReportingEnabled: Whether or not order ID reporting for
	// pixels is enabled.
	// This value cannot be changed once set to `true`.
	PixelOrderIdReportingEnabled bool `json:"pixelOrderIdReportingEnabled,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PixelOrderIdReportingEnabled") 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.
	// "PixelOrderIdReportingEnabled") 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 *ThirdPartyOnlyConfig) MarshalJSON() ([]byte, error) {
	type NoMethod ThirdPartyOnlyConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ThirdPartyUrl: Tracking URLs from third parties to track interactions
// with an audio or a
// video creative.
type ThirdPartyUrl struct {
	// Type: The type of interaction needs to be tracked by the tracking URL
	//
	// Possible values:
	//   "THIRD_PARTY_URL_TYPE_UNSPECIFIED" - The type of third-party URL is
	// unspecified or is unknown in this version.
	//   "THIRD_PARTY_URL_TYPE_IMPRESSION" - Used to count impressions of
	// the creative after the audio or video
	// buffering is complete.
	//   "THIRD_PARTY_URL_TYPE_CLICK_TRACKING" - Used to track user clicks
	// on the audio or video.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_START" - Used to track the number
	// of times a user starts the audio or video.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_FIRST_QUARTILE" - Used to track
	// the number of times the audio or video plays to 25% of its
	// length.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_MIDPOINT" - Used to track the
	// number of times the audio or video plays to 50% of its
	// length.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_THIRD_QUARTILE" - Used to track
	// the number of times the audio or video plays to 75% of its
	// length.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_COMPLETE" - Used to track the
	// number of times the audio or video plays to the end.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_MUTE" - Used to track the number
	// of times a user mutes the audio or video.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_PAUSE" - Used to track the number
	// of times a user pauses the audio or video.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_REWIND" - Used to track the
	// number of times a user replays the audio or video.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_FULLSCREEN" - Used to track the
	// number of times a user expands the player to
	// full-screen size.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_STOP" - Used to track the number
	// of times a user stops the audio or video.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_CUSTOM" - Used to track the
	// number of times a user performs a custom click,
	// such as clicking on a video hot spot.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_SKIP" - Used to track the number
	// of times the audio or video was skipped.
	//   "THIRD_PARTY_URL_TYPE_AUDIO_VIDEO_PROGRESS" - Used to track the
	// number of times the audio or video plays to an offset
	// determined by the progress_offset.
	Type string `json:"type,omitempty"`

	// Url: Tracking URL used to track the interaction.
	//
	// Provide a URL with optional path or query string, beginning with
	// `https:`.
	// For example, https://www.example.com/path
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Type") 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. "Type") 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 *ThirdPartyUrl) MarshalJSON() ([]byte, error) {
	type NoMethod ThirdPartyUrl
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ThirdPartyVerifierAssignedTargetingOptionDetails: Assigned third
// party verifier targeting option details. This will be
// populated in the details field of an AssignedTargetingOption
// when
// targeting_type is
// `TARGETING_TYPE_THIRD_PARTY_VERIFIER`.
type ThirdPartyVerifierAssignedTargetingOptionDetails struct {
	// Adloox: Third party brand verifier -- Adloox.
	Adloox *Adloox `json:"adloox,omitempty"`

	// DoubleVerify: Third party brand verifier -- DoubleVerify.
	DoubleVerify *DoubleVerify `json:"doubleVerify,omitempty"`

	// IntegralAdScience: Third party brand verifier -- Integral Ad Science.
	IntegralAdScience *IntegralAdScience `json:"integralAdScience,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Adloox") 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. "Adloox") 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 *ThirdPartyVerifierAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ThirdPartyVerifierAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TimeRange: A time range.
type TimeRange struct {
	// EndTime: Required. The upper bound of a time range, inclusive.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: Required. The lower bound of a time range, inclusive.
	StartTime string `json:"startTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndTime") to
	// unconditionally include in API requests. By default, fields with
	// empty 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. "EndTime") 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 *TimeRange) MarshalJSON() ([]byte, error) {
	type NoMethod TimeRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TimerEvent: Timer event of the creative.
type TimerEvent struct {
	// Name: Required. The name of the timer event.
	Name string `json:"name,omitempty"`

	// ReportingName: Required. The name used to identify this timer event
	// in reports.
	ReportingName string `json:"reportingName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") 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. "Name") 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 *TimerEvent) MarshalJSON() ([]byte, error) {
	type NoMethod TimerEvent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TrackingFloodlightActivityConfig: Settings that control the behavior
// of a single Floodlight activity config.
type TrackingFloodlightActivityConfig struct {
	// FloodlightActivityId: Required. The ID of the Floodlight activity.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// PostClickLookbackWindowDays: Required. The number of days after an ad
	// has been clicked in which a
	// conversion may be counted.
	// Must be between 0 and 90 inclusive.
	PostClickLookbackWindowDays int64 `json:"postClickLookbackWindowDays,omitempty"`

	// PostViewLookbackWindowDays: Required. The number of days after an ad
	// has been viewed in which a
	// conversion may be counted.
	// Must be between 0 and 90 inclusive.
	PostViewLookbackWindowDays int64 `json:"postViewLookbackWindowDays,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "FloodlightActivityId") 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. "FloodlightActivityId") 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 *TrackingFloodlightActivityConfig) MarshalJSON() ([]byte, error) {
	type NoMethod TrackingFloodlightActivityConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Transcode: Represents information about the transcoded audio or video
// file.
type Transcode struct {
	// AudioBitRateKbps: The bit rate for the audio stream of the transcoded
	// video, or the bit rate
	// for the transcoded audio, in kilobits per second.
	AudioBitRateKbps int64 `json:"audioBitRateKbps,omitempty,string"`

	// AudioSampleRateHz: The sample rate for the audio stream of the
	// transcoded video, or the sample
	// rate for the transcoded audio, in hertz.
	AudioSampleRateHz int64 `json:"audioSampleRateHz,omitempty,string"`

	// BitRateKbps: The transcoding bit rate of the transcoded video, in
	// kilobits per second.
	BitRateKbps int64 `json:"bitRateKbps,omitempty,string"`

	// Dimensions: The dimensions of the transcoded video.
	Dimensions *Dimensions `json:"dimensions,omitempty"`

	// FileSizeBytes: The size of the transcoded file, in bytes.
	FileSizeBytes int64 `json:"fileSizeBytes,omitempty,string"`

	// FrameRate: The frame rate of the transcoded video, in frames per
	// second.
	FrameRate float64 `json:"frameRate,omitempty"`

	// MimeType: The MIME type of the transcoded file.
	MimeType string `json:"mimeType,omitempty"`

	// Name: The name of the transcoded file.
	Name string `json:"name,omitempty"`

	// Transcoded: Indicates if the transcoding was successful.
	Transcoded bool `json:"transcoded,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AudioBitRateKbps") 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. "AudioBitRateKbps") 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 *Transcode) MarshalJSON() ([]byte, error) {
	type NoMethod Transcode
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// UniversalAdId: A creative identifier provided by a registry that is
// unique across all
// platforms. This is part of the VAST 4.0 standard.
type UniversalAdId struct {
	// Id: The unique creative identifier.
	Id string `json:"id,omitempty"`

	// Registry: The registry provides unique creative identifiers.
	//
	// Possible values:
	//   "UNIVERSAL_AD_REGISTRY_UNSPECIFIED" - The Universal Ad registry is
	// unspecified or is unknown in this version.
	//   "UNIVERSAL_AD_REGISTRY_OTHER" - Use a custom provider to provide
	// the Universal Ad ID.
	//   "UNIVERSAL_AD_REGISTRY_AD_ID" - Use Ad-ID to provide the Universal
	// Ad ID.
	//   "UNIVERSAL_AD_REGISTRY_CLEARCAST" - Use clearcast.co.uk to provide
	// the Universal Ad ID.
	//   "UNIVERSAL_AD_REGISTRY_DV360" - Use Display & Video 360 to provide
	// the Universal Ad ID.
	//   "UNIVERSAL_AD_REGISTRY_CM" - Use Campaign Manager to provide the
	// Universal Ad ID.
	Registry string `json:"registry,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") 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. "Id") 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 *UniversalAdId) MarshalJSON() ([]byte, error) {
	type NoMethod UniversalAdId
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UrlAssignedTargetingOptionDetails: Details for assigned URL targeting
// option. This will be populated in the
// details field of an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_URL`.
type UrlAssignedTargetingOptionDetails struct {
	// Negative: Indicates if this option is being negatively targeted.
	Negative bool `json:"negative,omitempty"`

	// Url: Required. The URL, for example `example.com`.
	//
	// DV360 supports two levels of subdirectory targeting, for
	// example
	// `www.example.com/one-subdirectory-level/second-level`, and five
	// levels of
	// subdomain targeting, for example
	// `five.four.three.two.one.example.com`.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Negative") 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. "Negative") 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 *UrlAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod UrlAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UserRewardedContentAssignedTargetingOptionDetails: User rewarded
// content targeting option details. This will be populated
// in
// the
// user_rewarded_content_details
// field when
// targeting_type is
// `TARGETING_TYPE_USER_REWARDED_CONTENT`.
type UserRewardedContentAssignedTargetingOptionDetails struct {
	// TargetingOptionId: Required. The targeting_option_id field
	// when
	// targeting_type is
	// `TARGETING_TYPE_USER_REWARDED_CONTENT`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// UserRewardedContent: Output only. User rewarded content status for
	// video ads.
	//
	// Possible values:
	//   "USER_REWARDED_CONTENT_UNSPECIFIED" - User rewarded content is not
	// specified or is unknown in this version.
	//   "USER_REWARDED_CONTENT_USER_REWARDED" - Represents ads where the
	// user will see a reward after viewing.
	//   "USER_REWARDED_CONTENT_NOT_USER_REWARDED" - Represents all other
	// ads besides user-rewarded.
	UserRewardedContent string `json:"userRewardedContent,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetingOptionId")
	// 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. "TargetingOptionId") 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 *UserRewardedContentAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod UserRewardedContentAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UserRewardedContentTargetingOptionDetails: Represents a targetable
// user rewarded content status for video ads only. This
// will be populated in the
// user_rewarded_content_details
// field when
// targeting_type is
// `TARGETING_TYPE_USER_REWARDED_CONTENT`.
type UserRewardedContentTargetingOptionDetails struct {
	// UserRewardedContent: Output only. User rewarded content status for
	// video ads.
	//
	// Possible values:
	//   "USER_REWARDED_CONTENT_UNSPECIFIED" - User rewarded content is not
	// specified or is unknown in this version.
	//   "USER_REWARDED_CONTENT_USER_REWARDED" - Represents ads where the
	// user will see a reward after viewing.
	//   "USER_REWARDED_CONTENT_NOT_USER_REWARDED" - Represents all other
	// ads besides user-rewarded.
	UserRewardedContent string `json:"userRewardedContent,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UserRewardedContent")
	// 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. "UserRewardedContent") 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 *UserRewardedContentTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod UserRewardedContentTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VideoPlayerSizeAssignedTargetingOptionDetails: Video player size
// targeting option details. This will be populated in
// the
// video_player_size_details
// field when targeting_type
// is
// `TARGETING_TYPE_VIDEO_PLAYER_SIZE`.
// Explicitly targeting all options is not supported. Remove all video
// player
// size targeting options to achieve this effect.
type VideoPlayerSizeAssignedTargetingOptionDetails struct {
	// TargetingOptionId: Required. The targeting_option_id field
	// when
	// targeting_type is
	// `TARGETING_TYPE_VIDEO_PLAYER_SIZE`.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// VideoPlayerSize: Output only. The video player size.
	//
	// Possible values:
	//   "VIDEO_PLAYER_SIZE_UNSPECIFIED" - Video player size is not
	// specified in this version. This enum is a place
	// holder for a default value and does not represent a real video player
	// size.
	//   "VIDEO_PLAYER_SIZE_SMALL" - The dimensions of the video player are
	// less than 400×300 (desktop), or up
	// to 20% of screen covered (mobile).
	//   "VIDEO_PLAYER_SIZE_LARGE" - The dimensions of the video player are
	// between 400x300 and 1280x720 pixels
	// (desktop), or 20% to 90% of the screen covered (mobile).
	//   "VIDEO_PLAYER_SIZE_HD" - The dimensions of the video player are
	// 1280×720 or greater (desktop), or
	// over 90% of the screen covered (mobile).
	//   "VIDEO_PLAYER_SIZE_UNKNOWN" - The dimensions of the video player
	// are unknown.
	VideoPlayerSize string `json:"videoPlayerSize,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetingOptionId")
	// 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. "TargetingOptionId") 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 *VideoPlayerSizeAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod VideoPlayerSizeAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VideoPlayerSizeTargetingOptionDetails: Represents a targetable video
// player size. This will be populated in
// the
// video_player_size_details
// field when targeting_type is
// `TARGETING_TYPE_VIDEO_PLAYER_SIZE`.
type VideoPlayerSizeTargetingOptionDetails struct {
	// VideoPlayerSize: Output only. The video player size.
	//
	// Possible values:
	//   "VIDEO_PLAYER_SIZE_UNSPECIFIED" - Video player size is not
	// specified in this version. This enum is a place
	// holder for a default value and does not represent a real video player
	// size.
	//   "VIDEO_PLAYER_SIZE_SMALL" - The dimensions of the video player are
	// less than 400×300 (desktop), or up
	// to 20% of screen covered (mobile).
	//   "VIDEO_PLAYER_SIZE_LARGE" - The dimensions of the video player are
	// between 400x300 and 1280x720 pixels
	// (desktop), or 20% to 90% of the screen covered (mobile).
	//   "VIDEO_PLAYER_SIZE_HD" - The dimensions of the video player are
	// 1280×720 or greater (desktop), or
	// over 90% of the screen covered (mobile).
	//   "VIDEO_PLAYER_SIZE_UNKNOWN" - The dimensions of the video player
	// are unknown.
	VideoPlayerSize string `json:"videoPlayerSize,omitempty"`

	// ForceSendFields is a list of field names (e.g. "VideoPlayerSize") 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. "VideoPlayerSize") 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 *VideoPlayerSizeTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod VideoPlayerSizeTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ViewabilityAssignedTargetingOptionDetails: Assigned viewability
// targeting option details. This will be populated in
// the
// viewability_details field of
// an AssignedTargetingOption when
// targeting_type is
// `TARGETING_TYPE_VIEWABILITY`.
type ViewabilityAssignedTargetingOptionDetails struct {
	// TargetingOptionId: Required. The targeting_option_id of
	// a
	// TargetingOption of type `TARGETING_TYPE_VIEWABILITY` (e.g.,
	// "509010"
	// for targeting the `VIEWABILITY_10_PERCENT_OR_MORE` option).
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

	// Viewability: Output only. The predicted viewability percentage.
	//
	// Possible values:
	//   "VIEWABILITY_UNSPECIFIED" - Default value when viewability is not
	// specified in this version. This enum
	// is a placeholder for default value and does not represent a
	// real
	// viewability option.
	//   "VIEWABILITY_10_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 10% likely to be viewable.
	//   "VIEWABILITY_20_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 20% likely to be viewable.
	//   "VIEWABILITY_30_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 30% likely to be viewable.
	//   "VIEWABILITY_40_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 40% likely to be viewable.
	//   "VIEWABILITY_50_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 50% likely to be viewable.
	//   "VIEWABILITY_60_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 60% likely to be viewable.
	//   "VIEWABILITY_70_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 70% likely to be viewable.
	//   "VIEWABILITY_80_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 80% likely to be viewable.
	//   "VIEWABILITY_90_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 90% likely to be viewable.
	Viewability string `json:"viewability,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TargetingOptionId")
	// 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. "TargetingOptionId") 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 *ViewabilityAssignedTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ViewabilityAssignedTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ViewabilityTargetingOptionDetails: Represents a targetable
// viewability. This will be populated in the
// viewability_details field of a
// TargetingOption when targeting_type is
// `TARGETING_TYPE_VIEWABILITY`.
type ViewabilityTargetingOptionDetails struct {
	// Viewability: Output only. The predicted viewability percentage.
	//
	// Possible values:
	//   "VIEWABILITY_UNSPECIFIED" - Default value when viewability is not
	// specified in this version. This enum
	// is a placeholder for default value and does not represent a
	// real
	// viewability option.
	//   "VIEWABILITY_10_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 10% likely to be viewable.
	//   "VIEWABILITY_20_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 20% likely to be viewable.
	//   "VIEWABILITY_30_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 30% likely to be viewable.
	//   "VIEWABILITY_40_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 40% likely to be viewable.
	//   "VIEWABILITY_50_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 50% likely to be viewable.
	//   "VIEWABILITY_60_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 60% likely to be viewable.
	//   "VIEWABILITY_70_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 70% likely to be viewable.
	//   "VIEWABILITY_80_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 80% likely to be viewable.
	//   "VIEWABILITY_90_PERCENT_OR_MORE" - Bid only on impressions that are
	// at least 90% likely to be viewable.
	Viewability string `json:"viewability,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Viewability") 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. "Viewability") 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 *ViewabilityTargetingOptionDetails) MarshalJSON() ([]byte, error) {
	type NoMethod ViewabilityTargetingOptionDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "displayvideo.advertisers.bulkEditAdvertiserAssignedTargetingOptions":

type AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall struct {
	s                                                 *Service
	advertiserId                                      int64
	bulkeditadvertiserassignedtargetingoptionsrequest *BulkEditAdvertiserAssignedTargetingOptionsRequest
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// BulkEditAdvertiserAssignedTargetingOptions: Bulk edits targeting
// options under a single advertiser.
// The operation will delete the assigned targeting options provided
// in
// BulkEditAdvertiserAssignedTargetingOptionsRequest.delete_requests
// and
// then create the assigned targeting options provided
// in
// BulkEditAdvertiserAssignedTargetingOptionsRequest.create_requests .
func (r *AdvertisersService) BulkEditAdvertiserAssignedTargetingOptions(advertiserId int64, bulkeditadvertiserassignedtargetingoptionsrequest *BulkEditAdvertiserAssignedTargetingOptionsRequest) *AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall {
	c := &AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.bulkeditadvertiserassignedtargetingoptionsrequest = bulkeditadvertiserassignedtargetingoptionsrequest
	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 *AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall) Fields(s ...googleapi.Field) *AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall {
	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 *AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall) Context(ctx context.Context) *AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall {
	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 *AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.bulkeditadvertiserassignedtargetingoptionsrequest)
	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/advertisers/{+advertiserId}:bulkEditAdvertiserAssignedTargetingOptions")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.bulkEditAdvertiserAssignedTargetingOptions" call.
// Exactly one of *BulkEditAdvertiserAssignedTargetingOptionsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *BulkEditAdvertiserAssignedTargetingOptionsResponse.ServerResponse.Hea
// der 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 *AdvertisersBulkEditAdvertiserAssignedTargetingOptionsCall) Do(opts ...googleapi.CallOption) (*BulkEditAdvertiserAssignedTargetingOptionsResponse, 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 := &BulkEditAdvertiserAssignedTargetingOptionsResponse{
		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": "Bulk edits targeting options under a single advertiser.\nThe operation will delete the assigned targeting options provided in\nBulkEditAdvertiserAssignedTargetingOptionsRequest.delete_requests and\nthen create the assigned targeting options provided in\nBulkEditAdvertiserAssignedTargetingOptionsRequest.create_requests .",
	//   "flatPath": "v1/advertisers/{advertisersId}:bulkEditAdvertiserAssignedTargetingOptions",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.bulkEditAdvertiserAssignedTargetingOptions",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}:bulkEditAdvertiserAssignedTargetingOptions",
	//   "request": {
	//     "$ref": "BulkEditAdvertiserAssignedTargetingOptionsRequest"
	//   },
	//   "response": {
	//     "$ref": "BulkEditAdvertiserAssignedTargetingOptionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.bulkListAdvertiserAssignedTargetingOptions":

type AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// BulkListAdvertiserAssignedTargetingOptions: Lists assigned targeting
// options of an advertiser across targeting types.
func (r *AdvertisersService) BulkListAdvertiserAssignedTargetingOptions(advertiserId int64) *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall {
	c := &AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// assigned targeting option properties.
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by the logical operator `OR`..
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `targetingType`
//
// Examples:
//
// * targetingType with value
// TARGETING_TYPE_CHANNEL
// `targetingType="TARGETING_TYPE_CHANNEL"
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) Filter(filter string) *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `targetingType` (default)
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `targetingType desc`.
func (c *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) OrderBy(orderBy string) *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page
// size.
// The size must be an integer between `1` and `5000`. If
// unspecified,
// the default is '5000'. Returns error code `INVALID_ARGUMENT` if an
// invalid
// value is specified.
func (c *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) PageSize(pageSize int64) *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token that lets
// the client fetch the next page of results.
// Typically, this is the value of
// next_page_token
// returned from the previous call
// to
// `BulkListAdvertiserAssignedTargetingOptions` method.
// If not specified, the first page of results will be returned.
func (c *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) PageToken(pageToken string) *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall {
	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 *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) Fields(s ...googleapi.Field) *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall {
	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 *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) IfNoneMatch(entityTag string) *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall {
	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 *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) Context(ctx context.Context) *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall {
	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 *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}:bulkListAdvertiserAssignedTargetingOptions")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.bulkListAdvertiserAssignedTargetingOptions" call.
// Exactly one of *BulkListAdvertiserAssignedTargetingOptionsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *BulkListAdvertiserAssignedTargetingOptionsResponse.ServerResponse.Hea
// der 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 *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) Do(opts ...googleapi.CallOption) (*BulkListAdvertiserAssignedTargetingOptionsResponse, 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 := &BulkListAdvertiserAssignedTargetingOptionsResponse{
		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 assigned targeting options of an advertiser across targeting types.",
	//   "flatPath": "v1/advertisers/{advertisersId}:bulkListAdvertiserAssignedTargetingOptions",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.bulkListAdvertiserAssignedTargetingOptions",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by assigned targeting option properties.\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by the logical operator `OR`..\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `targetingType`\n\nExamples:\n\n* targetingType with value TARGETING_TYPE_CHANNEL\n`targetingType=\"TARGETING_TYPE_CHANNEL\"`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `targetingType` (default)\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`targetingType desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size.\nThe size must be an integer between `1` and `5000`. If unspecified,\nthe default is '5000'. Returns error code `INVALID_ARGUMENT` if an invalid\nvalue is specified.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token that lets the client fetch the next page of results.\nTypically, this is the value of\nnext_page_token\nreturned from the previous call to\n`BulkListAdvertiserAssignedTargetingOptions` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}:bulkListAdvertiserAssignedTargetingOptions",
	//   "response": {
	//     "$ref": "BulkListAdvertiserAssignedTargetingOptionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersBulkListAdvertiserAssignedTargetingOptionsCall) Pages(ctx context.Context, f func(*BulkListAdvertiserAssignedTargetingOptionsResponse) 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 "displayvideo.advertisers.create":

type AdvertisersCreateCall struct {
	s          *Service
	advertiser *Advertiser
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a new advertiser.
// Returns the newly created advertiser if successful.
// This method can take up to 180 seconds to complete.
func (r *AdvertisersService) Create(advertiser *Advertiser) *AdvertisersCreateCall {
	c := &AdvertisersCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiser = advertiser
	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 *AdvertisersCreateCall) Fields(s ...googleapi.Field) *AdvertisersCreateCall {
	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 *AdvertisersCreateCall) Context(ctx context.Context) *AdvertisersCreateCall {
	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 *AdvertisersCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.advertiser)
	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/advertisers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.create" call.
// Exactly one of *Advertiser or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Advertiser.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 *AdvertisersCreateCall) Do(opts ...googleapi.CallOption) (*Advertiser, 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 := &Advertiser{
		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 new advertiser.\nReturns the newly created advertiser if successful.\nThis method can take up to 180 seconds to complete.",
	//   "flatPath": "v1/advertisers",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/advertisers",
	//   "request": {
	//     "$ref": "Advertiser"
	//   },
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.delete":

type AdvertisersDeleteCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Delete: Deletes an advertiser.
// Deleting an advertiser will delete all of its child resources, for
// example,
// campaigns, insertion orders and line items.
// A deleted advertiser cannot be recovered.
func (r *AdvertisersService) Delete(advertiserId int64) *AdvertisersDeleteCall {
	c := &AdvertisersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	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 *AdvertisersDeleteCall) Fields(s ...googleapi.Field) *AdvertisersDeleteCall {
	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 *AdvertisersDeleteCall) Context(ctx context.Context) *AdvertisersDeleteCall {
	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 *AdvertisersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "displayvideo.advertisers.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AdvertisersDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Empty{
		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": "Deletes an advertiser.\nDeleting an advertiser will delete all of its child resources, for example,\ncampaigns, insertion orders and line items.\nA deleted advertiser cannot be recovered.",
	//   "flatPath": "v1/advertisers/{advertisersId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.delete",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser we need to delete.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.get":

type AdvertisersGetCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets an advertiser.
func (r *AdvertisersService) Get(advertiserId int64) *AdvertisersGetCall {
	c := &AdvertisersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	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 *AdvertisersGetCall) Fields(s ...googleapi.Field) *AdvertisersGetCall {
	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 *AdvertisersGetCall) IfNoneMatch(entityTag string) *AdvertisersGetCall {
	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 *AdvertisersGetCall) Context(ctx context.Context) *AdvertisersGetCall {
	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 *AdvertisersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.get" call.
// Exactly one of *Advertiser or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Advertiser.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 *AdvertisersGetCall) Do(opts ...googleapi.CallOption) (*Advertiser, 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 := &Advertiser{
		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 an advertiser.",
	//   "flatPath": "v1/advertisers/{advertisersId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.get",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}",
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.list":

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

// List: Lists advertisers that are accessible to the current user.
//
// The order is defined by the order_by
// parameter.
//
// A single partner_id is required.
// Cross-partner listing is not supported.
func (r *AdvertisersService) List() *AdvertisersListCall {
	c := &AdvertisersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// advertiser properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by `AND` or `OR` logical operators.
// A
// sequence of restrictions implicitly uses `AND`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `entityStatus`
//
// Examples:
//
// * All active advertisers under a
// partner:
// `entityStatus="ENTITY_STATUS_ACTIVE"
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersListCall) Filter(filter string) *AdvertisersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `displayName` (default)
// * `entityStatus`
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name. For
// example,
// `displayName desc`.
func (c *AdvertisersListCall) OrderBy(orderBy string) *AdvertisersListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`.
func (c *AdvertisersListCall) PageSize(pageSize int64) *AdvertisersListCall {
	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
// next_page_token
// returned from the previous call to `ListAdvertisers` method.
// If not specified, the first page of results will be returned.
func (c *AdvertisersListCall) PageToken(pageToken string) *AdvertisersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": Required. The ID
// of the partner that the fetched advertisers should all belong to.
// The system only supports listing advertisers for one partner at a
// time.
func (c *AdvertisersListCall) PartnerId(partnerId int64) *AdvertisersListCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *AdvertisersListCall) Fields(s ...googleapi.Field) *AdvertisersListCall {
	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 *AdvertisersListCall) IfNoneMatch(entityTag string) *AdvertisersListCall {
	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 *AdvertisersListCall) Context(ctx context.Context) *AdvertisersListCall {
	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 *AdvertisersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.list" call.
// Exactly one of *ListAdvertisersResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListAdvertisersResponse.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 *AdvertisersListCall) Do(opts ...googleapi.CallOption) (*ListAdvertisersResponse, 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 := &ListAdvertisersResponse{
		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 advertisers that are accessible to the current user.\n\nThe order is defined by the order_by\nparameter.\n\nA single partner_id is required.\nCross-partner listing is not supported.",
	//   "flatPath": "v1/advertisers",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "filter": {
	//       "description": "Allows filtering by advertiser properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by `AND` or `OR` logical operators. A\nsequence of restrictions implicitly uses `AND`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `entityStatus`\n\nExamples:\n\n* All active advertisers under a partner:\n`entityStatus=\"ENTITY_STATUS_ACTIVE\"`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `displayName` (default)\n* `entityStatus`\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. For example,\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListAdvertisers` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "Required. The ID of the partner that the fetched advertisers should all belong to.\nThe system only supports listing advertisers for one partner at a time.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers",
	//   "response": {
	//     "$ref": "ListAdvertisersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersListCall) Pages(ctx context.Context, f func(*ListAdvertisersResponse) 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 "displayvideo.advertisers.patch":

type AdvertisersPatchCall struct {
	s            *Service
	advertiserId int64
	advertiser   *Advertiser
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Patch: Updates an existing advertiser.
// Returns the updated advertiser if successful.
func (r *AdvertisersService) Patch(advertiserId int64, advertiser *Advertiser) *AdvertisersPatchCall {
	c := &AdvertisersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.advertiser = advertiser
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *AdvertisersPatchCall) UpdateMask(updateMask string) *AdvertisersPatchCall {
	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 *AdvertisersPatchCall) Fields(s ...googleapi.Field) *AdvertisersPatchCall {
	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 *AdvertisersPatchCall) Context(ctx context.Context) *AdvertisersPatchCall {
	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 *AdvertisersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.advertiser)
	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/advertisers/{+advertiserId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.patch" call.
// Exactly one of *Advertiser or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Advertiser.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 *AdvertisersPatchCall) Do(opts ...googleapi.CallOption) (*Advertiser, 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 := &Advertiser{
		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 an existing advertiser.\nReturns the updated advertiser if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.advertisers.patch",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Required. The mask to control which fields to update.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}",
	//   "request": {
	//     "$ref": "Advertiser"
	//   },
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.assets.upload":

type AdvertisersAssetsUploadCall struct {
	s                  *Service
	advertiserId       int64
	createassetrequest *CreateAssetRequest
	urlParams_         gensupport.URLParams
	mediaInfo_         *gensupport.MediaInfo
	ctx_               context.Context
	header_            http.Header
}

// Upload: Uploads an asset.
// Returns the ID of the newly uploaded asset if successful.
// The asset file size should be no more than 10 MB for images, 200 MB
// for
// ZIP files, and 1 GB for videos.
func (r *AdvertisersAssetsService) Upload(advertiserId int64, createassetrequest *CreateAssetRequest) *AdvertisersAssetsUploadCall {
	c := &AdvertisersAssetsUploadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.createassetrequest = createassetrequest
	return c
}

// Media specifies the media to upload in one or more chunks. The chunk
// size may be controlled by supplying a MediaOption generated by
// googleapi.ChunkSize. The chunk size defaults to
// googleapi.DefaultUploadChunkSize.The Content-Type header used in the
// upload request will be determined by sniffing the contents of r,
// unless a MediaOption generated by googleapi.ContentType is
// supplied.
// At most one of Media and ResumableMedia may be set.
func (c *AdvertisersAssetsUploadCall) Media(r io.Reader, options ...googleapi.MediaOption) *AdvertisersAssetsUploadCall {
	c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options)
	return c
}

// ResumableMedia specifies the media to upload in chunks and can be
// canceled with ctx.
//
// Deprecated: use Media instead.
//
// At most one of Media and ResumableMedia may be set. mediaType
// identifies the MIME media type of the upload, such as "image/png". If
// mediaType is "", it will be auto-detected. The provided ctx will
// supersede any context previously provided to the Context method.
func (c *AdvertisersAssetsUploadCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *AdvertisersAssetsUploadCall {
	c.ctx_ = ctx
	c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType)
	return c
}

// ProgressUpdater provides a callback function that will be called
// after every chunk. It should be a low-latency function in order to
// not slow down the upload operation. This should only be called when
// using ResumableMedia (as opposed to Media).
func (c *AdvertisersAssetsUploadCall) ProgressUpdater(pu googleapi.ProgressUpdater) *AdvertisersAssetsUploadCall {
	c.mediaInfo_.SetProgressUpdater(pu)
	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 *AdvertisersAssetsUploadCall) Fields(s ...googleapi.Field) *AdvertisersAssetsUploadCall {
	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.
// This context will supersede any context previously provided to the
// ResumableMedia method.
func (c *AdvertisersAssetsUploadCall) Context(ctx context.Context) *AdvertisersAssetsUploadCall {
	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 *AdvertisersAssetsUploadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersAssetsUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.createassetrequest)
	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/advertisers/{+advertiserId}/assets")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/v1/advertisers/{+advertiserId}/assets")
		c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())
	}
	if body == nil {
		body = new(bytes.Buffer)
		reqHeaders.Set("Content-Type", "application/json")
	}
	body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)
	defer cleanup()
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	req.GetBody = getBody
	googleapi.Expand(req.URL, map[string]string{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.assets.upload" call.
// Exactly one of *CreateAssetResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreateAssetResponse.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 *AdvertisersAssetsUploadCall) Do(opts ...googleapi.CallOption) (*CreateAssetResponse, 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
	}
	rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))
	if rx != nil {
		rx.Client = c.s.client
		rx.UserAgent = c.s.userAgent()
		ctx := c.ctx_
		if ctx == nil {
			ctx = context.TODO()
		}
		res, err = rx.Upload(ctx)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		if err := googleapi.CheckResponse(res); err != nil {
			return nil, err
		}
	}
	ret := &CreateAssetResponse{
		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": "Uploads an asset.\nReturns the ID of the newly uploaded asset if successful.\nThe asset file size should be no more than 10 MB for images, 200 MB for\nZIP files, and 1 GB for videos.",
	//   "flatPath": "v1/advertisers/{advertisersId}/assets",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.assets.upload",
	//   "mediaUpload": {
	//     "accept": [
	//       "*/*"
	//     ],
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/v1/advertisers/{+advertiserId}/assets"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser this asset belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/assets",
	//   "request": {
	//     "$ref": "CreateAssetRequest"
	//   },
	//   "response": {
	//     "$ref": "CreateAssetResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "displayvideo.advertisers.campaigns.create":

type AdvertisersCampaignsCreateCall struct {
	s            *Service
	advertiserId int64
	campaign     *Campaign
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a new campaign.
// Returns the newly created campaign if successful.
func (r *AdvertisersCampaignsService) Create(advertiserId int64, campaign *Campaign) *AdvertisersCampaignsCreateCall {
	c := &AdvertisersCampaignsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.campaign = campaign
	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 *AdvertisersCampaignsCreateCall) Fields(s ...googleapi.Field) *AdvertisersCampaignsCreateCall {
	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 *AdvertisersCampaignsCreateCall) Context(ctx context.Context) *AdvertisersCampaignsCreateCall {
	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 *AdvertisersCampaignsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCampaignsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.campaign)
	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/advertisers/{+advertiserId}/campaigns")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.campaigns.create" call.
// Exactly one of *Campaign or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Campaign.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 *AdvertisersCampaignsCreateCall) Do(opts ...googleapi.CallOption) (*Campaign, 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 := &Campaign{
		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 new campaign.\nReturns the newly created campaign if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/campaigns",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.campaigns.create",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser the campaign belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/campaigns",
	//   "request": {
	//     "$ref": "Campaign"
	//   },
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.campaigns.delete":

type AdvertisersCampaignsDeleteCall struct {
	s            *Service
	advertiserId int64
	campaignId   int64
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Delete: Permanently deletes a campaign. A deleted campaign cannot be
// recovered.
// The campaign should be archived first, i.e. set
// entity_status to `ENTITY_STATUS_ARCHIVED`, to be
// able to delete it.
func (r *AdvertisersCampaignsService) Delete(advertiserId int64, campaignId int64) *AdvertisersCampaignsDeleteCall {
	c := &AdvertisersCampaignsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.campaignId = campaignId
	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 *AdvertisersCampaignsDeleteCall) Fields(s ...googleapi.Field) *AdvertisersCampaignsDeleteCall {
	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 *AdvertisersCampaignsDeleteCall) Context(ctx context.Context) *AdvertisersCampaignsDeleteCall {
	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 *AdvertisersCampaignsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCampaignsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/advertisers/{+advertiserId}/campaigns/{+campaignId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"campaignId":   strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.campaigns.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AdvertisersCampaignsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Empty{
		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": "Permanently deletes a campaign. A deleted campaign cannot be recovered.\nThe campaign should be archived first, i.e. set\nentity_status to `ENTITY_STATUS_ARCHIVED`, to be\nable to delete it.",
	//   "flatPath": "v1/advertisers/{advertisersId}/campaigns/{campaignsId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.campaigns.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser this campaign belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "campaignId": {
	//       "description": "The ID of the campaign we need to delete.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/campaigns/{+campaignId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.campaigns.get":

type AdvertisersCampaignsGetCall struct {
	s            *Service
	advertiserId int64
	campaignId   int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a campaign.
func (r *AdvertisersCampaignsService) Get(advertiserId int64, campaignId int64) *AdvertisersCampaignsGetCall {
	c := &AdvertisersCampaignsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.campaignId = campaignId
	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 *AdvertisersCampaignsGetCall) Fields(s ...googleapi.Field) *AdvertisersCampaignsGetCall {
	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 *AdvertisersCampaignsGetCall) IfNoneMatch(entityTag string) *AdvertisersCampaignsGetCall {
	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 *AdvertisersCampaignsGetCall) Context(ctx context.Context) *AdvertisersCampaignsGetCall {
	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 *AdvertisersCampaignsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCampaignsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/campaigns/{+campaignId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"campaignId":   strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.campaigns.get" call.
// Exactly one of *Campaign or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Campaign.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 *AdvertisersCampaignsGetCall) Do(opts ...googleapi.CallOption) (*Campaign, 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 := &Campaign{
		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 campaign.",
	//   "flatPath": "v1/advertisers/{advertisersId}/campaigns/{campaignsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.campaigns.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser this campaign belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "campaignId": {
	//       "description": "Required. The ID of the campaign to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/campaigns/{+campaignId}",
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.campaigns.list":

type AdvertisersCampaignsListCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists campaigns in an advertiser.
//
// The order is defined by the order_by
// parameter.
// If a filter by
// entity_status is not specified, campaigns
// with
// `ENTITY_STATUS_ARCHIVED` will not be included in the results.
func (r *AdvertisersCampaignsService) List(advertiserId int64) *AdvertisersCampaignsListCall {
	c := &AdvertisersCampaignsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// campaign properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by `AND` or `OR` logical operators.
// A
// sequence of restrictions implicitly uses `AND`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `entityStatus`
//
// Examples:
//
// * All `ENTITY_STATUS_ACTIVE` or `ENTITY_STATUS_PAUSED` campaigns
// under an
// advertiser:
// `(entityStatus="ENTITY_STATUS_ACTIVE"
// OR
// entityStatus="ENTITY_STATUS_PAUSED")`
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersCampaignsListCall) Filter(filter string) *AdvertisersCampaignsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `displayName` (default)
// * `entityStatus`
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *AdvertisersCampaignsListCall) OrderBy(orderBy string) *AdvertisersCampaignsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`.
func (c *AdvertisersCampaignsListCall) PageSize(pageSize int64) *AdvertisersCampaignsListCall {
	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
// next_page_token returned from the
// previous call to `ListCampaigns` method. If not specified, the first
// page
// of results will be returned.
func (c *AdvertisersCampaignsListCall) PageToken(pageToken string) *AdvertisersCampaignsListCall {
	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 *AdvertisersCampaignsListCall) Fields(s ...googleapi.Field) *AdvertisersCampaignsListCall {
	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 *AdvertisersCampaignsListCall) IfNoneMatch(entityTag string) *AdvertisersCampaignsListCall {
	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 *AdvertisersCampaignsListCall) Context(ctx context.Context) *AdvertisersCampaignsListCall {
	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 *AdvertisersCampaignsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCampaignsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/campaigns")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.campaigns.list" call.
// Exactly one of *ListCampaignsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListCampaignsResponse.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 *AdvertisersCampaignsListCall) Do(opts ...googleapi.CallOption) (*ListCampaignsResponse, 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 := &ListCampaignsResponse{
		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 campaigns in an advertiser.\n\nThe order is defined by the order_by\nparameter.\nIf a filter by\nentity_status is not specified, campaigns with\n`ENTITY_STATUS_ARCHIVED` will not be included in the results.",
	//   "flatPath": "v1/advertisers/{advertisersId}/campaigns",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.campaigns.list",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser to list campaigns for.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by campaign properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by `AND` or `OR` logical operators. A\nsequence of restrictions implicitly uses `AND`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `entityStatus`\n\nExamples:\n\n* All `ENTITY_STATUS_ACTIVE` or `ENTITY_STATUS_PAUSED` campaigns under an\nadvertiser:\n`(entityStatus=\"ENTITY_STATUS_ACTIVE\" OR\nentityStatus=\"ENTITY_STATUS_PAUSED\")`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `displayName` (default)\n* `entityStatus`\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`.",
	//       "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\nnext_page_token returned from the\nprevious call to `ListCampaigns` method. If not specified, the first page\nof results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/campaigns",
	//   "response": {
	//     "$ref": "ListCampaignsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersCampaignsListCall) Pages(ctx context.Context, f func(*ListCampaignsResponse) 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 "displayvideo.advertisers.campaigns.patch":

type AdvertisersCampaignsPatchCall struct {
	s            *Service
	advertiserId int64
	campaignId   int64
	campaign     *Campaign
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Patch: Updates an existing campaign.
// Returns the updated campaign if successful.
func (r *AdvertisersCampaignsService) Patch(advertiserId int64, campaignId int64, campaign *Campaign) *AdvertisersCampaignsPatchCall {
	c := &AdvertisersCampaignsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.campaignId = campaignId
	c.campaign = campaign
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *AdvertisersCampaignsPatchCall) UpdateMask(updateMask string) *AdvertisersCampaignsPatchCall {
	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 *AdvertisersCampaignsPatchCall) Fields(s ...googleapi.Field) *AdvertisersCampaignsPatchCall {
	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 *AdvertisersCampaignsPatchCall) Context(ctx context.Context) *AdvertisersCampaignsPatchCall {
	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 *AdvertisersCampaignsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCampaignsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.campaign)
	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/advertisers/{+advertiserId}/campaigns/{+campaignId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"campaignId":   strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.campaigns.patch" call.
// Exactly one of *Campaign or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Campaign.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 *AdvertisersCampaignsPatchCall) Do(opts ...googleapi.CallOption) (*Campaign, 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 := &Campaign{
		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 an existing campaign.\nReturns the updated campaign if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/campaigns/{campaignsId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.advertisers.campaigns.patch",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser the campaign belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "campaignId": {
	//       "description": "Output only. The unique ID of the campaign. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Required. The mask to control which fields to update.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/campaigns/{+campaignId}",
	//   "request": {
	//     "$ref": "Campaign"
	//   },
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.channels.get":

type AdvertisersChannelsGetCall struct {
	s            *Service
	advertiserId int64
	channelId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a channel for a partner or advertiser.
func (r *AdvertisersChannelsService) Get(advertiserId int64, channelId int64) *AdvertisersChannelsGetCall {
	c := &AdvertisersChannelsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.channelId = channelId
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the fetched channel.
func (c *AdvertisersChannelsGetCall) PartnerId(partnerId int64) *AdvertisersChannelsGetCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *AdvertisersChannelsGetCall) Fields(s ...googleapi.Field) *AdvertisersChannelsGetCall {
	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 *AdvertisersChannelsGetCall) IfNoneMatch(entityTag string) *AdvertisersChannelsGetCall {
	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 *AdvertisersChannelsGetCall) Context(ctx context.Context) *AdvertisersChannelsGetCall {
	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 *AdvertisersChannelsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersChannelsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/channels/{+channelId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"channelId":    strconv.FormatInt(c.channelId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.channels.get" call.
// Exactly one of *Channel or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Channel.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 *AdvertisersChannelsGetCall) Do(opts ...googleapi.CallOption) (*Channel, 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 := &Channel{
		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 channel for a partner or advertiser.",
	//   "flatPath": "v1/advertisers/{advertisersId}/channels/{channelsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.channels.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the fetched channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the channel to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the fetched channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/channels/{+channelId}",
	//   "response": {
	//     "$ref": "Channel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.channels.list":

type AdvertisersChannelsListCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists channels for a partner or advertiser.
func (r *AdvertisersChannelsService) List(advertiserId int64) *AdvertisersChannelsListCall {
	c := &AdvertisersChannelsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// channel fields.
//
// Supported syntax:
//
// * Filter expressions for channel currently can only contain at most
// one
// * restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `displayName`
//
// Examples:
//
// * All channels for which the display name contains
// "google":
// `displayName : "google".
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersChannelsListCall) Filter(filter string) *AdvertisersChannelsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `displayName` (default)
// * `channelId`
//
// The default sorting order is ascending. To specify descending order
// for a
// field, a suffix " desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *AdvertisersChannelsListCall) OrderBy(orderBy string) *AdvertisersChannelsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *AdvertisersChannelsListCall) PageSize(pageSize int64) *AdvertisersChannelsListCall {
	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
// next_page_token returned from the
// previous call to `ListChannels` method. If not specified, the first
// page
// of results will be returned.
func (c *AdvertisersChannelsListCall) PageToken(pageToken string) *AdvertisersChannelsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the channels.
func (c *AdvertisersChannelsListCall) PartnerId(partnerId int64) *AdvertisersChannelsListCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *AdvertisersChannelsListCall) Fields(s ...googleapi.Field) *AdvertisersChannelsListCall {
	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 *AdvertisersChannelsListCall) IfNoneMatch(entityTag string) *AdvertisersChannelsListCall {
	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 *AdvertisersChannelsListCall) Context(ctx context.Context) *AdvertisersChannelsListCall {
	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 *AdvertisersChannelsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersChannelsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/channels")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.channels.list" call.
// Exactly one of *ListChannelsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListChannelsResponse.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 *AdvertisersChannelsListCall) Do(opts ...googleapi.CallOption) (*ListChannelsResponse, 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 := &ListChannelsResponse{
		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 channels for a partner or advertiser.",
	//   "flatPath": "v1/advertisers/{advertisersId}/channels",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.channels.list",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the channels.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by channel fields.\n\nSupported syntax:\n\n* Filter expressions for channel currently can only contain at most one\n* restriction.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `CONTAINS (:)`.\n* Supported fields:\n    - `displayName`\n\nExamples:\n\n* All channels for which the display name contains \"google\":\n`displayName : \"google\"`.\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `displayName` (default)\n* `channelId`\n\nThe default sorting order is ascending. To specify descending order for a\nfield, a suffix \" desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token returned from the\nprevious call to `ListChannels` method. If not specified, the first page\nof results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the channels.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/channels",
	//   "response": {
	//     "$ref": "ListChannelsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersChannelsListCall) Pages(ctx context.Context, f func(*ListChannelsResponse) 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 "displayvideo.advertisers.creatives.create":

type AdvertisersCreativesCreateCall struct {
	s            *Service
	advertiserId int64
	creative     *Creative
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a new creative.
// Returns the newly created creative if successful.
func (r *AdvertisersCreativesService) Create(advertiserId int64, creative *Creative) *AdvertisersCreativesCreateCall {
	c := &AdvertisersCreativesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	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 *AdvertisersCreativesCreateCall) Fields(s ...googleapi.Field) *AdvertisersCreativesCreateCall {
	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 *AdvertisersCreativesCreateCall) Context(ctx context.Context) *AdvertisersCreativesCreateCall {
	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 *AdvertisersCreativesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCreativesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.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 *AdvertisersCreativesCreateCall) 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 new creative.\nReturns the newly created creative if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/creatives",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.creatives.create",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser the creative belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/creatives",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.creatives.delete":

type AdvertisersCreativesDeleteCall struct {
	s            *Service
	advertiserId int64
	creativeId   int64
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Delete: Deletes a creative.
// Returns error code `NOT_FOUND` if the creative does not exist.
// The creative should be archived first, i.e. set
// entity_status to `ENTITY_STATUS_ARCHIVED`, before
// it can be deleted.
func (r *AdvertisersCreativesService) Delete(advertiserId int64, creativeId int64) *AdvertisersCreativesDeleteCall {
	c := &AdvertisersCreativesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.creativeId = creativeId
	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 *AdvertisersCreativesDeleteCall) Fields(s ...googleapi.Field) *AdvertisersCreativesDeleteCall {
	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 *AdvertisersCreativesDeleteCall) Context(ctx context.Context) *AdvertisersCreativesDeleteCall {
	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 *AdvertisersCreativesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "displayvideo.advertisers.creatives.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AdvertisersCreativesDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Empty{
		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": "Deletes a creative.\nReturns error code `NOT_FOUND` if the creative does not exist.\nThe creative should be archived first, i.e. set\nentity_status to `ENTITY_STATUS_ARCHIVED`, before\nit can be deleted.",
	//   "flatPath": "v1/advertisers/{advertisersId}/creatives/{creativesId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.creatives.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "creativeId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser this creative belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "creativeId": {
	//       "description": "The ID of the creative to be deleted.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/creatives/{+creativeId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.creatives.get":

type AdvertisersCreativesGetCall struct {
	s            *Service
	advertiserId int64
	creativeId   int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a creative.
func (r *AdvertisersCreativesService) Get(advertiserId int64, creativeId int64) *AdvertisersCreativesGetCall {
	c := &AdvertisersCreativesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.creativeId = creativeId
	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 *AdvertisersCreativesGetCall) Fields(s ...googleapi.Field) *AdvertisersCreativesGetCall {
	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 *AdvertisersCreativesGetCall) IfNoneMatch(entityTag string) *AdvertisersCreativesGetCall {
	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 *AdvertisersCreativesGetCall) Context(ctx context.Context) *AdvertisersCreativesGetCall {
	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 *AdvertisersCreativesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCreativesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/creatives/{+creativeId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"creativeId":   strconv.FormatInt(c.creativeId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.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 *AdvertisersCreativesGetCall) 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/advertisers/{advertisersId}/creatives/{creativesId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.creatives.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "creativeId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser this creative belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "creativeId": {
	//       "description": "Required. The ID of the creative to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/creatives/{+creativeId}",
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.creatives.list":

type AdvertisersCreativesListCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists creatives in an advertiser.
//
// The order is defined by the order_by
// parameter.
// If a filter by
// entity_status is not specified, creatives
// with
// `ENTITY_STATUS_ARCHIVED` will not be included in the results.
func (r *AdvertisersCreativesService) List(advertiserId int64) *AdvertisersCreativesListCall {
	c := &AdvertisersCreativesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// creative properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restriction for the same field must be combined by `OR`.
// * Restriction for different fields must be combined by `AND`.
// * Between `(` and `)` there can only be restrictions combined by
// `OR`
// for the same field.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)` for the following fields:
//     - `entityStatus`
//     - `creativeType`.
//     - `dimensions`
//     - `minDuration`
//     - `maxDuration`
//     - `approvalStatus`
//     - `exchangeReviewStatus`
//     - `dynamic`
// * The operator must be `HAS (:)` for the following fields:
//     - `lineItemIds`
// * For `entityStatus`, `minDuration`, `maxDuration`, and `dynamic`
// there may
// be at most one restriction.
// * For `dimensions`, the value is in the form of
// "{width}x{height}".
// * For `exchangeReviewStatus`, the value is in the form
// of
// `{exchange}-{reviewStatus}`.
// * For `minDuration` and `maxDuration`, the value is in the form
// of
// "{duration}s". Only seconds are supported with millisecond
// granularity.
// * There may be multiple `lineItemIds` restrictions in order to
// search
// against multiple possible line item IDs.
//
// Examples:
//
// * All native creatives: `creativeType="CREATIVE_TYPE_NATIVE"
// * All active creatives with 300x400 or 50x100
// dimensions:
// `entityStatus="ENTITY_STATUS_ACTIVE" AND (dimensions="300x400"
// OR dimensions="50x100")`
// * All dynamic creatives that are approved by AdX or
// AppNexus, with a minimum duration of 5 seconds and
// 200ms.
// `dynamic="true" AND minDuration="5.2s"
// AND
// (exchangeReviewStatus="EXCHANGE_GOOGLE_AD_MANAGER-REVIEW_STATUS_AP
// PROVED"
// OR
// exchangeReviewStatus="EXCHANGE_APPNEXUS-REVIEW_STATUS_APPROVED")`
// * All video creatives that are associated with line item ID 1 or
// 2:
// creativeType="CREATIVE_TYPE_VIDEO" AND (lineItemIds:1 OR
// lineItemIds:2)
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersCreativesListCall) Filter(filter string) *AdvertisersCreativesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `creativeId` (default)
// * `createTime`
// * `mediaDuration`
// * `dimensions` (sorts by width first, then by height)
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example: `createTime desc`.
func (c *AdvertisersCreativesListCall) OrderBy(orderBy string) *AdvertisersCreativesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *AdvertisersCreativesListCall) PageSize(pageSize int64) *AdvertisersCreativesListCall {
	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
// next_page_token
// returned from the previous call to `ListCreatives` method.
// If not specified, the first page of results will be returned.
func (c *AdvertisersCreativesListCall) PageToken(pageToken string) *AdvertisersCreativesListCall {
	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 *AdvertisersCreativesListCall) Fields(s ...googleapi.Field) *AdvertisersCreativesListCall {
	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 *AdvertisersCreativesListCall) IfNoneMatch(entityTag string) *AdvertisersCreativesListCall {
	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 *AdvertisersCreativesListCall) Context(ctx context.Context) *AdvertisersCreativesListCall {
	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 *AdvertisersCreativesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCreativesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.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 *AdvertisersCreativesListCall) 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 in an advertiser.\n\nThe order is defined by the order_by\nparameter.\nIf a filter by\nentity_status is not specified, creatives with\n`ENTITY_STATUS_ARCHIVED` will not be included in the results.",
	//   "flatPath": "v1/advertisers/{advertisersId}/creatives",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.creatives.list",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser to list creatives for.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by creative properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restriction for the same field must be combined by `OR`.\n* Restriction for different fields must be combined by `AND`.\n* Between `(` and `)` there can only be restrictions combined by `OR`\nfor the same field.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)` for the following fields:\n    - `entityStatus`\n    - `creativeType`.\n    - `dimensions`\n    - `minDuration`\n    - `maxDuration`\n    - `approvalStatus`\n    - `exchangeReviewStatus`\n    - `dynamic`\n* The operator must be `HAS (:)` for the following fields:\n    - `lineItemIds`\n* For `entityStatus`, `minDuration`, `maxDuration`, and `dynamic` there may\nbe at most one restriction.\n* For `dimensions`, the value is in the form of `\"{width}x{height}\"`.\n* For `exchangeReviewStatus`, the value is in the form of\n`{exchange}-{reviewStatus}`.\n* For `minDuration` and `maxDuration`, the value is in the form of\n`\"{duration}s\"`. Only seconds are supported with millisecond granularity.\n* There may be multiple `lineItemIds` restrictions in order to search\nagainst multiple possible line item IDs.\n\nExamples:\n\n* All native creatives: `creativeType=\"CREATIVE_TYPE_NATIVE\"`\n* All active creatives with 300x400 or 50x100 dimensions:\n`entityStatus=\"ENTITY_STATUS_ACTIVE\" AND (dimensions=\"300x400\"\nOR dimensions=\"50x100\")`\n* All dynamic creatives that are approved by AdX or\nAppNexus, with a minimum duration of 5 seconds and 200ms.\n`dynamic=\"true\" AND minDuration=\"5.2s\" AND\n(exchangeReviewStatus=\"EXCHANGE_GOOGLE_AD_MANAGER-REVIEW_STATUS_APPROVED\"\nOR exchangeReviewStatus=\"EXCHANGE_APPNEXUS-REVIEW_STATUS_APPROVED\")`\n* All video creatives that are associated with line item ID 1 or 2:\ncreativeType=\"CREATIVE_TYPE_VIDEO\" AND (lineItemIds:1 OR lineItemIds:2)\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `creativeId` (default)\n* `createTime`\n* `mediaDuration`\n* `dimensions` (sorts by width first, then by height)\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name.\nExample: `createTime desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListCreatives` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/creatives",
	//   "response": {
	//     "$ref": "ListCreativesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersCreativesListCall) 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 "displayvideo.advertisers.creatives.patch":

type AdvertisersCreativesPatchCall struct {
	s            *Service
	advertiserId int64
	creativeId   int64
	creative     *Creative
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Patch: Updates an existing creative.
// Returns the updated creative if successful.
func (r *AdvertisersCreativesService) Patch(advertiserId int64, creativeId int64, creative *Creative) *AdvertisersCreativesPatchCall {
	c := &AdvertisersCreativesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.creativeId = creativeId
	c.creative = creative
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *AdvertisersCreativesPatchCall) UpdateMask(updateMask string) *AdvertisersCreativesPatchCall {
	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 *AdvertisersCreativesPatchCall) Fields(s ...googleapi.Field) *AdvertisersCreativesPatchCall {
	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 *AdvertisersCreativesPatchCall) Context(ctx context.Context) *AdvertisersCreativesPatchCall {
	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 *AdvertisersCreativesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersCreativesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/creatives/{+creativeId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"creativeId":   strconv.FormatInt(c.creativeId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.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 *AdvertisersCreativesPatchCall) 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 an existing creative.\nReturns the updated creative if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/creatives/{creativesId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.advertisers.creatives.patch",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "creativeId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser the creative belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "creativeId": {
	//       "description": "Output only. The unique ID of the creative. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Required. The mask to control which fields to update.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/creatives/{+creativeId}",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.insertionOrders.create":

type AdvertisersInsertionOrdersCreateCall struct {
	s              *Service
	advertiserId   int64
	insertionorder *InsertionOrder
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Create: Creates a new insertion order.
// Returns the newly created insertion order if successful.
func (r *AdvertisersInsertionOrdersService) Create(advertiserId int64, insertionorder *InsertionOrder) *AdvertisersInsertionOrdersCreateCall {
	c := &AdvertisersInsertionOrdersCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.insertionorder = insertionorder
	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 *AdvertisersInsertionOrdersCreateCall) Fields(s ...googleapi.Field) *AdvertisersInsertionOrdersCreateCall {
	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 *AdvertisersInsertionOrdersCreateCall) Context(ctx context.Context) *AdvertisersInsertionOrdersCreateCall {
	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 *AdvertisersInsertionOrdersCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersInsertionOrdersCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.insertionorder)
	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/advertisers/{+advertiserId}/insertionOrders")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.insertionOrders.create" call.
// Exactly one of *InsertionOrder or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InsertionOrder.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 *AdvertisersInsertionOrdersCreateCall) Do(opts ...googleapi.CallOption) (*InsertionOrder, 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 := &InsertionOrder{
		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 new insertion order.\nReturns the newly created insertion order if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/insertionOrders",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.insertionOrders.create",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser the insertion order belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/insertionOrders",
	//   "request": {
	//     "$ref": "InsertionOrder"
	//   },
	//   "response": {
	//     "$ref": "InsertionOrder"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.insertionOrders.delete":

type AdvertisersInsertionOrdersDeleteCall struct {
	s                *Service
	advertiserId     int64
	insertionOrderId int64
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Delete: Deletes an insertion order.
// Returns error code `NOT_FOUND` if the insertion order does not
// exist.
// The insertion order should be archived first, i.e. set
// entity_status to `ENTITY_STATUS_ARCHIVED`,
// to be able to delete it.
func (r *AdvertisersInsertionOrdersService) Delete(advertiserId int64, insertionOrderId int64) *AdvertisersInsertionOrdersDeleteCall {
	c := &AdvertisersInsertionOrdersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.insertionOrderId = insertionOrderId
	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 *AdvertisersInsertionOrdersDeleteCall) Fields(s ...googleapi.Field) *AdvertisersInsertionOrdersDeleteCall {
	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 *AdvertisersInsertionOrdersDeleteCall) Context(ctx context.Context) *AdvertisersInsertionOrdersDeleteCall {
	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 *AdvertisersInsertionOrdersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersInsertionOrdersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/advertisers/{+advertiserId}/insertionOrders/{+insertionOrderId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"advertiserId":     strconv.FormatInt(c.advertiserId, 10),
		"insertionOrderId": strconv.FormatInt(c.insertionOrderId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.insertionOrders.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AdvertisersInsertionOrdersDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Empty{
		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": "Deletes an insertion order.\nReturns error code `NOT_FOUND` if the insertion order does not exist.\nThe insertion order should be archived first, i.e. set\nentity_status to `ENTITY_STATUS_ARCHIVED`,\nto be able to delete it.",
	//   "flatPath": "v1/advertisers/{advertisersId}/insertionOrders/{insertionOrdersId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.insertionOrders.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "insertionOrderId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser this insertion order belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "insertionOrderId": {
	//       "description": "The ID of the insertion order we need to delete.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/insertionOrders/{+insertionOrderId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.insertionOrders.get":

type AdvertisersInsertionOrdersGetCall struct {
	s                *Service
	advertiserId     int64
	insertionOrderId int64
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
	header_          http.Header
}

// Get: Gets an insertion order.
// Returns error code `NOT_FOUND` if the insertion order does not exist.
func (r *AdvertisersInsertionOrdersService) Get(advertiserId int64, insertionOrderId int64) *AdvertisersInsertionOrdersGetCall {
	c := &AdvertisersInsertionOrdersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.insertionOrderId = insertionOrderId
	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 *AdvertisersInsertionOrdersGetCall) Fields(s ...googleapi.Field) *AdvertisersInsertionOrdersGetCall {
	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 *AdvertisersInsertionOrdersGetCall) IfNoneMatch(entityTag string) *AdvertisersInsertionOrdersGetCall {
	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 *AdvertisersInsertionOrdersGetCall) Context(ctx context.Context) *AdvertisersInsertionOrdersGetCall {
	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 *AdvertisersInsertionOrdersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersInsertionOrdersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/insertionOrders/{+insertionOrderId}")
	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{
		"advertiserId":     strconv.FormatInt(c.advertiserId, 10),
		"insertionOrderId": strconv.FormatInt(c.insertionOrderId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.insertionOrders.get" call.
// Exactly one of *InsertionOrder or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InsertionOrder.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 *AdvertisersInsertionOrdersGetCall) Do(opts ...googleapi.CallOption) (*InsertionOrder, 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 := &InsertionOrder{
		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 an insertion order.\nReturns error code `NOT_FOUND` if the insertion order does not exist.",
	//   "flatPath": "v1/advertisers/{advertisersId}/insertionOrders/{insertionOrdersId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.insertionOrders.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "insertionOrderId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser this insertion order belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "insertionOrderId": {
	//       "description": "Required. The ID of the insertion order to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/insertionOrders/{+insertionOrderId}",
	//   "response": {
	//     "$ref": "InsertionOrder"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.insertionOrders.list":

type AdvertisersInsertionOrdersListCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists insertion orders in an advertiser.
//
// The order is defined by the order_by
// parameter.
// If a filter by
// entity_status is not specified, insertion
// orders with `ENTITY_STATUS_ARCHIVED` will not be included in the
// results.
func (r *AdvertisersInsertionOrdersService) List(advertiserId int64) *AdvertisersInsertionOrdersListCall {
	c := &AdvertisersInsertionOrdersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// insertion order properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by `AND` or `OR` logical operators.
// A
// sequence of restrictions implicitly uses `AND`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `campaignId`
//     - `entityStatus`
//
// Examples:
//
// * All insertion orders under a campaign: `campaignId="1234"
// * All `ENTITY_STATUS_ACTIVE` or `ENTITY_STATUS_PAUSED` insertion
// orders
// under an advertiser:
// `(entityStatus="ENTITY_STATUS_ACTIVE"
// OR
// entityStatus="ENTITY_STATUS_PAUSED")`
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersInsertionOrdersListCall) Filter(filter string) *AdvertisersInsertionOrdersListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * "displayName" (default)
// * "entityStatus"
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *AdvertisersInsertionOrdersListCall) OrderBy(orderBy string) *AdvertisersInsertionOrdersListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *AdvertisersInsertionOrdersListCall) PageSize(pageSize int64) *AdvertisersInsertionOrdersListCall {
	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
// next_page_token returned
// from the previous call to `ListInsertionOrders` method. If not
// specified,
// the first page of results will be returned.
func (c *AdvertisersInsertionOrdersListCall) PageToken(pageToken string) *AdvertisersInsertionOrdersListCall {
	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 *AdvertisersInsertionOrdersListCall) Fields(s ...googleapi.Field) *AdvertisersInsertionOrdersListCall {
	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 *AdvertisersInsertionOrdersListCall) IfNoneMatch(entityTag string) *AdvertisersInsertionOrdersListCall {
	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 *AdvertisersInsertionOrdersListCall) Context(ctx context.Context) *AdvertisersInsertionOrdersListCall {
	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 *AdvertisersInsertionOrdersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersInsertionOrdersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/insertionOrders")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.insertionOrders.list" call.
// Exactly one of *ListInsertionOrdersResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListInsertionOrdersResponse.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 *AdvertisersInsertionOrdersListCall) Do(opts ...googleapi.CallOption) (*ListInsertionOrdersResponse, 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 := &ListInsertionOrdersResponse{
		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 insertion orders in an advertiser.\n\nThe order is defined by the order_by\nparameter.\nIf a filter by\nentity_status is not specified, insertion\norders with `ENTITY_STATUS_ARCHIVED` will not be included in the results.",
	//   "flatPath": "v1/advertisers/{advertisersId}/insertionOrders",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.insertionOrders.list",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser to list insertion orders for.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by insertion order properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by `AND` or `OR` logical operators. A\nsequence of restrictions implicitly uses `AND`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `campaignId`\n    - `entityStatus`\n\nExamples:\n\n* All insertion orders under a campaign: `campaignId=\"1234\"`\n* All `ENTITY_STATUS_ACTIVE` or `ENTITY_STATUS_PAUSED` insertion orders\nunder an advertiser:\n`(entityStatus=\"ENTITY_STATUS_ACTIVE\" OR\nentityStatus=\"ENTITY_STATUS_PAUSED\")`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* \"displayName\" (default)\n* \"entityStatus\"\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token returned\nfrom the previous call to `ListInsertionOrders` method. If not specified,\nthe first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/insertionOrders",
	//   "response": {
	//     "$ref": "ListInsertionOrdersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersInsertionOrdersListCall) Pages(ctx context.Context, f func(*ListInsertionOrdersResponse) 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 "displayvideo.advertisers.insertionOrders.patch":

type AdvertisersInsertionOrdersPatchCall struct {
	s                *Service
	advertiserId     int64
	insertionOrderId int64
	insertionorder   *InsertionOrder
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Patch: Updates an existing insertion order.
// Returns the updated insertion order if successful.
func (r *AdvertisersInsertionOrdersService) Patch(advertiserId int64, insertionOrderId int64, insertionorder *InsertionOrder) *AdvertisersInsertionOrdersPatchCall {
	c := &AdvertisersInsertionOrdersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.insertionOrderId = insertionOrderId
	c.insertionorder = insertionorder
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *AdvertisersInsertionOrdersPatchCall) UpdateMask(updateMask string) *AdvertisersInsertionOrdersPatchCall {
	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 *AdvertisersInsertionOrdersPatchCall) Fields(s ...googleapi.Field) *AdvertisersInsertionOrdersPatchCall {
	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 *AdvertisersInsertionOrdersPatchCall) Context(ctx context.Context) *AdvertisersInsertionOrdersPatchCall {
	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 *AdvertisersInsertionOrdersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersInsertionOrdersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.insertionorder)
	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/advertisers/{+advertiserId}/insertionOrders/{+insertionOrderId}")
	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{
		"advertiserId":     strconv.FormatInt(c.advertiserId, 10),
		"insertionOrderId": strconv.FormatInt(c.insertionOrderId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.insertionOrders.patch" call.
// Exactly one of *InsertionOrder or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InsertionOrder.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 *AdvertisersInsertionOrdersPatchCall) Do(opts ...googleapi.CallOption) (*InsertionOrder, 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 := &InsertionOrder{
		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 an existing insertion order.\nReturns the updated insertion order if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/insertionOrders/{insertionOrdersId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.advertisers.insertionOrders.patch",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "insertionOrderId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser the insertion order belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "insertionOrderId": {
	//       "description": "Output only. The unique ID of the insertion order. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Required. The mask to control which fields to update.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/insertionOrders/{+insertionOrderId}",
	//   "request": {
	//     "$ref": "InsertionOrder"
	//   },
	//   "response": {
	//     "$ref": "InsertionOrder"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.bulkEditLineItemAssignedTargetingOptions":

type AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall struct {
	s                                               *Service
	advertiserId                                    int64
	lineItemId                                      int64
	bulkeditlineitemassignedtargetingoptionsrequest *BulkEditLineItemAssignedTargetingOptionsRequest
	urlParams_                                      gensupport.URLParams
	ctx_                                            context.Context
	header_                                         http.Header
}

// BulkEditLineItemAssignedTargetingOptions: Bulk edits targeting
// options under a single line item.
// The operation will delete the assigned targeting options provided
// in
// BulkEditLineItemAssignedTargetingOptionsRequest.delete_requests
// and
// then create the assigned targeting options provided
// in
// BulkEditLineItemAssignedTargetingOptionsRequest.create_requests .
func (r *AdvertisersLineItemsService) BulkEditLineItemAssignedTargetingOptions(advertiserId int64, lineItemId int64, bulkeditlineitemassignedtargetingoptionsrequest *BulkEditLineItemAssignedTargetingOptionsRequest) *AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall {
	c := &AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	c.bulkeditlineitemassignedtargetingoptionsrequest = bulkeditlineitemassignedtargetingoptionsrequest
	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 *AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall {
	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 *AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall) Context(ctx context.Context) *AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall {
	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 *AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.bulkeditlineitemassignedtargetingoptionsrequest)
	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/advertisers/{+advertiserId}/lineItems/{+lineItemId}:bulkEditLineItemAssignedTargetingOptions")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":   strconv.FormatInt(c.lineItemId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.bulkEditLineItemAssignedTargetingOptions" call.
// Exactly one of *BulkEditLineItemAssignedTargetingOptionsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *BulkEditLineItemAssignedTargetingOptionsResponse.ServerResponse.Heade
// r 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 *AdvertisersLineItemsBulkEditLineItemAssignedTargetingOptionsCall) Do(opts ...googleapi.CallOption) (*BulkEditLineItemAssignedTargetingOptionsResponse, 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 := &BulkEditLineItemAssignedTargetingOptionsResponse{
		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": "Bulk edits targeting options under a single line item.\nThe operation will delete the assigned targeting options provided in\nBulkEditLineItemAssignedTargetingOptionsRequest.delete_requests and\nthen create the assigned targeting options provided in\nBulkEditLineItemAssignedTargetingOptionsRequest.create_requests .",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}:bulkEditLineItemAssignedTargetingOptions",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.lineItems.bulkEditLineItemAssignedTargetingOptions",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Required. The ID of the line item the assigned targeting option will belong to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}:bulkEditLineItemAssignedTargetingOptions",
	//   "request": {
	//     "$ref": "BulkEditLineItemAssignedTargetingOptionsRequest"
	//   },
	//   "response": {
	//     "$ref": "BulkEditLineItemAssignedTargetingOptionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.bulkListLineItemAssignedTargetingOptions":

type AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall struct {
	s            *Service
	advertiserId int64
	lineItemId   int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// BulkListLineItemAssignedTargetingOptions: Lists assigned targeting
// options of a line item across targeting types.
func (r *AdvertisersLineItemsService) BulkListLineItemAssignedTargetingOptions(advertiserId int64, lineItemId int64) *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall {
	c := &AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// assigned targeting option properties.
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by the logical operator `OR` on the
// same
// field.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `targetingType`
//     - `inheritance`
//
// Examples:
//
// * AssignedTargetingOptions of targeting
// type
// TARGETING_TYPE_PROXIMITY_LOCATION_LIST or
// TARGETING_TYPE_CHANNEL
// `targetingType="TARGETING_TYPE_PROXIMITY_LOCATI
// ON_LIST" OR
// targetingType="TARGETING_TYPE_CHANNEL"
// * AssignedTargetingOptions with inheritance status of NOT_INHERITED
// or
//   INHERITED_FROM_PARTNER
// `inheritance="NOT_INHERITED" OR
// inheritance="INHERITED_FROM_PARTNER"
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) Filter(filter string) *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `targetingType` (default)
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `targetingType desc`.
func (c *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) OrderBy(orderBy string) *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page
// size.
// The size must be an integer between `1` and `5000`. If
// unspecified,
// the default is '5000'. Returns error code `INVALID_ARGUMENT` if an
// invalid
// value is specified.
func (c *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) PageSize(pageSize int64) *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token that lets
// the client fetch the next page of results.
// Typically, this is the value of
// next_page_token
// returned from the previous call
// to
// `BulkListLineItemAssignedTargetingOptions` method.
// If not specified, the first page of results will be returned.
func (c *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) PageToken(pageToken string) *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall {
	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 *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall {
	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 *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) IfNoneMatch(entityTag string) *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall {
	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 *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) Context(ctx context.Context) *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall {
	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 *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/lineItems/{+lineItemId}:bulkListLineItemAssignedTargetingOptions")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":   strconv.FormatInt(c.lineItemId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.bulkListLineItemAssignedTargetingOptions" call.
// Exactly one of *BulkListLineItemAssignedTargetingOptionsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *BulkListLineItemAssignedTargetingOptionsResponse.ServerResponse.Heade
// r 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 *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) Do(opts ...googleapi.CallOption) (*BulkListLineItemAssignedTargetingOptionsResponse, 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 := &BulkListLineItemAssignedTargetingOptionsResponse{
		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 assigned targeting options of a line item across targeting types.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}:bulkListLineItemAssignedTargetingOptions",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.lineItems.bulkListLineItemAssignedTargetingOptions",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by assigned targeting option properties.\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by the logical operator `OR` on the same\nfield.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `targetingType`\n    - `inheritance`\n\nExamples:\n\n* AssignedTargetingOptions of targeting type\nTARGETING_TYPE_PROXIMITY_LOCATION_LIST or TARGETING_TYPE_CHANNEL\n`targetingType=\"TARGETING_TYPE_PROXIMITY_LOCATION_LIST\" OR\ntargetingType=\"TARGETING_TYPE_CHANNEL\"`\n* AssignedTargetingOptions with inheritance status of NOT_INHERITED or\n  INHERITED_FROM_PARTNER\n`inheritance=\"NOT_INHERITED\" OR inheritance=\"INHERITED_FROM_PARTNER\"`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Required. The ID of the line item to list assigned targeting options for.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `targetingType` (default)\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`targetingType desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size.\nThe size must be an integer between `1` and `5000`. If unspecified,\nthe default is '5000'. Returns error code `INVALID_ARGUMENT` if an invalid\nvalue is specified.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token that lets the client fetch the next page of results.\nTypically, this is the value of\nnext_page_token\nreturned from the previous call to\n`BulkListLineItemAssignedTargetingOptions` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}:bulkListLineItemAssignedTargetingOptions",
	//   "response": {
	//     "$ref": "BulkListLineItemAssignedTargetingOptionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersLineItemsBulkListLineItemAssignedTargetingOptionsCall) Pages(ctx context.Context, f func(*BulkListLineItemAssignedTargetingOptionsResponse) 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 "displayvideo.advertisers.lineItems.create":

type AdvertisersLineItemsCreateCall struct {
	s            *Service
	advertiserId int64
	lineitem     *LineItem
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a new line item.
// Returns the newly created line item if successful.
func (r *AdvertisersLineItemsService) Create(advertiserId int64, lineitem *LineItem) *AdvertisersLineItemsCreateCall {
	c := &AdvertisersLineItemsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineitem = lineitem
	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 *AdvertisersLineItemsCreateCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsCreateCall {
	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 *AdvertisersLineItemsCreateCall) Context(ctx context.Context) *AdvertisersLineItemsCreateCall {
	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 *AdvertisersLineItemsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.lineitem)
	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/advertisers/{+advertiserId}/lineItems")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.create" call.
// Exactly one of *LineItem or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *LineItem.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 *AdvertisersLineItemsCreateCall) Do(opts ...googleapi.CallOption) (*LineItem, 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 := &LineItem{
		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 new line item.\nReturns the newly created line item if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.lineItems.create",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems",
	//   "request": {
	//     "$ref": "LineItem"
	//   },
	//   "response": {
	//     "$ref": "LineItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.delete":

type AdvertisersLineItemsDeleteCall struct {
	s            *Service
	advertiserId int64
	lineItemId   int64
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Delete: Deletes a line item.
// Returns error code `NOT_FOUND` if the line item does not exist.
// The line item should be archived first, i.e. set
// entity_status to `ENTITY_STATUS_ARCHIVED`, to be
// able to delete it.
func (r *AdvertisersLineItemsService) Delete(advertiserId int64, lineItemId int64) *AdvertisersLineItemsDeleteCall {
	c := &AdvertisersLineItemsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	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 *AdvertisersLineItemsDeleteCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsDeleteCall {
	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 *AdvertisersLineItemsDeleteCall) Context(ctx context.Context) *AdvertisersLineItemsDeleteCall {
	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 *AdvertisersLineItemsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":   strconv.FormatInt(c.lineItemId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AdvertisersLineItemsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Empty{
		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": "Deletes a line item.\nReturns error code `NOT_FOUND` if the line item does not exist.\nThe line item should be archived first, i.e. set\nentity_status to `ENTITY_STATUS_ARCHIVED`, to be\nable to delete it.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.lineItems.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser this line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "The ID of the line item we need to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.get":

type AdvertisersLineItemsGetCall struct {
	s            *Service
	advertiserId int64
	lineItemId   int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a line item.
func (r *AdvertisersLineItemsService) Get(advertiserId int64, lineItemId int64) *AdvertisersLineItemsGetCall {
	c := &AdvertisersLineItemsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	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 *AdvertisersLineItemsGetCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsGetCall {
	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 *AdvertisersLineItemsGetCall) IfNoneMatch(entityTag string) *AdvertisersLineItemsGetCall {
	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 *AdvertisersLineItemsGetCall) Context(ctx context.Context) *AdvertisersLineItemsGetCall {
	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 *AdvertisersLineItemsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/lineItems/{+lineItemId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":   strconv.FormatInt(c.lineItemId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.get" call.
// Exactly one of *LineItem or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *LineItem.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 *AdvertisersLineItemsGetCall) Do(opts ...googleapi.CallOption) (*LineItem, 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 := &LineItem{
		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 line item.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.lineItems.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser this line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Required. The ID of the line item to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}",
	//   "response": {
	//     "$ref": "LineItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.list":

type AdvertisersLineItemsListCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists line items in an advertiser.
//
// The order is defined by the order_by
// parameter.
// If a filter by
// entity_status is not specified, line items
// with
// `ENTITY_STATUS_ARCHIVED` will not be included in the results.
func (r *AdvertisersLineItemsService) List(advertiserId int64) *AdvertisersLineItemsListCall {
	c := &AdvertisersLineItemsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by line
// item properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by `AND` or `OR` logical operators.
// A
// sequence of restrictions implicitly uses `AND`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `campaignId`
//     - `insertionOrderId`
//     - `entityStatus`
//     - `lineItemType`.
//
// Examples:
//
// * All line items under an insertion order:
// `insertionOrderId="1234"
// * All `ENTITY_STATUS_ACTIVE` or `ENTITY_STATUS_PAUSED`
// and `LINE_ITEM_TYPE_DISPLAY_DEFAULT` line items under an
// advertiser:
// `(entityStatus="ENTITY_STATUS_ACTIVE"
// OR
// entityStatus="ENTITY_STATUS_PAUSED")
// AND
// lineItemType="LINE_ITEM_TYPE_DISPLAY_DEFAULT"
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersLineItemsListCall) Filter(filter string) *AdvertisersLineItemsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * "displayName" (default)
// * "entityStatus"
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *AdvertisersLineItemsListCall) OrderBy(orderBy string) *AdvertisersLineItemsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *AdvertisersLineItemsListCall) PageSize(pageSize int64) *AdvertisersLineItemsListCall {
	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
// next_page_token
// returned from the previous call to `ListLineItems` method.
// If not specified, the first page of results will be returned.
func (c *AdvertisersLineItemsListCall) PageToken(pageToken string) *AdvertisersLineItemsListCall {
	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 *AdvertisersLineItemsListCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsListCall {
	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 *AdvertisersLineItemsListCall) IfNoneMatch(entityTag string) *AdvertisersLineItemsListCall {
	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 *AdvertisersLineItemsListCall) Context(ctx context.Context) *AdvertisersLineItemsListCall {
	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 *AdvertisersLineItemsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/lineItems")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.list" call.
// Exactly one of *ListLineItemsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListLineItemsResponse.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 *AdvertisersLineItemsListCall) Do(opts ...googleapi.CallOption) (*ListLineItemsResponse, 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 := &ListLineItemsResponse{
		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 line items in an advertiser.\n\nThe order is defined by the order_by\nparameter.\nIf a filter by\nentity_status is not specified, line items with\n`ENTITY_STATUS_ARCHIVED` will not be included in the results.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.lineItems.list",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser to list line items for.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by line item properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by `AND` or `OR` logical operators. A\nsequence of restrictions implicitly uses `AND`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `campaignId`\n    - `insertionOrderId`\n    - `entityStatus`\n    - `lineItemType`.\n\nExamples:\n\n* All line items under an insertion order: `insertionOrderId=\"1234\"`\n* All `ENTITY_STATUS_ACTIVE` or `ENTITY_STATUS_PAUSED`\nand `LINE_ITEM_TYPE_DISPLAY_DEFAULT` line items under an advertiser:\n`(entityStatus=\"ENTITY_STATUS_ACTIVE\" OR\nentityStatus=\"ENTITY_STATUS_PAUSED\") AND\nlineItemType=\"LINE_ITEM_TYPE_DISPLAY_DEFAULT\"`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* \"displayName\" (default)\n* \"entityStatus\"\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListLineItems` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems",
	//   "response": {
	//     "$ref": "ListLineItemsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersLineItemsListCall) Pages(ctx context.Context, f func(*ListLineItemsResponse) 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 "displayvideo.advertisers.lineItems.patch":

type AdvertisersLineItemsPatchCall struct {
	s            *Service
	advertiserId int64
	lineItemId   int64
	lineitem     *LineItem
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Patch: Updates an existing line item.
// Returns the updated line item if successful.
func (r *AdvertisersLineItemsService) Patch(advertiserId int64, lineItemId int64, lineitem *LineItem) *AdvertisersLineItemsPatchCall {
	c := &AdvertisersLineItemsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	c.lineitem = lineitem
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *AdvertisersLineItemsPatchCall) UpdateMask(updateMask string) *AdvertisersLineItemsPatchCall {
	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 *AdvertisersLineItemsPatchCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsPatchCall {
	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 *AdvertisersLineItemsPatchCall) Context(ctx context.Context) *AdvertisersLineItemsPatchCall {
	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 *AdvertisersLineItemsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.lineitem)
	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/advertisers/{+advertiserId}/lineItems/{+lineItemId}")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":   strconv.FormatInt(c.lineItemId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.patch" call.
// Exactly one of *LineItem or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *LineItem.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 *AdvertisersLineItemsPatchCall) Do(opts ...googleapi.CallOption) (*LineItem, 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 := &LineItem{
		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 an existing line item.\nReturns the updated line item if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.advertisers.lineItems.patch",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Output only. The unique ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Output only. The unique ID of the line item. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Required. The mask to control which fields to update.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}",
	//   "request": {
	//     "$ref": "LineItem"
	//   },
	//   "response": {
	//     "$ref": "LineItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.create":

type AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall struct {
	s                       *Service
	advertiserId            int64
	lineItemId              int64
	targetingType           string
	assignedtargetingoption *AssignedTargetingOption
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Create: Assigns a targeting option to a line item.
// Returns the assigned targeting option if successful.
func (r *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService) Create(advertiserId int64, lineItemId int64, targetingType string, assignedtargetingoption *AssignedTargetingOption) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall {
	c := &AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	c.targetingType = targetingType
	c.assignedtargetingoption = assignedtargetingoption
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall) Context(ctx context.Context) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.assignedtargetingoption)
	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/advertisers/{+advertiserId}/lineItems/{+lineItemId}/targetingTypes/{+targetingType}/assignedTargetingOptions")
	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{
		"advertiserId":  strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":    strconv.FormatInt(c.lineItemId, 10),
		"targetingType": c.targetingType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.create" call.
// Exactly one of *AssignedTargetingOption or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AssignedTargetingOption.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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsCreateCall) Do(opts ...googleapi.CallOption) (*AssignedTargetingOption, 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 := &AssignedTargetingOption{
		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": "Assigns a targeting option to a line item.\nReturns the assigned targeting option if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}/targetingTypes/{targetingTypesId}/assignedTargetingOptions",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.create",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId",
	//     "targetingType"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Required. The ID of the line item the assigned targeting option will belong to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. Identifies the type of this assigned targeting option.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}/targetingTypes/{+targetingType}/assignedTargetingOptions",
	//   "request": {
	//     "$ref": "AssignedTargetingOption"
	//   },
	//   "response": {
	//     "$ref": "AssignedTargetingOption"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.delete":

type AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall struct {
	s                         *Service
	advertiserId              int64
	lineItemId                int64
	targetingType             string
	assignedTargetingOptionId string
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Delete: Deletes an assigned targeting option from a line item.
func (r *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService) Delete(advertiserId int64, lineItemId int64, targetingType string, assignedTargetingOptionId string) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall {
	c := &AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	c.targetingType = targetingType
	c.assignedTargetingOptionId = assignedTargetingOptionId
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall) Context(ctx context.Context) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}/targetingTypes/{+targetingType}/assignedTargetingOptions/{+assignedTargetingOptionId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"advertiserId":              strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":                strconv.FormatInt(c.lineItemId, 10),
		"targetingType":             c.targetingType,
		"assignedTargetingOptionId": c.assignedTargetingOptionId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Empty{
		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": "Deletes an assigned targeting option from a line item.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}/targetingTypes/{targetingTypesId}/assignedTargetingOptions/{assignedTargetingOptionsId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId",
	//     "targetingType",
	//     "assignedTargetingOptionId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "assignedTargetingOptionId": {
	//       "description": "Required. The ID of the assigned targeting option to delete.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Required. The ID of the line item the assigned targeting option belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. Identifies the type of this assigned targeting option.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}/targetingTypes/{+targetingType}/assignedTargetingOptions/{+assignedTargetingOptionId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.get":

type AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall struct {
	s                         *Service
	advertiserId              int64
	lineItemId                int64
	targetingType             string
	assignedTargetingOptionId string
	urlParams_                gensupport.URLParams
	ifNoneMatch_              string
	ctx_                      context.Context
	header_                   http.Header
}

// Get: Gets a single targeting option assigned to a line item.
func (r *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService) Get(advertiserId int64, lineItemId int64, targetingType string, assignedTargetingOptionId string) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall {
	c := &AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	c.targetingType = targetingType
	c.assignedTargetingOptionId = assignedTargetingOptionId
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall) IfNoneMatch(entityTag string) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall) Context(ctx context.Context) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/lineItems/{+lineItemId}/targetingTypes/{+targetingType}/assignedTargetingOptions/{+assignedTargetingOptionId}")
	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{
		"advertiserId":              strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":                strconv.FormatInt(c.lineItemId, 10),
		"targetingType":             c.targetingType,
		"assignedTargetingOptionId": c.assignedTargetingOptionId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.get" call.
// Exactly one of *AssignedTargetingOption or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AssignedTargetingOption.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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsGetCall) Do(opts ...googleapi.CallOption) (*AssignedTargetingOption, 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 := &AssignedTargetingOption{
		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 single targeting option assigned to a line item.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}/targetingTypes/{targetingTypesId}/assignedTargetingOptions/{assignedTargetingOptionsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId",
	//     "targetingType",
	//     "assignedTargetingOptionId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "assignedTargetingOptionId": {
	//       "description": "Required. An identifier unique to the targeting type in this line item that\nidentifies the assigned targeting option being requested.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Required. The ID of the line item the assigned targeting option belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. Identifies the type of this assigned targeting option.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}/targetingTypes/{+targetingType}/assignedTargetingOptions/{+assignedTargetingOptionId}",
	//   "response": {
	//     "$ref": "AssignedTargetingOption"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.list":

type AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall struct {
	s             *Service
	advertiserId  int64
	lineItemId    int64
	targetingType string
	urlParams_    gensupport.URLParams
	ifNoneMatch_  string
	ctx_          context.Context
	header_       http.Header
}

// List: Lists the targeting options assigned to a line item.
func (r *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsService) List(advertiserId int64, lineItemId int64, targetingType string) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall {
	c := &AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	c.targetingType = targetingType
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// assigned targeting option properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by the logical operator `OR`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `assignedTargetingOptionId`
//     - `inheritance`
//
// Examples:
//
// * AssignedTargetingOptions with ID 1 or
// 2
// `assignedTargetingOptionId="1" OR assignedTargetingOptionId="2"
// * AssignedTargetingOptions with inheritance status of NOT_INHERITED
// or
//   INHERITED_FROM_PARTNER
// `inheritance="NOT_INHERITED" OR
// inheritance="INHERITED_FROM_PARTNER"
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) Filter(filter string) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `assignedTargetingOptionId` (default)
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `assignedTargetingOptionId desc`.
func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) OrderBy(orderBy string) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) PageSize(pageSize int64) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall {
	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
// next_page_token
// returned from the previous call to
// `ListLineItemAssignedTargetingOptions`
// method. If not specified, the first page of results will be returned.
func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) PageToken(pageToken string) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) Fields(s ...googleapi.Field) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) IfNoneMatch(entityTag string) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) Context(ctx context.Context) *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall {
	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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/lineItems/{+lineItemId}/targetingTypes/{+targetingType}/assignedTargetingOptions")
	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{
		"advertiserId":  strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":    strconv.FormatInt(c.lineItemId, 10),
		"targetingType": c.targetingType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.list" call.
// Exactly one of *ListLineItemAssignedTargetingOptionsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *ListLineItemAssignedTargetingOptionsResponse.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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) Do(opts ...googleapi.CallOption) (*ListLineItemAssignedTargetingOptionsResponse, 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 := &ListLineItemAssignedTargetingOptionsResponse{
		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 targeting options assigned to a line item.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}/targetingTypes/{targetingTypesId}/assignedTargetingOptions",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.lineItems.targetingTypes.assignedTargetingOptions.list",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId",
	//     "targetingType"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser the line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by assigned targeting option properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by the logical operator `OR`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `assignedTargetingOptionId`\n    - `inheritance`\n\nExamples:\n\n* AssignedTargetingOptions with ID 1 or 2\n`assignedTargetingOptionId=\"1\" OR assignedTargetingOptionId=\"2\"`\n* AssignedTargetingOptions with inheritance status of NOT_INHERITED or\n  INHERITED_FROM_PARTNER\n`inheritance=\"NOT_INHERITED\" OR inheritance=\"INHERITED_FROM_PARTNER\"`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Required. The ID of the line item to list assigned targeting options for.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `assignedTargetingOptionId` (default)\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`assignedTargetingOptionId desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListLineItemAssignedTargetingOptions`\nmethod. If not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. Identifies the type of assigned targeting options to list.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}/targetingTypes/{+targetingType}/assignedTargetingOptions",
	//   "response": {
	//     "$ref": "ListLineItemAssignedTargetingOptionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersLineItemsTargetingTypesAssignedTargetingOptionsListCall) Pages(ctx context.Context, f func(*ListLineItemAssignedTargetingOptionsResponse) 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 "displayvideo.advertisers.locationLists.get":

type AdvertisersLocationListsGetCall struct {
	s              *Service
	advertiserId   int64
	locationListId int64
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Gets a location list.
func (r *AdvertisersLocationListsService) Get(advertiserId int64, locationListId int64) *AdvertisersLocationListsGetCall {
	c := &AdvertisersLocationListsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.locationListId = locationListId
	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 *AdvertisersLocationListsGetCall) Fields(s ...googleapi.Field) *AdvertisersLocationListsGetCall {
	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 *AdvertisersLocationListsGetCall) IfNoneMatch(entityTag string) *AdvertisersLocationListsGetCall {
	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 *AdvertisersLocationListsGetCall) Context(ctx context.Context) *AdvertisersLocationListsGetCall {
	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 *AdvertisersLocationListsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLocationListsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/locationLists/{+locationListId}")
	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{
		"advertiserId":   strconv.FormatInt(c.advertiserId, 10),
		"locationListId": strconv.FormatInt(c.locationListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.locationLists.get" call.
// Exactly one of *LocationList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LocationList.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 *AdvertisersLocationListsGetCall) Do(opts ...googleapi.CallOption) (*LocationList, 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 := &LocationList{
		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 location list.",
	//   "flatPath": "v1/advertisers/{advertisersId}/locationLists/{locationListsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.locationLists.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "locationListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the fetched location list belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "locationListId": {
	//       "description": "Required. The ID of the location list to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/locationLists/{+locationListId}",
	//   "response": {
	//     "$ref": "LocationList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.locationLists.list":

type AdvertisersLocationListsListCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists location lists based on a given advertiser id.
func (r *AdvertisersLocationListsService) List(advertiserId int64) *AdvertisersLocationListsListCall {
	c := &AdvertisersLocationListsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// location list fields.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by `AND` or `OR` logical operators.
// A
// sequence of restrictions implicitly uses `AND`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `locationType`
//
// Examples:
//
// * All regional location
// list:
// `locationType="TARGETING_LOCATION_TYPE_REGIONAL"
// * All proximity location
// list:
// `locationType="TARGETING_LOCATION_TYPE_PROXIMITY"
func (c *AdvertisersLocationListsListCall) Filter(filter string) *AdvertisersLocationListsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `locationListId` (default)
// * `displayName`
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *AdvertisersLocationListsListCall) OrderBy(orderBy string) *AdvertisersLocationListsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`.
// Defaults to `100` if not set. Returns error code `INVALID_ARGUMENT`
// if an
// invalid value is specified.
func (c *AdvertisersLocationListsListCall) PageSize(pageSize int64) *AdvertisersLocationListsListCall {
	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
// next_page_token
// returned from the previous call to `ListLocationLists` method.
// If not specified, the first page of results will be returned.
func (c *AdvertisersLocationListsListCall) PageToken(pageToken string) *AdvertisersLocationListsListCall {
	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 *AdvertisersLocationListsListCall) Fields(s ...googleapi.Field) *AdvertisersLocationListsListCall {
	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 *AdvertisersLocationListsListCall) IfNoneMatch(entityTag string) *AdvertisersLocationListsListCall {
	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 *AdvertisersLocationListsListCall) Context(ctx context.Context) *AdvertisersLocationListsListCall {
	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 *AdvertisersLocationListsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLocationListsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/locationLists")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.locationLists.list" call.
// Exactly one of *ListLocationListsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListLocationListsResponse.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 *AdvertisersLocationListsListCall) Do(opts ...googleapi.CallOption) (*ListLocationListsResponse, 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 := &ListLocationListsResponse{
		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 location lists based on a given advertiser id.",
	//   "flatPath": "v1/advertisers/{advertisersId}/locationLists",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.locationLists.list",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the fetched location lists belong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by location list fields.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by `AND` or `OR` logical operators. A\nsequence of restrictions implicitly uses `AND`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `locationType`\n\nExamples:\n\n* All regional location list:\n`locationType=\"TARGETING_LOCATION_TYPE_REGIONAL\"`\n* All proximity location list:\n`locationType=\"TARGETING_LOCATION_TYPE_PROXIMITY\"`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `locationListId` (default)\n* `displayName`\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`.\nDefaults to `100` if not set. Returns error code `INVALID_ARGUMENT` if an\ninvalid value is specified.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results the server should return.\n\nTypically, this is the value of\nnext_page_token\nreturned from the previous call to `ListLocationLists` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/locationLists",
	//   "response": {
	//     "$ref": "ListLocationListsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersLocationListsListCall) Pages(ctx context.Context, f func(*ListLocationListsResponse) 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 "displayvideo.advertisers.negativeKeywordLists.get":

type AdvertisersNegativeKeywordListsGetCall struct {
	s                     *Service
	advertiserId          int64
	negativeKeywordListId int64
	urlParams_            gensupport.URLParams
	ifNoneMatch_          string
	ctx_                  context.Context
	header_               http.Header
}

// Get: Gets a negative keyword list given an advertiser ID and a
// negative keyword
// list ID.
func (r *AdvertisersNegativeKeywordListsService) Get(advertiserId int64, negativeKeywordListId int64) *AdvertisersNegativeKeywordListsGetCall {
	c := &AdvertisersNegativeKeywordListsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.negativeKeywordListId = negativeKeywordListId
	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 *AdvertisersNegativeKeywordListsGetCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsGetCall {
	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 *AdvertisersNegativeKeywordListsGetCall) IfNoneMatch(entityTag string) *AdvertisersNegativeKeywordListsGetCall {
	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 *AdvertisersNegativeKeywordListsGetCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsGetCall {
	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 *AdvertisersNegativeKeywordListsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/negativeKeywordLists/{+negativeKeywordListId}")
	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{
		"advertiserId":          strconv.FormatInt(c.advertiserId, 10),
		"negativeKeywordListId": strconv.FormatInt(c.negativeKeywordListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.negativeKeywordLists.get" call.
// Exactly one of *NegativeKeywordList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *NegativeKeywordList.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 *AdvertisersNegativeKeywordListsGetCall) Do(opts ...googleapi.CallOption) (*NegativeKeywordList, 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 := &NegativeKeywordList{
		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 negative keyword list given an advertiser ID and a negative keyword\nlist ID.",
	//   "flatPath": "v1/advertisers/{advertisersId}/negativeKeywordLists/{negativeKeywordListsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "negativeKeywordListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the fetched negative keyword list\nbelongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "negativeKeywordListId": {
	//       "description": "Required. The ID of the negative keyword list to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/negativeKeywordLists/{+negativeKeywordListId}",
	//   "response": {
	//     "$ref": "NegativeKeywordList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.negativeKeywordLists.list":

type AdvertisersNegativeKeywordListsListCall struct {
	s            *Service
	advertiserId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists negative keyword lists based on a given advertiser id.
func (r *AdvertisersNegativeKeywordListsService) List(advertiserId int64) *AdvertisersNegativeKeywordListsListCall {
	c := &AdvertisersNegativeKeywordListsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`.
// Defaults to `100` if not set. Returns error code `INVALID_ARGUMENT`
// if an
// invalid value is specified.
func (c *AdvertisersNegativeKeywordListsListCall) PageSize(pageSize int64) *AdvertisersNegativeKeywordListsListCall {
	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
// next_page_token
// returned from the previous call to `ListNegativeKeywordLists`
// method.
// If not specified, the first page of results will be returned.
func (c *AdvertisersNegativeKeywordListsListCall) PageToken(pageToken string) *AdvertisersNegativeKeywordListsListCall {
	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 *AdvertisersNegativeKeywordListsListCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsListCall {
	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 *AdvertisersNegativeKeywordListsListCall) IfNoneMatch(entityTag string) *AdvertisersNegativeKeywordListsListCall {
	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 *AdvertisersNegativeKeywordListsListCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsListCall {
	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 *AdvertisersNegativeKeywordListsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/negativeKeywordLists")
	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{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.negativeKeywordLists.list" call.
// Exactly one of *ListNegativeKeywordListsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListNegativeKeywordListsResponse.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 *AdvertisersNegativeKeywordListsListCall) Do(opts ...googleapi.CallOption) (*ListNegativeKeywordListsResponse, 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 := &ListNegativeKeywordListsResponse{
		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 negative keyword lists based on a given advertiser id.",
	//   "flatPath": "v1/advertisers/{advertisersId}/negativeKeywordLists",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.list",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the fetched negative keyword lists\nbelong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`.\nDefaults to `100` if not set. Returns error code `INVALID_ARGUMENT` if an\ninvalid value is specified.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results the server should return.\n\nTypically, this is the value of\nnext_page_token\nreturned from the previous call to `ListNegativeKeywordLists` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/negativeKeywordLists",
	//   "response": {
	//     "$ref": "ListNegativeKeywordListsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersNegativeKeywordListsListCall) Pages(ctx context.Context, f func(*ListNegativeKeywordListsResponse) 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 "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.create":

type AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall struct {
	s                       *Service
	advertiserId            int64
	targetingType           string
	assignedtargetingoption *AssignedTargetingOption
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Create: Assigns a targeting option to an advertiser.
// Returns the assigned targeting option if successful.
func (r *AdvertisersTargetingTypesAssignedTargetingOptionsService) Create(advertiserId int64, targetingType string, assignedtargetingoption *AssignedTargetingOption) *AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall {
	c := &AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.targetingType = targetingType
	c.assignedtargetingoption = assignedtargetingoption
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall) Fields(s ...googleapi.Field) *AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall) Context(ctx context.Context) *AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.assignedtargetingoption)
	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/advertisers/{+advertiserId}/targetingTypes/{+targetingType}/assignedTargetingOptions")
	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{
		"advertiserId":  strconv.FormatInt(c.advertiserId, 10),
		"targetingType": c.targetingType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.create" call.
// Exactly one of *AssignedTargetingOption or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AssignedTargetingOption.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 *AdvertisersTargetingTypesAssignedTargetingOptionsCreateCall) Do(opts ...googleapi.CallOption) (*AssignedTargetingOption, 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 := &AssignedTargetingOption{
		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": "Assigns a targeting option to an advertiser.\nReturns the assigned targeting option if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/targetingTypes/{targetingTypesId}/assignedTargetingOptions",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.create",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "targetingType"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. Identifies the type of this assigned targeting option.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/targetingTypes/{+targetingType}/assignedTargetingOptions",
	//   "request": {
	//     "$ref": "AssignedTargetingOption"
	//   },
	//   "response": {
	//     "$ref": "AssignedTargetingOption"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.delete":

type AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall struct {
	s                         *Service
	advertiserId              int64
	targetingType             string
	assignedTargetingOptionId string
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Delete: Deletes an assigned targeting option from an advertiser.
func (r *AdvertisersTargetingTypesAssignedTargetingOptionsService) Delete(advertiserId int64, targetingType string, assignedTargetingOptionId string) *AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall {
	c := &AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.targetingType = targetingType
	c.assignedTargetingOptionId = assignedTargetingOptionId
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall) Fields(s ...googleapi.Field) *AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall) Context(ctx context.Context) *AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/advertisers/{+advertiserId}/targetingTypes/{+targetingType}/assignedTargetingOptions/{+assignedTargetingOptionId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"advertiserId":              strconv.FormatInt(c.advertiserId, 10),
		"targetingType":             c.targetingType,
		"assignedTargetingOptionId": c.assignedTargetingOptionId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AdvertisersTargetingTypesAssignedTargetingOptionsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Empty{
		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": "Deletes an assigned targeting option from an advertiser.",
	//   "flatPath": "v1/advertisers/{advertisersId}/targetingTypes/{targetingTypesId}/assignedTargetingOptions/{assignedTargetingOptionsId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "targetingType",
	//     "assignedTargetingOptionId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "assignedTargetingOptionId": {
	//       "description": "Required. The ID of the assigned targeting option to delete.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. Identifies the type of this assigned targeting option.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/targetingTypes/{+targetingType}/assignedTargetingOptions/{+assignedTargetingOptionId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.get":

type AdvertisersTargetingTypesAssignedTargetingOptionsGetCall struct {
	s                         *Service
	advertiserId              int64
	targetingType             string
	assignedTargetingOptionId string
	urlParams_                gensupport.URLParams
	ifNoneMatch_              string
	ctx_                      context.Context
	header_                   http.Header
}

// Get: Gets a single targeting option assigned to an advertiser.
func (r *AdvertisersTargetingTypesAssignedTargetingOptionsService) Get(advertiserId int64, targetingType string, assignedTargetingOptionId string) *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall {
	c := &AdvertisersTargetingTypesAssignedTargetingOptionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.targetingType = targetingType
	c.assignedTargetingOptionId = assignedTargetingOptionId
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall) Fields(s ...googleapi.Field) *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall) IfNoneMatch(entityTag string) *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall) Context(ctx context.Context) *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/targetingTypes/{+targetingType}/assignedTargetingOptions/{+assignedTargetingOptionId}")
	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{
		"advertiserId":              strconv.FormatInt(c.advertiserId, 10),
		"targetingType":             c.targetingType,
		"assignedTargetingOptionId": c.assignedTargetingOptionId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.get" call.
// Exactly one of *AssignedTargetingOption or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AssignedTargetingOption.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 *AdvertisersTargetingTypesAssignedTargetingOptionsGetCall) Do(opts ...googleapi.CallOption) (*AssignedTargetingOption, 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 := &AssignedTargetingOption{
		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 single targeting option assigned to an advertiser.",
	//   "flatPath": "v1/advertisers/{advertisersId}/targetingTypes/{targetingTypesId}/assignedTargetingOptions/{assignedTargetingOptionsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "targetingType",
	//     "assignedTargetingOptionId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "assignedTargetingOptionId": {
	//       "description": "Required. An identifier unique to the targeting type in this advertiser that\nidentifies the assigned targeting option being requested.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. Identifies the type of this assigned targeting option.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/targetingTypes/{+targetingType}/assignedTargetingOptions/{+assignedTargetingOptionId}",
	//   "response": {
	//     "$ref": "AssignedTargetingOption"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.list":

type AdvertisersTargetingTypesAssignedTargetingOptionsListCall struct {
	s             *Service
	advertiserId  int64
	targetingType string
	urlParams_    gensupport.URLParams
	ifNoneMatch_  string
	ctx_          context.Context
	header_       http.Header
}

// List: Lists the targeting options assigned to an advertiser.
func (r *AdvertisersTargetingTypesAssignedTargetingOptionsService) List(advertiserId int64, targetingType string) *AdvertisersTargetingTypesAssignedTargetingOptionsListCall {
	c := &AdvertisersTargetingTypesAssignedTargetingOptionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.targetingType = targetingType
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// assigned targeting option properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by the logical operator `OR`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `assignedTargetingOptionId`
//
// Examples:
//
// * AssignedTargetingOption with ID
// 123456
// `assignedTargetingOptionId="123456"
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) Filter(filter string) *AdvertisersTargetingTypesAssignedTargetingOptionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `assignedTargetingOptionId` (default)
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `assignedTargetingOptionId desc`.
func (c *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) OrderBy(orderBy string) *AdvertisersTargetingTypesAssignedTargetingOptionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) PageSize(pageSize int64) *AdvertisersTargetingTypesAssignedTargetingOptionsListCall {
	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
// next_page_token
// returned from the previous call to
// `ListAdvertiserAssignedTargetingOptions`
// method. If not specified, the first page of results will be returned.
func (c *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) PageToken(pageToken string) *AdvertisersTargetingTypesAssignedTargetingOptionsListCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) Fields(s ...googleapi.Field) *AdvertisersTargetingTypesAssignedTargetingOptionsListCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) IfNoneMatch(entityTag string) *AdvertisersTargetingTypesAssignedTargetingOptionsListCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) Context(ctx context.Context) *AdvertisersTargetingTypesAssignedTargetingOptionsListCall {
	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 *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/advertisers/{+advertiserId}/targetingTypes/{+targetingType}/assignedTargetingOptions")
	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{
		"advertiserId":  strconv.FormatInt(c.advertiserId, 10),
		"targetingType": c.targetingType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.list" call.
// Exactly one of *ListAdvertiserAssignedTargetingOptionsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *ListAdvertiserAssignedTargetingOptionsResponse.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 *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) Do(opts ...googleapi.CallOption) (*ListAdvertiserAssignedTargetingOptionsResponse, 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 := &ListAdvertiserAssignedTargetingOptionsResponse{
		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 targeting options assigned to an advertiser.",
	//   "flatPath": "v1/advertisers/{advertisersId}/targetingTypes/{targetingTypesId}/assignedTargetingOptions",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.targetingTypes.assignedTargetingOptions.list",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "targetingType"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by assigned targeting option properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by the logical operator `OR`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `assignedTargetingOptionId`\n\nExamples:\n\n* AssignedTargetingOption with ID 123456\n`assignedTargetingOptionId=\"123456\"`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `assignedTargetingOptionId` (default)\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`assignedTargetingOptionId desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListAdvertiserAssignedTargetingOptions`\nmethod. If not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. Identifies the type of assigned targeting options to list.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/targetingTypes/{+targetingType}/assignedTargetingOptions",
	//   "response": {
	//     "$ref": "ListAdvertiserAssignedTargetingOptionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *AdvertisersTargetingTypesAssignedTargetingOptionsListCall) Pages(ctx context.Context, f func(*ListAdvertiserAssignedTargetingOptionsResponse) 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 "displayvideo.combinedAudiences.get":

type CombinedAudiencesGetCall struct {
	s                  *Service
	combinedAudienceId int64
	urlParams_         gensupport.URLParams
	ifNoneMatch_       string
	ctx_               context.Context
	header_            http.Header
}

// Get: Gets a combined audience.
func (r *CombinedAudiencesService) Get(combinedAudienceId int64) *CombinedAudiencesGetCall {
	c := &CombinedAudiencesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.combinedAudienceId = combinedAudienceId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the fetched combined
// audience.
func (c *CombinedAudiencesGetCall) AdvertiserId(advertiserId int64) *CombinedAudiencesGetCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the fetched combined audience.
func (c *CombinedAudiencesGetCall) PartnerId(partnerId int64) *CombinedAudiencesGetCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *CombinedAudiencesGetCall) Fields(s ...googleapi.Field) *CombinedAudiencesGetCall {
	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 *CombinedAudiencesGetCall) IfNoneMatch(entityTag string) *CombinedAudiencesGetCall {
	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 *CombinedAudiencesGetCall) Context(ctx context.Context) *CombinedAudiencesGetCall {
	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 *CombinedAudiencesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CombinedAudiencesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/combinedAudiences/{+combinedAudienceId}")
	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{
		"combinedAudienceId": strconv.FormatInt(c.combinedAudienceId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.combinedAudiences.get" call.
// Exactly one of *CombinedAudience or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CombinedAudience.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 *CombinedAudiencesGetCall) Do(opts ...googleapi.CallOption) (*CombinedAudience, 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 := &CombinedAudience{
		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 combined audience.",
	//   "flatPath": "v1/combinedAudiences/{combinedAudiencesId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.combinedAudiences.get",
	//   "parameterOrder": [
	//     "combinedAudienceId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the fetched combined\naudience.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "combinedAudienceId": {
	//       "description": "Required. The ID of the combined audience to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the fetched combined audience.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/combinedAudiences/{+combinedAudienceId}",
	//   "response": {
	//     "$ref": "CombinedAudience"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.combinedAudiences.list":

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

// List: Lists combined audiences.
//
// The order is defined by the
// order_by parameter.
func (r *CombinedAudiencesService) List() *CombinedAudiencesListCall {
	c := &CombinedAudiencesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the fetched combined
// audiences.
func (c *CombinedAudiencesListCall) AdvertiserId(advertiserId int64) *CombinedAudiencesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// combined audience fields.
//
// Supported syntax:
//
// * Filter expressions for combined audiences currently can only
// contain at
// most one restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `displayName`
//
// Examples:
//
// * All combined audiences for which the display name contains
// "Google":
// `displayName : "Google".
//
// The length of this field should be no more than 500 characters.
func (c *CombinedAudiencesListCall) Filter(filter string) *CombinedAudiencesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `combinedAudienceId` (default)
// * `displayName`
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *CombinedAudiencesListCall) OrderBy(orderBy string) *CombinedAudiencesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *CombinedAudiencesListCall) PageSize(pageSize int64) *CombinedAudiencesListCall {
	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
// next_page_token
// returned from the previous call to `ListCombinedAudiences` method.
// If not specified, the first page of results will be returned.
func (c *CombinedAudiencesListCall) PageToken(pageToken string) *CombinedAudiencesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the fetched combined audiences.
func (c *CombinedAudiencesListCall) PartnerId(partnerId int64) *CombinedAudiencesListCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *CombinedAudiencesListCall) Fields(s ...googleapi.Field) *CombinedAudiencesListCall {
	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 *CombinedAudiencesListCall) IfNoneMatch(entityTag string) *CombinedAudiencesListCall {
	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 *CombinedAudiencesListCall) Context(ctx context.Context) *CombinedAudiencesListCall {
	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 *CombinedAudiencesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CombinedAudiencesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/combinedAudiences")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.combinedAudiences.list" call.
// Exactly one of *ListCombinedAudiencesResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListCombinedAudiencesResponse.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 *CombinedAudiencesListCall) Do(opts ...googleapi.CallOption) (*ListCombinedAudiencesResponse, 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 := &ListCombinedAudiencesResponse{
		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 combined audiences.\n\nThe order is defined by the\norder_by parameter.",
	//   "flatPath": "v1/combinedAudiences",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.combinedAudiences.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the fetched combined\naudiences.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by combined audience fields.\n\nSupported syntax:\n\n* Filter expressions for combined audiences currently can only contain at\nmost one restriction.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `CONTAINS (:)`.\n* Supported fields:\n    - `displayName`\n\nExamples:\n\n* All combined audiences for which the display name contains \"Google\":\n`displayName : \"Google\"`.\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `combinedAudienceId` (default)\n* `displayName`\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListCombinedAudiences` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the fetched combined audiences.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/combinedAudiences",
	//   "response": {
	//     "$ref": "ListCombinedAudiencesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *CombinedAudiencesListCall) Pages(ctx context.Context, f func(*ListCombinedAudiencesResponse) 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 "displayvideo.customLists.get":

type CustomListsGetCall struct {
	s            *Service
	customListId int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a custom list.
func (r *CustomListsService) Get(customListId int64) *CustomListsGetCall {
	c := &CustomListsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.customListId = customListId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the DV360 advertiser that has access to the fetched custom
// lists.
func (c *CustomListsGetCall) AdvertiserId(advertiserId int64) *CustomListsGetCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	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 *CustomListsGetCall) Fields(s ...googleapi.Field) *CustomListsGetCall {
	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 *CustomListsGetCall) IfNoneMatch(entityTag string) *CustomListsGetCall {
	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 *CustomListsGetCall) Context(ctx context.Context) *CustomListsGetCall {
	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 *CustomListsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomListsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/customLists/{+customListId}")
	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{
		"customListId": strconv.FormatInt(c.customListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.customLists.get" call.
// Exactly one of *CustomList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CustomList.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 *CustomListsGetCall) Do(opts ...googleapi.CallOption) (*CustomList, 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 := &CustomList{
		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 custom list.",
	//   "flatPath": "v1/customLists/{customListsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.customLists.get",
	//   "parameterOrder": [
	//     "customListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the DV360 advertiser that has access to the fetched custom\nlists.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "customListId": {
	//       "description": "Required. The ID of the custom list to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/customLists/{+customListId}",
	//   "response": {
	//     "$ref": "CustomList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.customLists.list":

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

// List: Lists custom lists.
//
// The order is defined by the order_by
// parameter.
func (r *CustomListsService) List() *CustomListsListCall {
	c := &CustomListsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the DV360 advertiser that has access to the fetched custom
// lists.
func (c *CustomListsListCall) AdvertiserId(advertiserId int64) *CustomListsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// custom list fields.
//
// Supported syntax:
//
// * Filter expressions for custom lists currently can only contain
// at
// most one restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `displayName`
//
// Examples:
//
// * All custom lists for which the display name contains
// "Google":
// `displayName : "Google".
//
// The length of this field should be no more than 500 characters.
func (c *CustomListsListCall) Filter(filter string) *CustomListsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `customListId` (default)
// * `displayName`
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *CustomListsListCall) OrderBy(orderBy string) *CustomListsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *CustomListsListCall) PageSize(pageSize int64) *CustomListsListCall {
	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
// next_page_token
// returned from the previous call to `ListCustomLists` method.
// If not specified, the first page of results will be returned.
func (c *CustomListsListCall) PageToken(pageToken string) *CustomListsListCall {
	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 *CustomListsListCall) Fields(s ...googleapi.Field) *CustomListsListCall {
	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 *CustomListsListCall) IfNoneMatch(entityTag string) *CustomListsListCall {
	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 *CustomListsListCall) Context(ctx context.Context) *CustomListsListCall {
	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 *CustomListsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomListsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/customLists")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.customLists.list" call.
// Exactly one of *ListCustomListsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListCustomListsResponse.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 *CustomListsListCall) Do(opts ...googleapi.CallOption) (*ListCustomListsResponse, 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 := &ListCustomListsResponse{
		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 custom lists.\n\nThe order is defined by the order_by\nparameter.",
	//   "flatPath": "v1/customLists",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.customLists.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the DV360 advertiser that has access to the fetched custom\nlists.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by custom list fields.\n\nSupported syntax:\n\n* Filter expressions for custom lists currently can only contain at\nmost one restriction.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `CONTAINS (:)`.\n* Supported fields:\n    - `displayName`\n\nExamples:\n\n* All custom lists for which the display name contains \"Google\":\n`displayName : \"Google\"`.\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `customListId` (default)\n* `displayName`\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListCustomLists` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/customLists",
	//   "response": {
	//     "$ref": "ListCustomListsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *CustomListsListCall) Pages(ctx context.Context, f func(*ListCustomListsResponse) 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 "displayvideo.firstAndThirdPartyAudiences.get":

type FirstAndThirdPartyAudiencesGetCall struct {
	s                            *Service
	firstAndThirdPartyAudienceId int64
	urlParams_                   gensupport.URLParams
	ifNoneMatch_                 string
	ctx_                         context.Context
	header_                      http.Header
}

// Get: Gets a first and third party audience.
func (r *FirstAndThirdPartyAudiencesService) Get(firstAndThirdPartyAudienceId int64) *FirstAndThirdPartyAudiencesGetCall {
	c := &FirstAndThirdPartyAudiencesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.firstAndThirdPartyAudienceId = firstAndThirdPartyAudienceId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the fetched first and
// third party audience.
func (c *FirstAndThirdPartyAudiencesGetCall) AdvertiserId(advertiserId int64) *FirstAndThirdPartyAudiencesGetCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the fetched first and
// third party audience.
func (c *FirstAndThirdPartyAudiencesGetCall) PartnerId(partnerId int64) *FirstAndThirdPartyAudiencesGetCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *FirstAndThirdPartyAudiencesGetCall) Fields(s ...googleapi.Field) *FirstAndThirdPartyAudiencesGetCall {
	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 *FirstAndThirdPartyAudiencesGetCall) IfNoneMatch(entityTag string) *FirstAndThirdPartyAudiencesGetCall {
	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 *FirstAndThirdPartyAudiencesGetCall) Context(ctx context.Context) *FirstAndThirdPartyAudiencesGetCall {
	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 *FirstAndThirdPartyAudiencesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FirstAndThirdPartyAudiencesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/firstAndThirdPartyAudiences/{+firstAndThirdPartyAudienceId}")
	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{
		"firstAndThirdPartyAudienceId": strconv.FormatInt(c.firstAndThirdPartyAudienceId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.firstAndThirdPartyAudiences.get" call.
// Exactly one of *FirstAndThirdPartyAudience or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *FirstAndThirdPartyAudience.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 *FirstAndThirdPartyAudiencesGetCall) Do(opts ...googleapi.CallOption) (*FirstAndThirdPartyAudience, 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 := &FirstAndThirdPartyAudience{
		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 first and third party audience.",
	//   "flatPath": "v1/firstAndThirdPartyAudiences/{firstAndThirdPartyAudiencesId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.firstAndThirdPartyAudiences.get",
	//   "parameterOrder": [
	//     "firstAndThirdPartyAudienceId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the fetched first and\nthird party audience.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "firstAndThirdPartyAudienceId": {
	//       "description": "Required. The ID of the first and third party audience to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the fetched first and\nthird party audience.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/firstAndThirdPartyAudiences/{+firstAndThirdPartyAudienceId}",
	//   "response": {
	//     "$ref": "FirstAndThirdPartyAudience"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.firstAndThirdPartyAudiences.list":

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

// List: Lists first and third party audiences.
//
// The order is defined by the
// order_by parameter.
func (r *FirstAndThirdPartyAudiencesService) List() *FirstAndThirdPartyAudiencesListCall {
	c := &FirstAndThirdPartyAudiencesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the fetched first and
// third party audiences.
func (c *FirstAndThirdPartyAudiencesListCall) AdvertiserId(advertiserId int64) *FirstAndThirdPartyAudiencesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// first and third party audience fields.
//
// Supported syntax:
//
// * Filter expressions for first and third party audiences currently
// can
// only contain at most one restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `displayName`
//
// Examples:
//
// * All first and third party audiences for which the display name
// contains
// "Google": `displayName : "Google".
//
// The length of this field should be no more than 500 characters.
func (c *FirstAndThirdPartyAudiencesListCall) Filter(filter string) *FirstAndThirdPartyAudiencesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `firstAndThirdPartyAudienceId` (default)
// * `displayName`
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *FirstAndThirdPartyAudiencesListCall) OrderBy(orderBy string) *FirstAndThirdPartyAudiencesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *FirstAndThirdPartyAudiencesListCall) PageSize(pageSize int64) *FirstAndThirdPartyAudiencesListCall {
	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
// next_page_token
// returned from the previous call to
// `ListFirstAndThirdPartyAudiences`
// method. If not specified, the first page of results will be returned.
func (c *FirstAndThirdPartyAudiencesListCall) PageToken(pageToken string) *FirstAndThirdPartyAudiencesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the fetched first and
// third party audiences.
func (c *FirstAndThirdPartyAudiencesListCall) PartnerId(partnerId int64) *FirstAndThirdPartyAudiencesListCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *FirstAndThirdPartyAudiencesListCall) Fields(s ...googleapi.Field) *FirstAndThirdPartyAudiencesListCall {
	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 *FirstAndThirdPartyAudiencesListCall) IfNoneMatch(entityTag string) *FirstAndThirdPartyAudiencesListCall {
	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 *FirstAndThirdPartyAudiencesListCall) Context(ctx context.Context) *FirstAndThirdPartyAudiencesListCall {
	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 *FirstAndThirdPartyAudiencesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FirstAndThirdPartyAudiencesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/firstAndThirdPartyAudiences")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.firstAndThirdPartyAudiences.list" call.
// Exactly one of *ListFirstAndThirdPartyAudiencesResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *ListFirstAndThirdPartyAudiencesResponse.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 *FirstAndThirdPartyAudiencesListCall) Do(opts ...googleapi.CallOption) (*ListFirstAndThirdPartyAudiencesResponse, 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 := &ListFirstAndThirdPartyAudiencesResponse{
		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 first and third party audiences.\n\nThe order is defined by the\norder_by parameter.",
	//   "flatPath": "v1/firstAndThirdPartyAudiences",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.firstAndThirdPartyAudiences.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the fetched first and\nthird party audiences.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by first and third party audience fields.\n\nSupported syntax:\n\n* Filter expressions for first and third party audiences currently can\nonly contain at most one restriction.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `CONTAINS (:)`.\n* Supported fields:\n    - `displayName`\n\nExamples:\n\n* All first and third party audiences for which the display name contains\n\"Google\": `displayName : \"Google\"`.\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `firstAndThirdPartyAudienceId` (default)\n* `displayName`\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListFirstAndThirdPartyAudiences`\nmethod. If not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the fetched first and\nthird party audiences.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/firstAndThirdPartyAudiences",
	//   "response": {
	//     "$ref": "ListFirstAndThirdPartyAudiencesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *FirstAndThirdPartyAudiencesListCall) Pages(ctx context.Context, f func(*ListFirstAndThirdPartyAudiencesResponse) 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 "displayvideo.floodlightGroups.get":

type FloodlightGroupsGetCall struct {
	s                 *Service
	floodlightGroupId int64
	urlParams_        gensupport.URLParams
	ifNoneMatch_      string
	ctx_              context.Context
	header_           http.Header
}

// Get: Gets a Floodlight group.
func (r *FloodlightGroupsService) Get(floodlightGroupId int64) *FloodlightGroupsGetCall {
	c := &FloodlightGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.floodlightGroupId = floodlightGroupId
	return c
}

// PartnerId sets the optional parameter "partnerId": Required. The
// partner context by which the Floodlight group is being accessed.
func (c *FloodlightGroupsGetCall) PartnerId(partnerId int64) *FloodlightGroupsGetCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *FloodlightGroupsGetCall) Fields(s ...googleapi.Field) *FloodlightGroupsGetCall {
	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 *FloodlightGroupsGetCall) IfNoneMatch(entityTag string) *FloodlightGroupsGetCall {
	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 *FloodlightGroupsGetCall) Context(ctx context.Context) *FloodlightGroupsGetCall {
	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 *FloodlightGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/floodlightGroups/{+floodlightGroupId}")
	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{
		"floodlightGroupId": strconv.FormatInt(c.floodlightGroupId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.floodlightGroups.get" call.
// Exactly one of *FloodlightGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *FloodlightGroup.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 *FloodlightGroupsGetCall) Do(opts ...googleapi.CallOption) (*FloodlightGroup, 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 := &FloodlightGroup{
		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 Floodlight group.",
	//   "flatPath": "v1/floodlightGroups/{floodlightGroupsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.floodlightGroups.get",
	//   "parameterOrder": [
	//     "floodlightGroupId"
	//   ],
	//   "parameters": {
	//     "floodlightGroupId": {
	//       "description": "Required. The ID of the Floodlight group to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "Required. The partner context by which the Floodlight group is being accessed.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/floodlightGroups/{+floodlightGroupId}",
	//   "response": {
	//     "$ref": "FloodlightGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.floodlightGroups.patch":

type FloodlightGroupsPatchCall struct {
	s                 *Service
	floodlightGroupId int64
	floodlightgroup   *FloodlightGroup
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Patch: Updates an existing Floodlight group.
// Returns the updated Floodlight group if successful.
func (r *FloodlightGroupsService) Patch(floodlightGroupId int64, floodlightgroup *FloodlightGroup) *FloodlightGroupsPatchCall {
	c := &FloodlightGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.floodlightGroupId = floodlightGroupId
	c.floodlightgroup = floodlightgroup
	return c
}

// PartnerId sets the optional parameter "partnerId": Required. The
// partner context by which the Floodlight group is being accessed.
func (c *FloodlightGroupsPatchCall) PartnerId(partnerId int64) *FloodlightGroupsPatchCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *FloodlightGroupsPatchCall) UpdateMask(updateMask string) *FloodlightGroupsPatchCall {
	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 *FloodlightGroupsPatchCall) Fields(s ...googleapi.Field) *FloodlightGroupsPatchCall {
	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 *FloodlightGroupsPatchCall) Context(ctx context.Context) *FloodlightGroupsPatchCall {
	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 *FloodlightGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.floodlightgroup)
	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/floodlightGroups/{floodlightGroupId}")
	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{
		"floodlightGroupId": strconv.FormatInt(c.floodlightGroupId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.floodlightGroups.patch" call.
// Exactly one of *FloodlightGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *FloodlightGroup.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 *FloodlightGroupsPatchCall) Do(opts ...googleapi.CallOption) (*FloodlightGroup, 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 := &FloodlightGroup{
		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 an existing Floodlight group.\nReturns the updated Floodlight group if successful.",
	//   "flatPath": "v1/floodlightGroups/{floodlightGroupId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.floodlightGroups.patch",
	//   "parameterOrder": [
	//     "floodlightGroupId"
	//   ],
	//   "parameters": {
	//     "floodlightGroupId": {
	//       "description": "Output only. The unique ID of the Floodlight group. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "Required. The partner context by which the Floodlight group is being accessed.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Required. The mask to control which fields to update.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/floodlightGroups/{floodlightGroupId}",
	//   "request": {
	//     "$ref": "FloodlightGroup"
	//   },
	//   "response": {
	//     "$ref": "FloodlightGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.googleAudiences.get":

type GoogleAudiencesGetCall struct {
	s                *Service
	googleAudienceId int64
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
	header_          http.Header
}

// Get: Gets a Google audience.
func (r *GoogleAudiencesService) Get(googleAudienceId int64) *GoogleAudiencesGetCall {
	c := &GoogleAudiencesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.googleAudienceId = googleAudienceId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the fetched Google audience.
func (c *GoogleAudiencesGetCall) AdvertiserId(advertiserId int64) *GoogleAudiencesGetCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the fetched Google audience.
func (c *GoogleAudiencesGetCall) PartnerId(partnerId int64) *GoogleAudiencesGetCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *GoogleAudiencesGetCall) Fields(s ...googleapi.Field) *GoogleAudiencesGetCall {
	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 *GoogleAudiencesGetCall) IfNoneMatch(entityTag string) *GoogleAudiencesGetCall {
	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 *GoogleAudiencesGetCall) Context(ctx context.Context) *GoogleAudiencesGetCall {
	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 *GoogleAudiencesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GoogleAudiencesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/googleAudiences/{+googleAudienceId}")
	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{
		"googleAudienceId": strconv.FormatInt(c.googleAudienceId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.googleAudiences.get" call.
// Exactly one of *GoogleAudience or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *GoogleAudience.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 *GoogleAudiencesGetCall) Do(opts ...googleapi.CallOption) (*GoogleAudience, 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 := &GoogleAudience{
		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 Google audience.",
	//   "flatPath": "v1/googleAudiences/{googleAudiencesId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.googleAudiences.get",
	//   "parameterOrder": [
	//     "googleAudienceId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the fetched Google audience.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "googleAudienceId": {
	//       "description": "Required. The ID of the Google audience to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the fetched Google audience.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/googleAudiences/{+googleAudienceId}",
	//   "response": {
	//     "$ref": "GoogleAudience"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.googleAudiences.list":

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

// List: Lists Google audiences.
//
// The order is defined by the order_by
// parameter.
func (r *GoogleAudiencesService) List() *GoogleAudiencesListCall {
	c := &GoogleAudiencesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the fetched Google audiences.
func (c *GoogleAudiencesListCall) AdvertiserId(advertiserId int64) *GoogleAudiencesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// Google audience fields.
//
// Supported syntax:
//
// * Filter expressions for Google audiences currently can only contain
// at
// most one restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `displayName`
//
// Examples:
//
// * All Google audiences for which the display name contains
// "Google":
// `displayName : "Google".
//
// The length of this field should be no more than 500 characters.
func (c *GoogleAudiencesListCall) Filter(filter string) *GoogleAudiencesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `googleAudienceId` (default)
// * `displayName`
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *GoogleAudiencesListCall) OrderBy(orderBy string) *GoogleAudiencesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *GoogleAudiencesListCall) PageSize(pageSize int64) *GoogleAudiencesListCall {
	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
// next_page_token
// returned from the previous call to `ListGoogleAudiences` method.
// If not specified, the first page of results will be returned.
func (c *GoogleAudiencesListCall) PageToken(pageToken string) *GoogleAudiencesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the fetched Google audiences.
func (c *GoogleAudiencesListCall) PartnerId(partnerId int64) *GoogleAudiencesListCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *GoogleAudiencesListCall) Fields(s ...googleapi.Field) *GoogleAudiencesListCall {
	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 *GoogleAudiencesListCall) IfNoneMatch(entityTag string) *GoogleAudiencesListCall {
	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 *GoogleAudiencesListCall) Context(ctx context.Context) *GoogleAudiencesListCall {
	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 *GoogleAudiencesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *GoogleAudiencesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/googleAudiences")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.googleAudiences.list" call.
// Exactly one of *ListGoogleAudiencesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListGoogleAudiencesResponse.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 *GoogleAudiencesListCall) Do(opts ...googleapi.CallOption) (*ListGoogleAudiencesResponse, 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 := &ListGoogleAudiencesResponse{
		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 Google audiences.\n\nThe order is defined by the order_by\nparameter.",
	//   "flatPath": "v1/googleAudiences",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.googleAudiences.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the fetched Google audiences.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by Google audience fields.\n\nSupported syntax:\n\n* Filter expressions for Google audiences currently can only contain at\nmost one restriction.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `CONTAINS (:)`.\n* Supported fields:\n    - `displayName`\n\nExamples:\n\n* All Google audiences for which the display name contains \"Google\":\n`displayName : \"Google\"`.\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `googleAudienceId` (default)\n* `displayName`\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListGoogleAudiences` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the fetched Google audiences.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/googleAudiences",
	//   "response": {
	//     "$ref": "ListGoogleAudiencesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *GoogleAudiencesListCall) Pages(ctx context.Context, f func(*ListGoogleAudiencesResponse) 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 "displayvideo.inventorySourceGroups.get":

type InventorySourceGroupsGetCall struct {
	s                      *Service
	inventorySourceGroupId int64
	urlParams_             gensupport.URLParams
	ifNoneMatch_           string
	ctx_                   context.Context
	header_                http.Header
}

// Get: Gets an inventory source group.
func (r *InventorySourceGroupsService) Get(inventorySourceGroupId int64) *InventorySourceGroupsGetCall {
	c := &InventorySourceGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.inventorySourceGroupId = inventorySourceGroupId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the inventory source group.
//
// If an inventory source group is partner-owned, only advertisers to
// which
// the group is explicitly shared can access the group.
func (c *InventorySourceGroupsGetCall) AdvertiserId(advertiserId int64) *InventorySourceGroupsGetCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the inventory source group.
//
// A partner cannot access an advertiser-owned inventory source group.
func (c *InventorySourceGroupsGetCall) PartnerId(partnerId int64) *InventorySourceGroupsGetCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *InventorySourceGroupsGetCall) Fields(s ...googleapi.Field) *InventorySourceGroupsGetCall {
	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 *InventorySourceGroupsGetCall) IfNoneMatch(entityTag string) *InventorySourceGroupsGetCall {
	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 *InventorySourceGroupsGetCall) Context(ctx context.Context) *InventorySourceGroupsGetCall {
	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 *InventorySourceGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/inventorySourceGroups/{+inventorySourceGroupId}")
	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{
		"inventorySourceGroupId": strconv.FormatInt(c.inventorySourceGroupId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySourceGroups.get" call.
// Exactly one of *InventorySourceGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *InventorySourceGroup.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 *InventorySourceGroupsGetCall) Do(opts ...googleapi.CallOption) (*InventorySourceGroup, 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 := &InventorySourceGroup{
		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 an inventory source group.",
	//   "flatPath": "v1/inventorySourceGroups/{inventorySourceGroupsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.inventorySourceGroups.get",
	//   "parameterOrder": [
	//     "inventorySourceGroupId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the inventory source group.\n\nIf an inventory source group is partner-owned, only advertisers to which\nthe group is explicitly shared can access the group.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "inventorySourceGroupId": {
	//       "description": "Required. The ID of the inventory source group to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the inventory source group.\n\nA partner cannot access an advertiser-owned inventory source group.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySourceGroups/{+inventorySourceGroupId}",
	//   "response": {
	//     "$ref": "InventorySourceGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.inventorySourceGroups.list":

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

// List: Lists inventory source groups that are accessible to the
// current user.
//
// The order is defined by the
// order_by parameter.
func (r *InventorySourceGroupsService) List() *InventorySourceGroupsListCall {
	c := &InventorySourceGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the inventory source group.
//
// If an inventory source group is partner-owned, only advertisers to
// which
// the group is explicitly shared can access the group.
func (c *InventorySourceGroupsListCall) AdvertiserId(advertiserId int64) *InventorySourceGroupsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// inventory source group properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by the logical operator `OR`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `inventorySourceGroupId`
//
// The length of this field should be no more than 500 characters.
func (c *InventorySourceGroupsListCall) Filter(filter string) *InventorySourceGroupsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `displayName` (default)
// * `inventorySourceGroupId`
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name. For
// example,
// `displayName desc`.
func (c *InventorySourceGroupsListCall) OrderBy(orderBy string) *InventorySourceGroupsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`.
func (c *InventorySourceGroupsListCall) PageSize(pageSize int64) *InventorySourceGroupsListCall {
	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
// next_page_token
// returned from the previous call to `ListInventorySources` method.
// If not specified, the first page of results will be returned.
func (c *InventorySourceGroupsListCall) PageToken(pageToken string) *InventorySourceGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the inventory source group.
//
// A partner cannot access advertiser-owned inventory source groups.
func (c *InventorySourceGroupsListCall) PartnerId(partnerId int64) *InventorySourceGroupsListCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *InventorySourceGroupsListCall) Fields(s ...googleapi.Field) *InventorySourceGroupsListCall {
	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 *InventorySourceGroupsListCall) IfNoneMatch(entityTag string) *InventorySourceGroupsListCall {
	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 *InventorySourceGroupsListCall) Context(ctx context.Context) *InventorySourceGroupsListCall {
	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 *InventorySourceGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/inventorySourceGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySourceGroups.list" call.
// Exactly one of *ListInventorySourceGroupsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListInventorySourceGroupsResponse.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 *InventorySourceGroupsListCall) Do(opts ...googleapi.CallOption) (*ListInventorySourceGroupsResponse, 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 := &ListInventorySourceGroupsResponse{
		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 inventory source groups that are accessible to the current user.\n\nThe order is defined by the\norder_by parameter.",
	//   "flatPath": "v1/inventorySourceGroups",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.inventorySourceGroups.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the inventory source group.\n\nIf an inventory source group is partner-owned, only advertisers to which\nthe group is explicitly shared can access the group.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by inventory source group properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by the logical operator `OR`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `inventorySourceGroupId`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `displayName` (default)\n* `inventorySourceGroupId`\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. For example,\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListInventorySources` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the inventory source group.\n\nA partner cannot access advertiser-owned inventory source groups.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySourceGroups",
	//   "response": {
	//     "$ref": "ListInventorySourceGroupsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *InventorySourceGroupsListCall) Pages(ctx context.Context, f func(*ListInventorySourceGroupsResponse) 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 "displayvideo.inventorySources.get":

type InventorySourcesGetCall struct {
	s                 *Service
	inventorySourceId int64
	urlParams_        gensupport.URLParams
	ifNoneMatch_      string
	ctx_              context.Context
	header_           http.Header
}

// Get: Gets an inventory source.
func (r *InventorySourcesService) Get(inventorySourceId int64) *InventorySourcesGetCall {
	c := &InventorySourcesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.inventorySourceId = inventorySourceId
	return c
}

// PartnerId sets the optional parameter "partnerId": Required. The ID
// of the DV360 partner to which the fetched inventory source
// is permissioned.
func (c *InventorySourcesGetCall) PartnerId(partnerId int64) *InventorySourcesGetCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *InventorySourcesGetCall) Fields(s ...googleapi.Field) *InventorySourcesGetCall {
	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 *InventorySourcesGetCall) IfNoneMatch(entityTag string) *InventorySourcesGetCall {
	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 *InventorySourcesGetCall) Context(ctx context.Context) *InventorySourcesGetCall {
	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 *InventorySourcesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourcesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/inventorySources/{+inventorySourceId}")
	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{
		"inventorySourceId": strconv.FormatInt(c.inventorySourceId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySources.get" call.
// Exactly one of *InventorySource or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InventorySource.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 *InventorySourcesGetCall) Do(opts ...googleapi.CallOption) (*InventorySource, 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 := &InventorySource{
		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 an inventory source.",
	//   "flatPath": "v1/inventorySources/{inventorySourcesId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.inventorySources.get",
	//   "parameterOrder": [
	//     "inventorySourceId"
	//   ],
	//   "parameters": {
	//     "inventorySourceId": {
	//       "description": "Required. The ID of the inventory source to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "Required. The ID of the DV360 partner to which the fetched inventory source\nis permissioned.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySources/{+inventorySourceId}",
	//   "response": {
	//     "$ref": "InventorySource"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.inventorySources.list":

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

// List: Lists inventory sources that are accessible to the current
// user.
//
// The order is defined by the
// order_by parameter.
// If a filter by
// entity_status is not
// specified, inventory sources with entity status
// `ENTITY_STATUS_ARCHIVED`
// will not be included in the results.
func (r *InventorySourcesService) List() *InventorySourcesListCall {
	c := &InventorySourcesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that has access to the inventory source.
func (c *InventorySourcesListCall) AdvertiserId(advertiserId int64) *InventorySourcesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// inventory source properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by `AND` or `OR` logical operators.
// A
// sequence of restrictions implicitly uses `AND`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `status.entityStatus`
//     - `commitment`
//     - `deliveryMethod`
//     - `rateDetails.rateType`
//     - `exchange`
//
// Examples:
//
// * All active inventory
// sources:
// `status.entityStatus="ENTITY_STATUS_ACTIVE"
// * Inventory sources belonging to Google Ad Manager or Rubicon
// exchanges:
// `exchange="EXCHANGE_GOOGLE_AD_MANAGER" OR
// exchange="EXCHANGE_RUBICON"
//
// The length of this field should be no more than 500 characters.
func (c *InventorySourcesListCall) Filter(filter string) *InventorySourcesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `displayName` (default)
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name. For
// example,
// `displayName desc`.
func (c *InventorySourcesListCall) OrderBy(orderBy string) *InventorySourcesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`.
func (c *InventorySourcesListCall) PageSize(pageSize int64) *InventorySourcesListCall {
	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
// next_page_token
// returned from the previous call to `ListInventorySources` method.
// If not specified, the first page of results will be returned.
func (c *InventorySourcesListCall) PageToken(pageToken string) *InventorySourcesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the inventory source.
func (c *InventorySourcesListCall) PartnerId(partnerId int64) *InventorySourcesListCall {
	c.urlParams_.Set("partnerId", fmt.Sprint(partnerId))
	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 *InventorySourcesListCall) Fields(s ...googleapi.Field) *InventorySourcesListCall {
	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 *InventorySourcesListCall) IfNoneMatch(entityTag string) *InventorySourcesListCall {
	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 *InventorySourcesListCall) Context(ctx context.Context) *InventorySourcesListCall {
	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 *InventorySourcesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourcesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/inventorySources")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySources.list" call.
// Exactly one of *ListInventorySourcesResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListInventorySourcesResponse.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 *InventorySourcesListCall) Do(opts ...googleapi.CallOption) (*ListInventorySourcesResponse, 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 := &ListInventorySourcesResponse{
		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 inventory sources that are accessible to the current user.\n\nThe order is defined by the\norder_by parameter.\nIf a filter by\nentity_status is not\nspecified, inventory sources with entity status `ENTITY_STATUS_ARCHIVED`\nwill not be included in the results.",
	//   "flatPath": "v1/inventorySources",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.inventorySources.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the inventory source.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by inventory source properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by `AND` or `OR` logical operators. A\nsequence of restrictions implicitly uses `AND`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `status.entityStatus`\n    - `commitment`\n    - `deliveryMethod`\n    - `rateDetails.rateType`\n    - `exchange`\n\nExamples:\n\n* All active inventory sources:\n`status.entityStatus=\"ENTITY_STATUS_ACTIVE\"`\n* Inventory sources belonging to Google Ad Manager or Rubicon exchanges:\n`exchange=\"EXCHANGE_GOOGLE_AD_MANAGER\" OR exchange=\"EXCHANGE_RUBICON\"`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `displayName` (default)\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. For example,\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListInventorySources` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that has access to the inventory source.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySources",
	//   "response": {
	//     "$ref": "ListInventorySourcesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *InventorySourcesListCall) Pages(ctx context.Context, f func(*ListInventorySourcesResponse) 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 "displayvideo.media.download":

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

// Download: Downloads media. Download is supported on the URI
// `/download/{resource_name=**}?alt=media.`
//
// **Note**: Download requests will not be successful without including
// `alt=media` query string.
func (r *MediaService) Download(resourceName string) *MediaDownloadCall {
	c := &MediaDownloadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	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 *MediaDownloadCall) Fields(s ...googleapi.Field) *MediaDownloadCall {
	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 *MediaDownloadCall) IfNoneMatch(entityTag string) *MediaDownloadCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do and Download
// methods. Any pending HTTP request will be aborted if the provided
// context is canceled.
func (c *MediaDownloadCall) Context(ctx context.Context) *MediaDownloadCall {
	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 *MediaDownloadCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MediaDownloadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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, "download/{+resourceName}")
	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{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Download fetches the API endpoint's "media" value, instead of the normal
// API response value. If the returned error is nil, the Response is guaranteed to
// have a 2xx status code. Callers must close the Response.Body as usual.
func (c *MediaDownloadCall) Download(opts ...googleapi.CallOption) (*http.Response, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("media")
	if err != nil {
		return nil, err
	}
	if err := googleapi.CheckMediaResponse(res); err != nil {
		res.Body.Close()
		return nil, err
	}
	return res, nil
}

// Do executes the "displayvideo.media.download" call.
// Exactly one of *GoogleBytestreamMedia or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleBytestreamMedia.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 *MediaDownloadCall) Do(opts ...googleapi.CallOption) (*GoogleBytestreamMedia, 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 := &GoogleBytestreamMedia{
		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": "Downloads media. Download is supported on the URI `/download/{resource_name=**}?alt=media.`\n\n**Note**: Download requests will not be successful without including `alt=media` query string.",
	//   "flatPath": "download/{downloadId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.media.download",
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Name of the media that is being downloaded.  See\nReadRequest.resource_name.",
	//       "location": "path",
	//       "pattern": "^.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "download/{+resourceName}",
	//   "response": {
	//     "$ref": "GoogleBytestreamMedia"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video",
	//     "https://www.googleapis.com/auth/doubleclickbidmanager"
	//   ],
	//   "supportsMediaDownload": true
	// }

}

// method id "displayvideo.partners.channels.get":

type PartnersChannelsGetCall struct {
	s            *Service
	partnerId    int64
	channelId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a channel for a partner or advertiser.
func (r *PartnersChannelsService) Get(partnerId int64, channelId int64) *PartnersChannelsGetCall {
	c := &PartnersChannelsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.partnerId = partnerId
	c.channelId = channelId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the fetched channel.
func (c *PartnersChannelsGetCall) AdvertiserId(advertiserId int64) *PartnersChannelsGetCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	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 *PartnersChannelsGetCall) Fields(s ...googleapi.Field) *PartnersChannelsGetCall {
	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 *PartnersChannelsGetCall) IfNoneMatch(entityTag string) *PartnersChannelsGetCall {
	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 *PartnersChannelsGetCall) Context(ctx context.Context) *PartnersChannelsGetCall {
	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 *PartnersChannelsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PartnersChannelsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/partners/{+partnerId}/channels/{+channelId}")
	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{
		"partnerId": strconv.FormatInt(c.partnerId, 10),
		"channelId": strconv.FormatInt(c.channelId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.partners.channels.get" call.
// Exactly one of *Channel or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Channel.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 *PartnersChannelsGetCall) Do(opts ...googleapi.CallOption) (*Channel, 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 := &Channel{
		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 channel for a partner or advertiser.",
	//   "flatPath": "v1/partners/{partnersId}/channels/{channelsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.partners.channels.get",
	//   "parameterOrder": [
	//     "partnerId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the fetched channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the channel to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the fetched channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/partners/{+partnerId}/channels/{+channelId}",
	//   "response": {
	//     "$ref": "Channel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.partners.channels.list":

type PartnersChannelsListCall struct {
	s            *Service
	partnerId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists channels for a partner or advertiser.
func (r *PartnersChannelsService) List(partnerId int64) *PartnersChannelsListCall {
	c := &PartnersChannelsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.partnerId = partnerId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the channels.
func (c *PartnersChannelsListCall) AdvertiserId(advertiserId int64) *PartnersChannelsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// channel fields.
//
// Supported syntax:
//
// * Filter expressions for channel currently can only contain at most
// one
// * restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `displayName`
//
// Examples:
//
// * All channels for which the display name contains
// "google":
// `displayName : "google".
//
// The length of this field should be no more than 500 characters.
func (c *PartnersChannelsListCall) Filter(filter string) *PartnersChannelsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `displayName` (default)
// * `channelId`
//
// The default sorting order is ascending. To specify descending order
// for a
// field, a suffix " desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *PartnersChannelsListCall) OrderBy(orderBy string) *PartnersChannelsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *PartnersChannelsListCall) PageSize(pageSize int64) *PartnersChannelsListCall {
	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
// next_page_token returned from the
// previous call to `ListChannels` method. If not specified, the first
// page
// of results will be returned.
func (c *PartnersChannelsListCall) PageToken(pageToken string) *PartnersChannelsListCall {
	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 *PartnersChannelsListCall) Fields(s ...googleapi.Field) *PartnersChannelsListCall {
	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 *PartnersChannelsListCall) IfNoneMatch(entityTag string) *PartnersChannelsListCall {
	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 *PartnersChannelsListCall) Context(ctx context.Context) *PartnersChannelsListCall {
	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 *PartnersChannelsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PartnersChannelsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/partners/{+partnerId}/channels")
	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{
		"partnerId": strconv.FormatInt(c.partnerId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.partners.channels.list" call.
// Exactly one of *ListChannelsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListChannelsResponse.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 *PartnersChannelsListCall) Do(opts ...googleapi.CallOption) (*ListChannelsResponse, 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 := &ListChannelsResponse{
		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 channels for a partner or advertiser.",
	//   "flatPath": "v1/partners/{partnersId}/channels",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.partners.channels.list",
	//   "parameterOrder": [
	//     "partnerId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the channels.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by channel fields.\n\nSupported syntax:\n\n* Filter expressions for channel currently can only contain at most one\n* restriction.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `CONTAINS (:)`.\n* Supported fields:\n    - `displayName`\n\nExamples:\n\n* All channels for which the display name contains \"google\":\n`displayName : \"google\"`.\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `displayName` (default)\n* `channelId`\n\nThe default sorting order is ascending. To specify descending order for a\nfield, a suffix \" desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token returned from the\nprevious call to `ListChannels` method. If not specified, the first page\nof results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the channels.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/partners/{+partnerId}/channels",
	//   "response": {
	//     "$ref": "ListChannelsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *PartnersChannelsListCall) Pages(ctx context.Context, f func(*ListChannelsResponse) 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 "displayvideo.sdfdownloadtasks.create":

type SdfdownloadtasksCreateCall struct {
	s                            *Service
	createsdfdownloadtaskrequest *CreateSdfDownloadTaskRequest
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Create: Creates an SDF Download Task. Returns an
// Operation.
//
// An SDF Download Task is a long-running, asynchronous operation.
// The
// metadata type of this operation is
// SdfDownloadTaskMetadata. If the request is successful, the
// response type of the operation is
// SdfDownloadTask. The response will not include the download
// files,
// which must be retrieved with
// media.download. The state of
// operation can be retrieved with
// sdfdownloadtask.operations.get.
//
// Any errors can be found in the
// error.message. Note
// that error.details is expected to be
// empty.
func (r *SdfdownloadtasksService) Create(createsdfdownloadtaskrequest *CreateSdfDownloadTaskRequest) *SdfdownloadtasksCreateCall {
	c := &SdfdownloadtasksCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.createsdfdownloadtaskrequest = createsdfdownloadtaskrequest
	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 *SdfdownloadtasksCreateCall) Fields(s ...googleapi.Field) *SdfdownloadtasksCreateCall {
	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 *SdfdownloadtasksCreateCall) Context(ctx context.Context) *SdfdownloadtasksCreateCall {
	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 *SdfdownloadtasksCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SdfdownloadtasksCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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.createsdfdownloadtaskrequest)
	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/sdfdownloadtasks")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.sdfdownloadtasks.create" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SdfdownloadtasksCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Operation{
		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 an SDF Download Task. Returns an\nOperation.\n\nAn SDF Download Task is a long-running, asynchronous operation. The\nmetadata type of this operation is\nSdfDownloadTaskMetadata. If the request is successful, the\nresponse type of the operation is\nSdfDownloadTask. The response will not include the download files,\nwhich must be retrieved with\nmedia.download. The state of\noperation can be retrieved with\nsdfdownloadtask.operations.get.\n\nAny errors can be found in the\nerror.message. Note\nthat error.details is expected to be\nempty.",
	//   "flatPath": "v1/sdfdownloadtasks",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.sdfdownloadtasks.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/sdfdownloadtasks",
	//   "request": {
	//     "$ref": "CreateSdfDownloadTaskRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.sdfdownloadtasks.operations.get":

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

// Get: Gets the latest state of an asynchronous SDF download task
// operation. Clients should poll this method at intervals of 30
// seconds.
func (r *SdfdownloadtasksOperationsService) Get(name string) *SdfdownloadtasksOperationsGetCall {
	c := &SdfdownloadtasksOperationsGetCall{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 *SdfdownloadtasksOperationsGetCall) Fields(s ...googleapi.Field) *SdfdownloadtasksOperationsGetCall {
	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 *SdfdownloadtasksOperationsGetCall) IfNoneMatch(entityTag string) *SdfdownloadtasksOperationsGetCall {
	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 *SdfdownloadtasksOperationsGetCall) Context(ctx context.Context) *SdfdownloadtasksOperationsGetCall {
	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 *SdfdownloadtasksOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SdfdownloadtasksOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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 "displayvideo.sdfdownloadtasks.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SdfdownloadtasksOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &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 := &Operation{
		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 the latest state of an asynchronous SDF download task operation. Clients should poll this method at intervals of 30 seconds.",
	//   "flatPath": "v1/sdfdownloadtasks/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.sdfdownloadtasks.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^sdfdownloadtasks/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video",
	//     "https://www.googleapis.com/auth/doubleclickbidmanager"
	//   ]
	// }

}

// method id "displayvideo.targetingTypes.targetingOptions.get":

type TargetingTypesTargetingOptionsGetCall struct {
	s                 *Service
	targetingType     string
	targetingOptionId string
	urlParams_        gensupport.URLParams
	ifNoneMatch_      string
	ctx_              context.Context
	header_           http.Header
}

// Get: Gets a single targeting option.
func (r *TargetingTypesTargetingOptionsService) Get(targetingType string, targetingOptionId string) *TargetingTypesTargetingOptionsGetCall {
	c := &TargetingTypesTargetingOptionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.targetingType = targetingType
	c.targetingOptionId = targetingOptionId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Required.
// The Advertiser this request is being made in the context of.
func (c *TargetingTypesTargetingOptionsGetCall) AdvertiserId(advertiserId int64) *TargetingTypesTargetingOptionsGetCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	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 *TargetingTypesTargetingOptionsGetCall) Fields(s ...googleapi.Field) *TargetingTypesTargetingOptionsGetCall {
	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 *TargetingTypesTargetingOptionsGetCall) IfNoneMatch(entityTag string) *TargetingTypesTargetingOptionsGetCall {
	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 *TargetingTypesTargetingOptionsGetCall) Context(ctx context.Context) *TargetingTypesTargetingOptionsGetCall {
	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 *TargetingTypesTargetingOptionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTypesTargetingOptionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/targetingTypes/{+targetingType}/targetingOptions/{+targetingOptionId}")
	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{
		"targetingType":     c.targetingType,
		"targetingOptionId": c.targetingOptionId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.targetingTypes.targetingOptions.get" call.
// Exactly one of *TargetingOption or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TargetingOption.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 *TargetingTypesTargetingOptionsGetCall) Do(opts ...googleapi.CallOption) (*TargetingOption, 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 := &TargetingOption{
		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 single targeting option.",
	//   "flatPath": "v1/targetingTypes/{targetingTypesId}/targetingOptions/{targetingOptionsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.targetingTypes.targetingOptions.get",
	//   "parameterOrder": [
	//     "targetingType",
	//     "targetingOptionId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The Advertiser this request is being made in the context of.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetingOptionId": {
	//       "description": "Required. The ID of the of targeting option to retrieve.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. The type of targeting option to retrieve.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/targetingTypes/{+targetingType}/targetingOptions/{+targetingOptionId}",
	//   "response": {
	//     "$ref": "TargetingOption"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.targetingTypes.targetingOptions.list":

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

// List: Lists targeting options of a given type.
func (r *TargetingTypesTargetingOptionsService) List(targetingType string) *TargetingTypesTargetingOptionsListCall {
	c := &TargetingTypesTargetingOptionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.targetingType = targetingType
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Required.
// The Advertiser this request is being made in the context of.
func (c *TargetingTypesTargetingOptionsListCall) AdvertiserId(advertiserId int64) *TargetingTypesTargetingOptionsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// targeting option properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by `OR` logical operators.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be "=" (equal sign).
// * Supported fields:
//     - `targetingOptionId`
//
// The length of this field should be no more than 500 characters.
func (c *TargetingTypesTargetingOptionsListCall) Filter(filter string) *TargetingTypesTargetingOptionsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `targetingOptionId` (default)
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example: `targetingOptionId desc`.
func (c *TargetingTypesTargetingOptionsListCall) OrderBy(orderBy string) *TargetingTypesTargetingOptionsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *TargetingTypesTargetingOptionsListCall) PageSize(pageSize int64) *TargetingTypesTargetingOptionsListCall {
	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
// next_page_token
// returned from the previous call to `ListTargetingOptions` method.
// If not specified, the first page of results will be returned.
func (c *TargetingTypesTargetingOptionsListCall) PageToken(pageToken string) *TargetingTypesTargetingOptionsListCall {
	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 *TargetingTypesTargetingOptionsListCall) Fields(s ...googleapi.Field) *TargetingTypesTargetingOptionsListCall {
	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 *TargetingTypesTargetingOptionsListCall) IfNoneMatch(entityTag string) *TargetingTypesTargetingOptionsListCall {
	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 *TargetingTypesTargetingOptionsListCall) Context(ctx context.Context) *TargetingTypesTargetingOptionsListCall {
	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 *TargetingTypesTargetingOptionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTypesTargetingOptionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200518")
	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/targetingTypes/{+targetingType}/targetingOptions")
	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{
		"targetingType": c.targetingType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.targetingTypes.targetingOptions.list" call.
// Exactly one of *ListTargetingOptionsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListTargetingOptionsResponse.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 *TargetingTypesTargetingOptionsListCall) Do(opts ...googleapi.CallOption) (*ListTargetingOptionsResponse, 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 := &ListTargetingOptionsResponse{
		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 targeting options of a given type.",
	//   "flatPath": "v1/targetingTypes/{targetingTypesId}/targetingOptions",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.targetingTypes.targetingOptions.list",
	//   "parameterOrder": [
	//     "targetingType"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The Advertiser this request is being made in the context of.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by targeting option properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by `OR` logical operators.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be \"=\" (equal sign).\n* Supported fields:\n    - `targetingOptionId`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `targetingOptionId` (default)\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name.\nExample: `targetingOptionId desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "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\nnext_page_token\nreturned from the previous call to `ListTargetingOptions` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "targetingType": {
	//       "description": "Required. The type of targeting option to be listed.",
	//       "enum": [
	//         "TARGETING_TYPE_UNSPECIFIED",
	//         "TARGETING_TYPE_CHANNEL",
	//         "TARGETING_TYPE_APP_CATEGORY",
	//         "TARGETING_TYPE_APP",
	//         "TARGETING_TYPE_URL",
	//         "TARGETING_TYPE_DAY_AND_TIME",
	//         "TARGETING_TYPE_AGE_RANGE",
	//         "TARGETING_TYPE_REGIONAL_LOCATION_LIST",
	//         "TARGETING_TYPE_PROXIMITY_LOCATION_LIST",
	//         "TARGETING_TYPE_GENDER",
	//         "TARGETING_TYPE_VIDEO_PLAYER_SIZE",
	//         "TARGETING_TYPE_USER_REWARDED_CONTENT",
	//         "TARGETING_TYPE_PARENTAL_STATUS",
	//         "TARGETING_TYPE_CONTENT_INSTREAM_POSITION",
	//         "TARGETING_TYPE_CONTENT_OUTSTREAM_POSITION",
	//         "TARGETING_TYPE_DEVICE_TYPE",
	//         "TARGETING_TYPE_AUDIENCE_GROUP",
	//         "TARGETING_TYPE_BROWSER",
	//         "TARGETING_TYPE_HOUSEHOLD_INCOME",
	//         "TARGETING_TYPE_ON_SCREEN_POSITION",
	//         "TARGETING_TYPE_THIRD_PARTY_VERIFIER",
	//         "TARGETING_TYPE_DIGITAL_CONTENT_LABEL_EXCLUSION",
	//         "TARGETING_TYPE_SENSITIVE_CATEGORY_EXCLUSION",
	//         "TARGETING_TYPE_ENVIRONMENT",
	//         "TARGETING_TYPE_CARRIER_AND_ISP",
	//         "TARGETING_TYPE_OPERATING_SYSTEM",
	//         "TARGETING_TYPE_DEVICE_MAKE_MODEL",
	//         "TARGETING_TYPE_KEYWORD",
	//         "TARGETING_TYPE_NEGATIVE_KEYWORD_LIST",
	//         "TARGETING_TYPE_VIEWABILITY",
	//         "TARGETING_TYPE_CATEGORY",
	//         "TARGETING_TYPE_INVENTORY_SOURCE",
	//         "TARGETING_TYPE_LANGUAGE",
	//         "TARGETING_TYPE_AUTHORIZED_SELLER_STATUS",
	//         "TARGETING_TYPE_GEO_REGION",
	//         "TARGETING_TYPE_INVENTORY_SOURCE_GROUP",
	//         "TARGETING_TYPE_EXCHANGE",
	//         "TARGETING_TYPE_SUB_EXCHANGE"
	//       ],
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/targetingTypes/{+targetingType}/targetingOptions",
	//   "response": {
	//     "$ref": "ListTargetingOptionsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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 *TargetingTypesTargetingOptionsListCall) Pages(ctx context.Context, f func(*ListTargetingOptionsResponse) 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)
	}
}
