// 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/"
const mtlsBasePath = "https://displayvideo.mtls.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))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

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

type AdvertisersChannelsService struct {
	s *Service

	Sites *AdvertisersChannelsSitesService
}

func NewAdvertisersChannelsSitesService(s *Service) *AdvertisersChannelsSitesService {
	rs := &AdvertisersChannelsSitesService{s: s}
	return rs
}

type AdvertisersChannelsSitesService 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}
	rs.AssignedLocations = NewAdvertisersLocationListsAssignedLocationsService(s)
	return rs
}

type AdvertisersLocationListsService struct {
	s *Service

	AssignedLocations *AdvertisersLocationListsAssignedLocationsService
}

func NewAdvertisersLocationListsAssignedLocationsService(s *Service) *AdvertisersLocationListsAssignedLocationsService {
	rs := &AdvertisersLocationListsAssignedLocationsService{s: s}
	return rs
}

type AdvertisersLocationListsAssignedLocationsService struct {
	s *Service
}

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

type AdvertisersNegativeKeywordListsService struct {
	s *Service

	NegativeKeywords *AdvertisersNegativeKeywordListsNegativeKeywordsService
}

func NewAdvertisersNegativeKeywordListsNegativeKeywordsService(s *Service) *AdvertisersNegativeKeywordListsNegativeKeywordsService {
	rs := &AdvertisersNegativeKeywordListsNegativeKeywordsService{s: s}
	return rs
}

type AdvertisersNegativeKeywordListsNegativeKeywordsService 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}
	rs.AssignedInventorySources = NewInventorySourceGroupsAssignedInventorySourcesService(s)
	return rs
}

type InventorySourceGroupsService struct {
	s *Service

	AssignedInventorySources *InventorySourceGroupsAssignedInventorySourcesService
}

func NewInventorySourceGroupsAssignedInventorySourcesService(s *Service) *InventorySourceGroupsAssignedInventorySourcesService {
	rs := &InventorySourceGroupsAssignedInventorySourcesService{s: s}
	return rs
}

type InventorySourceGroupsAssignedInventorySourcesService 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}
	rs.Sites = NewPartnersChannelsSitesService(s)
	return rs
}

type PartnersChannelsService struct {
	s *Service

	Sites *PartnersChannelsSitesService
}

func NewPartnersChannelsSitesService(s *Service) *PartnersChannelsSitesService {
	rs := &PartnersChannelsSitesService{s: s}
	return rs
}

type PartnersChannelsSitesService 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)
}

// AssignedInventorySource: An assignment between a targetable inventory
// source and an inventory source
// group.
type AssignedInventorySource struct {
	// AssignedInventorySourceId: Output only. The unique ID of the assigned
	// inventory source. The ID is only
	// unique within a given inventory source group. It may be reused in
	// other
	// contexts.
	AssignedInventorySourceId int64 `json:"assignedInventorySourceId,omitempty,string"`

	// InventorySourceId: Required. The ID of the inventory source entity
	// being targeted.
	InventorySourceId string `json:"inventorySourceId,omitempty"`

	// Name: Output only. The resource name of the assigned inventory
	// source.
	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.
	// "AssignedInventorySourceId") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// AssignedLocation: An assignment between a location list and a
// relevant targeting option.
// Currently, geo region targeting options are the only supported option
// for
// assignment.
type AssignedLocation struct {
	// AssignedLocationId: Output only. The unique ID of the assigned
	// location. The ID is only unique within a
	// location list. It may be reused in other contexts.
	AssignedLocationId int64 `json:"assignedLocationId,omitempty,string"`

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

	// TargetingOptionId: Required. The ID of the targeting option assigned
	// to the location list. Must be of
	// type TARGETING_TYPE_GEO_REGION.
	TargetingOptionId string `json:"targetingOptionId,omitempty"`

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

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

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

func (s *AssignedLocation) MarshalJSON() ([]byte, error) {
	type NoMethod AssignedLocation
	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.
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)
}

// BulkEditAssignedInventorySourcesRequest: Request message for
// AssignedInventorySourceService.BulkEdit.
type BulkEditAssignedInventorySourcesRequest struct {
	// AdvertiserId: The ID of the advertiser that owns the parent inventory
	// source group.
	//
	// The parent partner does not have access to these assigned
	// inventory
	// sources.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// CreatedAssignedInventorySources: The assigned inventory sources to
	// create in bulk, specified as a list of
	// AssignedInventorySources.
	CreatedAssignedInventorySources []*AssignedInventorySource `json:"createdAssignedInventorySources,omitempty"`

	// DeletedAssignedInventorySources: The IDs of the assigned inventory
	// sources to delete in bulk, specified as a
	// list of
	// assigned_inventory_source_ids.
	DeletedAssignedInventorySources googleapi.Int64s `json:"deletedAssignedInventorySources,omitempty"`

	// PartnerId: The ID of the partner that owns the inventory source
	// group.
	//
	// Only this partner has write access to these assigned inventory
	// sources.
	PartnerId int64 `json:"partnerId,omitempty,string"`

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

// BulkEditAssignedInventorySourcesResponse: Response message for
// AssignedInventorySourceService.BulkEdit.
type BulkEditAssignedInventorySourcesResponse struct {
	// AssignedInventorySources: The list of assigned inventory sources that
	// have been successfully created.
	//
	// This list will be absent if empty.
	AssignedInventorySources []*AssignedInventorySource `json:"assignedInventorySources,omitempty"`

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

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

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

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

// BulkEditAssignedLocationsRequest: Request message for
// AssignedLocationService.BulkEditAssignedLocations.
type BulkEditAssignedLocationsRequest struct {
	// CreatedAssignedLocations: The assigned locations to create in bulk,
	// specified as a list of
	// AssignedLocations.
	CreatedAssignedLocations []*AssignedLocation `json:"createdAssignedLocations,omitempty"`

	// DeletedAssignedLocations: The IDs of the assigned locations to delete
	// in bulk, specified as a list of
	// assigned_location_ids.
	DeletedAssignedLocations googleapi.Int64s `json:"deletedAssignedLocations,omitempty"`

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

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

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

// BulkEditAssignedLocationsResponse: Response message for
// AssignedLocationService.BulkEditAssignedLocations.
type BulkEditAssignedLocationsResponse struct {
	// AssignedLocations: The list of assigned locations that have been
	// successfully created.
	//
	// This list will be absent if empty.
	AssignedLocations []*AssignedLocation `json:"assignedLocations,omitempty"`

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

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

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

func (s *BulkEditAssignedLocationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BulkEditAssignedLocationsResponse
	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)
}

// BulkEditNegativeKeywordsRequest: Request message for
// NegativeKeywordService.BulkEditNegativeKeywords.
type BulkEditNegativeKeywordsRequest struct {
	// CreatedNegativeKeywords: The negative keywords to create in batch,
	// specified as a list of
	// NegativeKeywords.
	CreatedNegativeKeywords []*NegativeKeyword `json:"createdNegativeKeywords,omitempty"`

	// DeletedNegativeKeywords: The negative keywords to delete in batch,
	// specified as a list of
	// keyword_values.
	DeletedNegativeKeywords []string `json:"deletedNegativeKeywords,omitempty"`

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

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

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

// BulkEditNegativeKeywordsResponse: Response message for
// NegativeKeywordService.BulkEditNegativeKeywords.
type BulkEditNegativeKeywordsResponse struct {
	// NegativeKeywords: The list of negative keywords that have been
	// successfully created.
	//
	// This list will be absent if empty.
	NegativeKeywords []*NegativeKeyword `json:"negativeKeywords,omitempty"`

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

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

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

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

// BulkEditSitesRequest: Request message for SiteService.BulkEditSites.
type BulkEditSitesRequest struct {
	// AdvertiserId: The ID of the advertiser that owns the parent channel.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// CreatedSites: The sites to create in batch, specified as a list of
	// Sites.
	CreatedSites []*Site `json:"createdSites,omitempty"`

	// DeletedSites: The sites to delete in batch, specified as a list of
	// site
	// url_or_app_ids.
	DeletedSites []string `json:"deletedSites,omitempty"`

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

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

// BulkEditSitesResponse: Response message for
// SiteService.BulkEditSites.
type BulkEditSitesResponse struct {
	// Sites: The list of sites that have been successfully created.
	//
	// This list will be absent if empty.
	Sites []*Site `json:"sites,omitempty"`

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

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

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

func (s *BulkEditSitesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BulkEditSitesResponse
	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
	//   "SDF_VERSION_5_2" - SDF version 5.2;
	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 is
	// 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_UNRULYX" - UnrulyX
	//   "EXCHANGE_OPEN8" - Open8
	//   "EXCHANGE_TRITON" - Triton.
	//   "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_UNRULYX" - UnrulyX
	//   "EXCHANGE_OPEN8" - Open8
	//   "EXCHANGE_TRITON" - Triton.
	//   "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 {
	// ActiveDisplayAudienceSize: Output only. The estimated audience size
	// for the Display network in the past month.
	//
	// If the size is less than 1000, the number will be hidden and 0 will
	// be
	// returned due to privacy reasons. Otherwise, the number will be
	// rounded off
	// to two significant digits.
	//
	// Only returned in GET request.
	ActiveDisplayAudienceSize int64 `json:"activeDisplayAudienceSize,omitempty,string"`

	// AudienceSource: Output only. The source of the audience.
	//
	// Possible values:
	//   "AUDIENCE_SOURCE_UNSPECIFIED" - Default value when audience source
	// is not specified or is unknown.
	//   "DISPLAY_VIDEO_360" - Originated from Display & Video 360.
	//   "CAMPAIGN_MANAGER" - Originated from Campaign Manager.
	//   "AD_MANAGER" - Originated from Google Ad Manager.
	//   "SEARCH_ADS_360" - Originated from Search Ads 360.
	//   "YOUTUBE" - Originated from Youtube.
	//   "ADS_DATA_HUB" - Originated from Ads Data Hub.
	AudienceSource string `json:"audienceSource,omitempty"`

	// AudienceType: Output only. The type of the audience.
	//
	// Possible values:
	//   "AUDIENCE_TYPE_UNSPECIFIED" - Default value when type is not
	// specified or is unknown.
	//   "CUSTOMER_MATCH_CONTACT_INFO" - Audience was generated through
	// matching customers to known contact
	// information.
	//   "CUSTOMER_MATCH_DEVICE_ID" - Audience was generated through
	// matching customers to known Mobile device
	// IDs.
	//   "CUSTOMER_MATCH_USER_ID" - Audience was generated through matching
	// customers to known User IDs.
	//   "ACTIVITY_BASED" - Audience was created based on campaign activity.
	//   "FREQUENCY_CAP" - Audience was created based on excluding the
	// number of impressions they
	// were served.
	//   "TAG_BASED" - Audience was created based on custom variables
	// attached to pixel.
	//   "YOUTUBE_USERS" - Audience was created based on past interactions
	// with videos, TrueView
	// ads, or YouTube channel.
	//   "LICENSED" - Subtype of third party audience type.
	AudienceType string `json:"audienceType,omitempty"`

	// Description: The user-provided description of the audience.
	//
	// Only applicable to first party audiences.
	Description string `json:"description,omitempty"`

	// DisplayAudienceSize: Output only. The estimated audience size for the
	// Display network.
	//
	// If the size is less than 1000, the number will be hidden and 0 will
	// be
	// returned due to privacy reasons. Otherwise, the number will be
	// rounded off
	// to two significant digits.
	//
	// Only returned in GET request.
	DisplayAudienceSize int64 `json:"displayAudienceSize,omitempty,string"`

	// DisplayDesktopAudienceSize: Output only. The estimated desktop
	// audience size in Display network.
	//
	// If the size is less than 1000, the number will be hidden and 0 will
	// be
	// returned due to privacy reasons. Otherwise, the number will be
	// rounded off
	// to two significant digits.
	//
	// Only applicable to first party audiences.
	//
	// Only returned in GET request.
	DisplayDesktopAudienceSize int64 `json:"displayDesktopAudienceSize,omitempty,string"`

	// DisplayMobileAppAudienceSize: Output only. The estimated mobile app
	// audience size in Display network.
	//
	// If the size is less than 1000, the number will be hidden and 0 will
	// be
	// returned due to privacy reasons. Otherwise, the number will be
	// rounded off
	// to two significant digits.
	//
	// Only applicable to first party audiences.
	//
	// Only returned in GET request.
	DisplayMobileAppAudienceSize int64 `json:"displayMobileAppAudienceSize,omitempty,string"`

	// DisplayMobileWebAudienceSize: Output only. The estimated mobile web
	// audience size in Display network.
	//
	// If the size is less than 1000, the number will be hidden and 0 will
	// be
	// returned due to privacy reasons. Otherwise, the number will be
	// rounded off
	// to two significant digits.
	//
	// Only applicable to first party audiences.
	//
	// Only returned in GET request.
	DisplayMobileWebAudienceSize int64 `json:"displayMobileWebAudienceSize,omitempty,string"`

	// DisplayName: 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"`

	// GmailAudienceSize: Output only. The estimated audience size for Gmail
	// network.
	//
	// If the size is less than 1000, the number will be hidden and 0 will
	// be
	// returned due to privacy reasons. Otherwise, the number will be
	// rounded off
	// to two significant digits.
	//
	// Only applicable to first party audiences.
	//
	// Only returned in GET request.
	GmailAudienceSize int64 `json:"gmailAudienceSize,omitempty,string"`

	// MembershipDurationDays: The duration in days that an entry remains in
	// the audience after the
	// qualifying event.
	//
	// Only applicable to first party audiences.
	MembershipDurationDays int64 `json:"membershipDurationDays,omitempty,string"`

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

	// YoutubeAudienceSize: Output only. The estimated audience size for
	// YouTube network.
	//
	// If the size is less than 1000, the number will be hidden and 0 will
	// be
	// returned due to privacy reasons. Otherwise, the number will be
	// rounded off
	// to two significant digits.
	//
	// Only applicable to first party audiences.
	//
	// Only returned in GET request.
	YoutubeAudienceSize int64 `json:"youtubeAudienceSize,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.
	// "ActiveDisplayAudienceSize") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g.
	// "ActiveDisplayAudienceSize") to include in API requests with the JSON
	// null value. By default, fields with empty values are omitted from API
	// requests. However, any field with an empty value appearing in
	// NullFields will be sent to the server as null. It is an error if a
	// field 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_UNRULYX" - UnrulyX
	//   "EXCHANGE_OPEN8" - Open8
	//   "EXCHANGE_TRITON" - Triton.
	//   "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)
}

// ListAssignedInventorySourcesResponse: Response message
// for
// AssignedInventorySourceService.ListAssignedInventorySources.
type ListAssignedInventorySourcesResponse struct {
	// AssignedInventorySources: The list of assigned inventory
	// sources.
	//
	// This list will be absent if empty.
	AssignedInventorySources []*AssignedInventorySource `json:"assignedInventorySources,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	//
	// Pass this value in the
	// page_token field
	// in the subsequent call to `ListAssignedInventorySources` 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.
	// "AssignedInventorySources") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// ListAssignedLocationsResponse: Response message
// for
// AssignedLocationService.ListAssignedLocations.
type ListAssignedLocationsResponse struct {
	// AssignedLocations: The list of assigned locations.
	//
	// This list will be absent if empty.
	AssignedLocations []*AssignedLocation `json:"assignedLocations,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	//
	// Pass this value in the
	// page_token field
	// in the subsequent call to `ListAssignedLocations` 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. "AssignedLocations")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

func (s *ListAssignedLocationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListAssignedLocationsResponse
	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)
}

// ListNegativeKeywordsResponse: Response message for
// NegativeKeywordService.ListNegativeKeywords.
type ListNegativeKeywordsResponse struct {
	// NegativeKeywords: The list of negative keywords.
	//
	// This list will be absent if empty.
	NegativeKeywords []*NegativeKeyword `json:"negativeKeywords,omitempty"`

	// NextPageToken: A token to retrieve the next page of results.
	//
	// Pass this value in the page_token
	// field in the subsequent call to `ListNegativeKeywords` 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. "NegativeKeywords") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

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

	// Sites: The list of sites.
	//
	// This list will be absent if empty.
	Sites []*Site `json:"sites,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 *ListSitesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListSitesResponse
	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)
}

// NegativeKeyword: A negatively targeted keyword that belongs to a
// negative keyword list.
type NegativeKeyword struct {
	// KeywordValue: Required. Immutable. The negatively targeted keyword,
	// for example `car insurance`.
	//
	// Must be UTF-8 encoded with a maximum size of 255 bytes. Maximum
	// number
	// of characters is 80. Maximum number of words is 10.
	//
	// Valid characters are restricted to ASCII characters only. The
	// only
	// URL-escaping permitted is for representing whitespace between
	// words.
	// Leading or trailing whitespace is ignored.
	KeywordValue string `json:"keywordValue,omitempty"`

	// Name: Output only. The resource name of the negative keyword.
	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. "KeywordValue") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

func (s *NegativeKeyword) MarshalJSON() ([]byte, error) {
	type NoMethod NegativeKeyword
	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 or in micro of
	// the
	// ROAS (Return On Advertising Spend) value which is also based
	// on
	// 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.
	// * when
	// performance_goal_type
	// is `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CUSTOM_ALGO`, upper bound
	// is
	// 1000.00 and lower bound is 0.01.
	//
	// 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 or
	// ROAS
	// value.
	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`
	// * `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CUSTOM_ALGO`.
	//
	// 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
	//   "SDF_VERSION_5_2" - SDF version 5.2;
	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
	//   "SDF_VERSION_5_2" - SDF version 5.2;
	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)
}

// Site: A single site. Sites are apps or websites belonging to a
// channel.
type Site struct {
	// Name: Output only. The resource name of the site.
	Name string `json:"name,omitempty"`

	// UrlOrAppId: Required. The URL or app ID of the site.
	// Must be UTF-8 encoded with a maximum length of 240 bytes.
	UrlOrAppId string `json:"urlOrAppId,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 *Site) MarshalJSON() ([]byte, error) {
	type NoMethod Site
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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.create":

type AdvertisersChannelsCreateCall struct {
	s            *Service
	advertiserId int64
	channel      *Channel
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a new channel. Returns the newly created channel if
// successful.
func (r *AdvertisersChannelsService) Create(advertiserId int64, channel *Channel) *AdvertisersChannelsCreateCall {
	c := &AdvertisersChannelsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.channel = channel
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the created channel.
func (c *AdvertisersChannelsCreateCall) PartnerId(partnerId int64) *AdvertisersChannelsCreateCall {
	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 *AdvertisersChannelsCreateCall) Fields(s ...googleapi.Field) *AdvertisersChannelsCreateCall {
	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 *AdvertisersChannelsCreateCall) Context(ctx context.Context) *AdvertisersChannelsCreateCall {
	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 *AdvertisersChannelsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersChannelsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.channel)
	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}/channels")
	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.channels.create" 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 *AdvertisersChannelsCreateCall) 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": "Creates a new channel. Returns the newly created channel if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/channels",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.channels.create",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the created channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the created channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/channels",
	//   "request": {
	//     "$ref": "Channel"
	//   },
	//   "response": {
	//     "$ref": "Channel"
	//   },
	//   "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/20200715")
	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/20200715")
	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.channels.patch":

type AdvertisersChannelsPatchCall struct {
	s            *Service
	advertiserId int64
	channelId    int64
	channel      *Channel
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Patch: Updates a channel. Returns the updated channel if successful.
func (r *AdvertisersChannelsService) Patch(advertiserId int64, channelId int64, channel *Channel) *AdvertisersChannelsPatchCall {
	c := &AdvertisersChannelsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.channelId = channelId
	c.channel = channel
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the created channel.
func (c *AdvertisersChannelsPatchCall) PartnerId(partnerId int64) *AdvertisersChannelsPatchCall {
	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 *AdvertisersChannelsPatchCall) UpdateMask(updateMask string) *AdvertisersChannelsPatchCall {
	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 *AdvertisersChannelsPatchCall) Fields(s ...googleapi.Field) *AdvertisersChannelsPatchCall {
	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 *AdvertisersChannelsPatchCall) Context(ctx context.Context) *AdvertisersChannelsPatchCall {
	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 *AdvertisersChannelsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersChannelsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.channel)
	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}/channels/{channelId}")
	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),
		"channelId":    strconv.FormatInt(c.channelId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.channels.patch" 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 *AdvertisersChannelsPatchCall) 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": "Updates a channel. Returns the updated channel if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/channels/{channelId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.advertisers.channels.patch",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the created channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Output only. The unique ID of the channel. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the created channel.",
	//       "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/advertisers/{+advertiserId}/channels/{channelId}",
	//   "request": {
	//     "$ref": "Channel"
	//   },
	//   "response": {
	//     "$ref": "Channel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.channels.sites.bulkEdit":

type AdvertisersChannelsSitesBulkEditCall struct {
	s                    *Service
	advertiserId         int64
	channelId            int64
	bulkeditsitesrequest *BulkEditSitesRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// BulkEdit: Bulk edits sites under a single channel.
//
// The operation will delete the sites provided
// in
// BulkEditSitesRequest.deleted_sites and then create the sites
// provided in BulkEditSitesRequest.created_sites.
func (r *AdvertisersChannelsSitesService) BulkEdit(advertiserId int64, channelId int64, bulkeditsitesrequest *BulkEditSitesRequest) *AdvertisersChannelsSitesBulkEditCall {
	c := &AdvertisersChannelsSitesBulkEditCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.channelId = channelId
	c.bulkeditsitesrequest = bulkeditsitesrequest
	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 *AdvertisersChannelsSitesBulkEditCall) Fields(s ...googleapi.Field) *AdvertisersChannelsSitesBulkEditCall {
	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 *AdvertisersChannelsSitesBulkEditCall) Context(ctx context.Context) *AdvertisersChannelsSitesBulkEditCall {
	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 *AdvertisersChannelsSitesBulkEditCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersChannelsSitesBulkEditCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.bulkeditsitesrequest)
	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}/channels/{+channelId}/sites:bulkEdit")
	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),
		"channelId":    strconv.FormatInt(c.channelId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.channels.sites.bulkEdit" call.
// Exactly one of *BulkEditSitesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BulkEditSitesResponse.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 *AdvertisersChannelsSitesBulkEditCall) Do(opts ...googleapi.CallOption) (*BulkEditSitesResponse, 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 := &BulkEditSitesResponse{
		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 sites under a single channel.\n\nThe operation will delete the sites provided in\nBulkEditSitesRequest.deleted_sites and then create the sites\nprovided in BulkEditSitesRequest.created_sites.",
	//   "flatPath": "v1/advertisers/{advertiserId}/channels/{channelsId}/sites:bulkEdit",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.channels.sites.bulkEdit",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the parent channel to which the sites belong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/channels/{+channelId}/sites:bulkEdit",
	//   "request": {
	//     "$ref": "BulkEditSitesRequest"
	//   },
	//   "response": {
	//     "$ref": "BulkEditSitesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.channels.sites.create":

type AdvertisersChannelsSitesCreateCall struct {
	s            *Service
	advertiserId int64
	channelId    int64
	site         *Site
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a site in a channel.
func (r *AdvertisersChannelsSitesService) Create(advertiserId int64, channelId int64, site *Site) *AdvertisersChannelsSitesCreateCall {
	c := &AdvertisersChannelsSitesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.channelId = channelId
	c.site = site
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the parent channel.
func (c *AdvertisersChannelsSitesCreateCall) PartnerId(partnerId int64) *AdvertisersChannelsSitesCreateCall {
	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 *AdvertisersChannelsSitesCreateCall) Fields(s ...googleapi.Field) *AdvertisersChannelsSitesCreateCall {
	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 *AdvertisersChannelsSitesCreateCall) Context(ctx context.Context) *AdvertisersChannelsSitesCreateCall {
	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 *AdvertisersChannelsSitesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersChannelsSitesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.site)
	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}/channels/{+channelId}/sites")
	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),
		"channelId":    strconv.FormatInt(c.channelId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.channels.sites.create" call.
// Exactly one of *Site or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Site.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 *AdvertisersChannelsSitesCreateCall) Do(opts ...googleapi.CallOption) (*Site, 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 := &Site{
		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 site in a channel.",
	//   "flatPath": "v1/advertisers/{advertiserId}/channels/{channelsId}/sites",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.channels.sites.create",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the parent channel in which the site will be created.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the parent channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/channels/{+channelId}/sites",
	//   "request": {
	//     "$ref": "Site"
	//   },
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.channels.sites.delete":

type AdvertisersChannelsSitesDeleteCall struct {
	s            *Service
	advertiserId int64
	channelId    int64
	urlOrAppId   string
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Delete: Deletes a site from a channel.
func (r *AdvertisersChannelsSitesService) Delete(advertiserId int64, channelId int64, urlOrAppId string) *AdvertisersChannelsSitesDeleteCall {
	c := &AdvertisersChannelsSitesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.channelId = channelId
	c.urlOrAppId = urlOrAppId
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the parent channel.
func (c *AdvertisersChannelsSitesDeleteCall) PartnerId(partnerId int64) *AdvertisersChannelsSitesDeleteCall {
	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 *AdvertisersChannelsSitesDeleteCall) Fields(s ...googleapi.Field) *AdvertisersChannelsSitesDeleteCall {
	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 *AdvertisersChannelsSitesDeleteCall) Context(ctx context.Context) *AdvertisersChannelsSitesDeleteCall {
	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 *AdvertisersChannelsSitesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersChannelsSitesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/channels/{+channelId}/sites/{+urlOrAppId}")
	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),
		"channelId":    strconv.FormatInt(c.channelId, 10),
		"urlOrAppId":   c.urlOrAppId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.channels.sites.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 *AdvertisersChannelsSitesDeleteCall) 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 site from a channel.",
	//   "flatPath": "v1/advertisers/{advertiserId}/channels/{channelsId}/sites/{sitesId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.channels.sites.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "channelId",
	//     "urlOrAppId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the parent channel to which the site belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the parent channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "urlOrAppId": {
	//       "description": "Required. The URL or app ID of the site to delete.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/channels/{+channelId}/sites/{+urlOrAppId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.channels.sites.list":

type AdvertisersChannelsSitesListCall struct {
	s            *Service
	advertiserId int64
	channelId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists sites in a channel.
func (r *AdvertisersChannelsSitesService) List(advertiserId int64, channelId int64) *AdvertisersChannelsSitesListCall {
	c := &AdvertisersChannelsSitesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.channelId = channelId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by site
// fields.
//
// Supported syntax:
//
// * Filter expressions for site currently can only contain at most
// one
// * restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `urlOrAppId`
//
// Examples:
//
// * All sites for which the URL or app ID contains
// "google":
// `urlOrAppId : "google"
func (c *AdvertisersChannelsSitesListCall) Filter(filter string) *AdvertisersChannelsSitesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `urlOrAppId` (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:
// `urlOrAppId desc`.
func (c *AdvertisersChannelsSitesListCall) OrderBy(orderBy string) *AdvertisersChannelsSitesListCall {
	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 *AdvertisersChannelsSitesListCall) PageSize(pageSize int64) *AdvertisersChannelsSitesListCall {
	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 `ListSites` method. If not specified, the first
// page
// of results will be returned.
func (c *AdvertisersChannelsSitesListCall) PageToken(pageToken string) *AdvertisersChannelsSitesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the parent channel.
func (c *AdvertisersChannelsSitesListCall) PartnerId(partnerId int64) *AdvertisersChannelsSitesListCall {
	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 *AdvertisersChannelsSitesListCall) Fields(s ...googleapi.Field) *AdvertisersChannelsSitesListCall {
	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 *AdvertisersChannelsSitesListCall) IfNoneMatch(entityTag string) *AdvertisersChannelsSitesListCall {
	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 *AdvertisersChannelsSitesListCall) Context(ctx context.Context) *AdvertisersChannelsSitesListCall {
	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 *AdvertisersChannelsSitesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersChannelsSitesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/sites")
	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.sites.list" call.
// Exactly one of *ListSitesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListSitesResponse.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 *AdvertisersChannelsSitesListCall) Do(opts ...googleapi.CallOption) (*ListSitesResponse, 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 := &ListSitesResponse{
		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 sites in a channel.",
	//   "flatPath": "v1/advertisers/{advertisersId}/channels/{channelsId}/sites",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.channels.sites.list",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the parent channel to which the requested sites belong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by site fields.\n\nSupported syntax:\n\n* Filter expressions for site 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    - `urlOrAppId`\n\nExamples:\n\n* All sites for which the URL or app ID contains \"google\":\n`urlOrAppId : \"google\"`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `urlOrAppId` (default)\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`urlOrAppId 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.\n\nTypically, this is the value of\nnext_page_token returned from the\nprevious call to `ListSites` 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 parent channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/channels/{+channelId}/sites",
	//   "response": {
	//     "$ref": "ListSitesResponse"
	//   },
	//   "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 *AdvertisersChannelsSitesListCall) Pages(ctx context.Context, f func(*ListSitesResponse) 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/20200715")
	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/20200715")
	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/20200715")
	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`
//     - `creativeId`
// * 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.
// * There may be multiple `creativeId` restrictions in order to
// search
// against multiple possible creative 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)`
// * Find creatives by multiple creative IDs:
// `creativeId=1 OR creativeId=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/20200715")
	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    - `creativeId`\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* There may be multiple `creativeId` restrictions in order to search\nagainst multiple possible creative 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:\n`creativeType=\"CREATIVE_TYPE_VIDEO\" AND (lineItemIds:1 OR lineItemIds:2)`\n* Find creatives by multiple creative IDs:\n`creativeId=1 OR creativeId=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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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"
// * “flight.dateRange.endDate”
//
// 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/20200715")
	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* “flight.dateRange.endDate”\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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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.create":

type AdvertisersLocationListsCreateCall struct {
	s            *Service
	advertiserId int64
	locationlist *LocationList
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a new location list. Returns the newly created
// location list if
// successful.
func (r *AdvertisersLocationListsService) Create(advertiserId int64, locationlist *LocationList) *AdvertisersLocationListsCreateCall {
	c := &AdvertisersLocationListsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.locationlist = locationlist
	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 *AdvertisersLocationListsCreateCall) Fields(s ...googleapi.Field) *AdvertisersLocationListsCreateCall {
	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 *AdvertisersLocationListsCreateCall) Context(ctx context.Context) *AdvertisersLocationListsCreateCall {
	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 *AdvertisersLocationListsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLocationListsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.locationlist)
	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}/locationLists")
	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.locationLists.create" 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 *AdvertisersLocationListsCreateCall) 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": "Creates a new location list. Returns the newly created location list if\nsuccessful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/locationLists",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.locationLists.create",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the location list belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/locationLists",
	//   "request": {
	//     "$ref": "LocationList"
	//   },
	//   "response": {
	//     "$ref": "LocationList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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/20200715")
	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/20200715")
	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.locationLists.patch":

type AdvertisersLocationListsPatchCall struct {
	s              *Service
	advertiserId   int64
	locationListId int64
	locationlist   *LocationList
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Patch: Updates a location list. Returns the updated location list if
// successful.
func (r *AdvertisersLocationListsService) Patch(advertiserId int64, locationListId int64, locationlist *LocationList) *AdvertisersLocationListsPatchCall {
	c := &AdvertisersLocationListsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.locationListId = locationListId
	c.locationlist = locationlist
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *AdvertisersLocationListsPatchCall) UpdateMask(updateMask string) *AdvertisersLocationListsPatchCall {
	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 *AdvertisersLocationListsPatchCall) Fields(s ...googleapi.Field) *AdvertisersLocationListsPatchCall {
	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 *AdvertisersLocationListsPatchCall) Context(ctx context.Context) *AdvertisersLocationListsPatchCall {
	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 *AdvertisersLocationListsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLocationListsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.locationlist)
	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}/locationLists/{locationListId}")
	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),
		"locationListId": strconv.FormatInt(c.locationListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.locationLists.patch" 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 *AdvertisersLocationListsPatchCall) 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": "Updates a location list. Returns the updated location list if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/locationLists/{locationListId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.advertisers.locationLists.patch",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "locationListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the location lists belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "locationListId": {
	//       "description": "Output only. The unique ID of the location list. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "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}/locationLists/{locationListId}",
	//   "request": {
	//     "$ref": "LocationList"
	//   },
	//   "response": {
	//     "$ref": "LocationList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.locationLists.assignedLocations.bulkEdit":

type AdvertisersLocationListsAssignedLocationsBulkEditCall struct {
	s                                *Service
	advertiserId                     int64
	locationListId                   int64
	bulkeditassignedlocationsrequest *BulkEditAssignedLocationsRequest
	urlParams_                       gensupport.URLParams
	ctx_                             context.Context
	header_                          http.Header
}

// BulkEdit: Bulk edits multiple assignments between locations and a
// single location
// list.
//
// The operation will delete the assigned locations provided
// in
// BulkEditAssignedLocationsRequest.deleted_assigned_locations and
// then
// create the assigned locations provided
// in
// BulkEditAssignedLocationsRequest.created_assigned_locations.
func (r *AdvertisersLocationListsAssignedLocationsService) BulkEdit(advertiserId int64, locationListId int64, bulkeditassignedlocationsrequest *BulkEditAssignedLocationsRequest) *AdvertisersLocationListsAssignedLocationsBulkEditCall {
	c := &AdvertisersLocationListsAssignedLocationsBulkEditCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.locationListId = locationListId
	c.bulkeditassignedlocationsrequest = bulkeditassignedlocationsrequest
	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 *AdvertisersLocationListsAssignedLocationsBulkEditCall) Fields(s ...googleapi.Field) *AdvertisersLocationListsAssignedLocationsBulkEditCall {
	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 *AdvertisersLocationListsAssignedLocationsBulkEditCall) Context(ctx context.Context) *AdvertisersLocationListsAssignedLocationsBulkEditCall {
	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 *AdvertisersLocationListsAssignedLocationsBulkEditCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLocationListsAssignedLocationsBulkEditCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.bulkeditassignedlocationsrequest)
	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}/locationLists/{+locationListId}/assignedLocations:bulkEdit")
	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),
		"locationListId": strconv.FormatInt(c.locationListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.locationLists.assignedLocations.bulkEdit" call.
// Exactly one of *BulkEditAssignedLocationsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BulkEditAssignedLocationsResponse.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 *AdvertisersLocationListsAssignedLocationsBulkEditCall) Do(opts ...googleapi.CallOption) (*BulkEditAssignedLocationsResponse, 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 := &BulkEditAssignedLocationsResponse{
		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 multiple assignments between locations and a single location\nlist.\n\nThe operation will delete the assigned locations provided in\nBulkEditAssignedLocationsRequest.deleted_assigned_locations and then\ncreate the assigned locations provided in\nBulkEditAssignedLocationsRequest.created_assigned_locations.",
	//   "flatPath": "v1/advertisers/{advertiserId}/locationLists/{locationListsId}/assignedLocations:bulkEdit",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.locationLists.assignedLocations.bulkEdit",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "locationListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the location list belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "locationListId": {
	//       "description": "Required. The ID of the location list to which these assignments are assigned.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/locationLists/{+locationListId}/assignedLocations:bulkEdit",
	//   "request": {
	//     "$ref": "BulkEditAssignedLocationsRequest"
	//   },
	//   "response": {
	//     "$ref": "BulkEditAssignedLocationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.locationLists.assignedLocations.create":

type AdvertisersLocationListsAssignedLocationsCreateCall struct {
	s                *Service
	advertiserId     int64
	locationListId   int64
	assignedlocation *AssignedLocation
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Create: Creates an assignment between a location and a location list.
func (r *AdvertisersLocationListsAssignedLocationsService) Create(advertiserId int64, locationListId int64, assignedlocation *AssignedLocation) *AdvertisersLocationListsAssignedLocationsCreateCall {
	c := &AdvertisersLocationListsAssignedLocationsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.locationListId = locationListId
	c.assignedlocation = assignedlocation
	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 *AdvertisersLocationListsAssignedLocationsCreateCall) Fields(s ...googleapi.Field) *AdvertisersLocationListsAssignedLocationsCreateCall {
	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 *AdvertisersLocationListsAssignedLocationsCreateCall) Context(ctx context.Context) *AdvertisersLocationListsAssignedLocationsCreateCall {
	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 *AdvertisersLocationListsAssignedLocationsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLocationListsAssignedLocationsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.assignedlocation)
	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}/locationLists/{locationListId}/assignedLocations")
	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),
		"locationListId": strconv.FormatInt(c.locationListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.locationLists.assignedLocations.create" call.
// Exactly one of *AssignedLocation or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AssignedLocation.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 *AdvertisersLocationListsAssignedLocationsCreateCall) Do(opts ...googleapi.CallOption) (*AssignedLocation, 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 := &AssignedLocation{
		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 assignment between a location and a location list.",
	//   "flatPath": "v1/advertisers/{advertiserId}/locationLists/{locationListId}/assignedLocations",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.locationLists.assignedLocations.create",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "locationListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the location list belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "locationListId": {
	//       "description": "Required. The ID of the location list for which the assignment will be created.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/locationLists/{locationListId}/assignedLocations",
	//   "request": {
	//     "$ref": "AssignedLocation"
	//   },
	//   "response": {
	//     "$ref": "AssignedLocation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.locationLists.assignedLocations.delete":

type AdvertisersLocationListsAssignedLocationsDeleteCall struct {
	s                  *Service
	advertiserId       int64
	locationListId     int64
	assignedLocationId int64
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Delete: Deletes the assignment between a location and a location
// list.
func (r *AdvertisersLocationListsAssignedLocationsService) Delete(advertiserId int64, locationListId int64, assignedLocationId int64) *AdvertisersLocationListsAssignedLocationsDeleteCall {
	c := &AdvertisersLocationListsAssignedLocationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.locationListId = locationListId
	c.assignedLocationId = assignedLocationId
	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 *AdvertisersLocationListsAssignedLocationsDeleteCall) Fields(s ...googleapi.Field) *AdvertisersLocationListsAssignedLocationsDeleteCall {
	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 *AdvertisersLocationListsAssignedLocationsDeleteCall) Context(ctx context.Context) *AdvertisersLocationListsAssignedLocationsDeleteCall {
	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 *AdvertisersLocationListsAssignedLocationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLocationListsAssignedLocationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/locationLists/{locationListId}/assignedLocations/{+assignedLocationId}")
	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),
		"locationListId":     strconv.FormatInt(c.locationListId, 10),
		"assignedLocationId": strconv.FormatInt(c.assignedLocationId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.locationLists.assignedLocations.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 *AdvertisersLocationListsAssignedLocationsDeleteCall) 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 the assignment between a location and a location list.",
	//   "flatPath": "v1/advertisers/{advertiserId}/locationLists/{locationListId}/assignedLocations/{assignedLocationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.locationLists.assignedLocations.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "locationListId",
	//     "assignedLocationId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the location list belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "assignedLocationId": {
	//       "description": "Required. The ID of the assigned location to delete.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "locationListId": {
	//       "description": "Required. The ID of the location list to which this assignment is assigned.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/locationLists/{locationListId}/assignedLocations/{+assignedLocationId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.locationLists.assignedLocations.list":

type AdvertisersLocationListsAssignedLocationsListCall struct {
	s              *Service
	advertiserId   int64
	locationListId int64
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// List: Lists locations assigned to a location list.
func (r *AdvertisersLocationListsAssignedLocationsService) List(advertiserId int64, locationListId int64) *AdvertisersLocationListsAssignedLocationsListCall {
	c := &AdvertisersLocationListsAssignedLocationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.locationListId = locationListId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// location list assignment fields.
//
// 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:
//     - `assignedLocationId`
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersLocationListsAssignedLocationsListCall) Filter(filter string) *AdvertisersLocationListsAssignedLocationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `assignedLocationId` (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:
// `assignedLocationId desc`.
func (c *AdvertisersLocationListsAssignedLocationsListCall) OrderBy(orderBy string) *AdvertisersLocationListsAssignedLocationsListCall {
	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 *AdvertisersLocationListsAssignedLocationsListCall) PageSize(pageSize int64) *AdvertisersLocationListsAssignedLocationsListCall {
	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 `ListAssignedLocations`
// method. If not specified, the first page of results will be returned.
func (c *AdvertisersLocationListsAssignedLocationsListCall) PageToken(pageToken string) *AdvertisersLocationListsAssignedLocationsListCall {
	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 *AdvertisersLocationListsAssignedLocationsListCall) Fields(s ...googleapi.Field) *AdvertisersLocationListsAssignedLocationsListCall {
	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 *AdvertisersLocationListsAssignedLocationsListCall) IfNoneMatch(entityTag string) *AdvertisersLocationListsAssignedLocationsListCall {
	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 *AdvertisersLocationListsAssignedLocationsListCall) Context(ctx context.Context) *AdvertisersLocationListsAssignedLocationsListCall {
	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 *AdvertisersLocationListsAssignedLocationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersLocationListsAssignedLocationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/assignedLocations")
	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.assignedLocations.list" call.
// Exactly one of *ListAssignedLocationsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListAssignedLocationsResponse.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 *AdvertisersLocationListsAssignedLocationsListCall) Do(opts ...googleapi.CallOption) (*ListAssignedLocationsResponse, 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 := &ListAssignedLocationsResponse{
		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 locations assigned to a location list.",
	//   "flatPath": "v1/advertisers/{advertiserId}/locationLists/{locationListId}/assignedLocations",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.locationLists.assignedLocations.list",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "locationListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the location list belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by location list assignment fields.\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    - `assignedLocationId`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "locationListId": {
	//       "description": "Required. The ID of the location list to which these assignments are assigned.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `assignedLocationId` (default)\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`assignedLocationId 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.\n\nTypically, this is the value of\nnext_page_token\nreturned from the previous call to `ListAssignedLocations`\nmethod. If not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/locationLists/{locationListId}/assignedLocations",
	//   "response": {
	//     "$ref": "ListAssignedLocationsResponse"
	//   },
	//   "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 *AdvertisersLocationListsAssignedLocationsListCall) Pages(ctx context.Context, f func(*ListAssignedLocationsResponse) 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.create":

type AdvertisersNegativeKeywordListsCreateCall struct {
	s                   *Service
	advertiserId        int64
	negativekeywordlist *NegativeKeywordList
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// Create: Creates a new negative keyword list. Returns the newly
// created negative
// keyword list if successful.
func (r *AdvertisersNegativeKeywordListsService) Create(advertiserId int64, negativekeywordlist *NegativeKeywordList) *AdvertisersNegativeKeywordListsCreateCall {
	c := &AdvertisersNegativeKeywordListsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.negativekeywordlist = negativekeywordlist
	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 *AdvertisersNegativeKeywordListsCreateCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsCreateCall {
	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 *AdvertisersNegativeKeywordListsCreateCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsCreateCall {
	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 *AdvertisersNegativeKeywordListsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.negativekeywordlist)
	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}/negativeKeywordLists")
	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.negativeKeywordLists.create" 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 *AdvertisersNegativeKeywordListsCreateCall) 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": "Creates a new negative keyword list. Returns the newly created negative\nkeyword list if successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/negativeKeywordLists",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.create",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the negative keyword list will\nbelong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/negativeKeywordLists",
	//   "request": {
	//     "$ref": "NegativeKeywordList"
	//   },
	//   "response": {
	//     "$ref": "NegativeKeywordList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.negativeKeywordLists.delete":

type AdvertisersNegativeKeywordListsDeleteCall struct {
	s                     *Service
	advertiserId          int64
	negativeKeywordListId int64
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Delete: Deletes a negative keyword list given an advertiser ID and a
// negative
// keyword list ID.
func (r *AdvertisersNegativeKeywordListsService) Delete(advertiserId int64, negativeKeywordListId int64) *AdvertisersNegativeKeywordListsDeleteCall {
	c := &AdvertisersNegativeKeywordListsDeleteCall{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 *AdvertisersNegativeKeywordListsDeleteCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsDeleteCall {
	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 *AdvertisersNegativeKeywordListsDeleteCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsDeleteCall {
	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 *AdvertisersNegativeKeywordListsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/negativeKeywordLists/{+negativeKeywordListId}")
	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),
		"negativeKeywordListId": strconv.FormatInt(c.negativeKeywordListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.negativeKeywordLists.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 *AdvertisersNegativeKeywordListsDeleteCall) 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 negative keyword list given an advertiser ID and a negative\nkeyword list ID.",
	//   "flatPath": "v1/advertisers/{advertisersId}/negativeKeywordLists/{negativeKeywordListsId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "negativeKeywordListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the negative keyword list belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "negativeKeywordListId": {
	//       "description": "Required. The ID of the negative keyword list to delete.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/negativeKeywordLists/{+negativeKeywordListId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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/20200715")
	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/20200715")
	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.negativeKeywordLists.patch":

type AdvertisersNegativeKeywordListsPatchCall struct {
	s                     *Service
	advertiserId          int64
	negativeKeywordListId int64
	negativekeywordlist   *NegativeKeywordList
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Patch: Updates a negative keyword list. Returns the updated negative
// keyword list
// if successful.
func (r *AdvertisersNegativeKeywordListsService) Patch(advertiserId int64, negativeKeywordListId int64, negativekeywordlist *NegativeKeywordList) *AdvertisersNegativeKeywordListsPatchCall {
	c := &AdvertisersNegativeKeywordListsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.negativeKeywordListId = negativeKeywordListId
	c.negativekeywordlist = negativekeywordlist
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *AdvertisersNegativeKeywordListsPatchCall) UpdateMask(updateMask string) *AdvertisersNegativeKeywordListsPatchCall {
	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 *AdvertisersNegativeKeywordListsPatchCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsPatchCall {
	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 *AdvertisersNegativeKeywordListsPatchCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsPatchCall {
	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 *AdvertisersNegativeKeywordListsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.negativekeywordlist)
	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}/negativeKeywordLists/{negativeKeywordListId}")
	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),
		"negativeKeywordListId": strconv.FormatInt(c.negativeKeywordListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.negativeKeywordLists.patch" 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 *AdvertisersNegativeKeywordListsPatchCall) 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": "Updates a negative keyword list. Returns the updated negative keyword list\nif successful.",
	//   "flatPath": "v1/advertisers/{advertisersId}/negativeKeywordLists/{negativeKeywordListId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.patch",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "negativeKeywordListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the negative keyword list belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "negativeKeywordListId": {
	//       "description": "Output only. The unique ID of the negative keyword list. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "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}/negativeKeywordLists/{negativeKeywordListId}",
	//   "request": {
	//     "$ref": "NegativeKeywordList"
	//   },
	//   "response": {
	//     "$ref": "NegativeKeywordList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.bulkEdit":

type AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall struct {
	s                               *Service
	advertiserId                    int64
	negativeKeywordListId           int64
	bulkeditnegativekeywordsrequest *BulkEditNegativeKeywordsRequest
	urlParams_                      gensupport.URLParams
	ctx_                            context.Context
	header_                         http.Header
}

// BulkEdit: Bulk edits negative keywords in a single negative keyword
// list.
//
// The operation will delete the negative keywords provided
// in
// BulkEditNegativeKeywordsRequest.deleted_negative_keywords and
// then
// create the negative keywords provided
// in
// BulkEditNegativeKeywordsRequest.created_negative_keywords.
//
// This operation is guaranteed to be atomic and will never result in
// a
// partial success or partial failure.
func (r *AdvertisersNegativeKeywordListsNegativeKeywordsService) BulkEdit(advertiserId int64, negativeKeywordListId int64, bulkeditnegativekeywordsrequest *BulkEditNegativeKeywordsRequest) *AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall {
	c := &AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.negativeKeywordListId = negativeKeywordListId
	c.bulkeditnegativekeywordsrequest = bulkeditnegativekeywordsrequest
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.bulkeditnegativekeywordsrequest)
	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}/negativeKeywordLists/{+negativeKeywordListId}/negativeKeywords:bulkEdit")
	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),
		"negativeKeywordListId": strconv.FormatInt(c.negativeKeywordListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.bulkEdit" call.
// Exactly one of *BulkEditNegativeKeywordsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BulkEditNegativeKeywordsResponse.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 *AdvertisersNegativeKeywordListsNegativeKeywordsBulkEditCall) Do(opts ...googleapi.CallOption) (*BulkEditNegativeKeywordsResponse, 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 := &BulkEditNegativeKeywordsResponse{
		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 negative keywords in a single negative keyword list.\n\nThe operation will delete the negative keywords provided in\nBulkEditNegativeKeywordsRequest.deleted_negative_keywords and then\ncreate the negative keywords provided in\nBulkEditNegativeKeywordsRequest.created_negative_keywords.\n\nThis operation is guaranteed to be atomic and will never result in a\npartial success or partial failure.",
	//   "flatPath": "v1/advertisers/{advertiserId}/negativeKeywordLists/{negativeKeywordListsId}/negativeKeywords:bulkEdit",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.bulkEdit",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "negativeKeywordListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the parent negative keyword list\nbelongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "negativeKeywordListId": {
	//       "description": "Required. The ID of the parent negative keyword list to which the negative keywords\nbelong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/negativeKeywordLists/{+negativeKeywordListId}/negativeKeywords:bulkEdit",
	//   "request": {
	//     "$ref": "BulkEditNegativeKeywordsRequest"
	//   },
	//   "response": {
	//     "$ref": "BulkEditNegativeKeywordsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.create":

type AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall struct {
	s                     *Service
	advertiserId          int64
	negativeKeywordListId int64
	negativekeyword       *NegativeKeyword
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Create: Creates a negative keyword in a negative keyword list.
func (r *AdvertisersNegativeKeywordListsNegativeKeywordsService) Create(advertiserId int64, negativeKeywordListId int64, negativekeyword *NegativeKeyword) *AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall {
	c := &AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.negativeKeywordListId = negativeKeywordListId
	c.negativekeyword = negativekeyword
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.negativekeyword)
	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}/negativeKeywordLists/{+negativeKeywordListId}/negativeKeywords")
	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),
		"negativeKeywordListId": strconv.FormatInt(c.negativeKeywordListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.create" call.
// Exactly one of *NegativeKeyword or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *NegativeKeyword.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 *AdvertisersNegativeKeywordListsNegativeKeywordsCreateCall) Do(opts ...googleapi.CallOption) (*NegativeKeyword, 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 := &NegativeKeyword{
		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 negative keyword in a negative keyword list.",
	//   "flatPath": "v1/advertisers/{advertiserId}/negativeKeywordLists/{negativeKeywordListsId}/negativeKeywords",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.create",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "negativeKeywordListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the parent negative keyword list\nbelongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "negativeKeywordListId": {
	//       "description": "Required. The ID of the parent negative keyword list in which the negative keyword\nwill be created.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/negativeKeywordLists/{+negativeKeywordListId}/negativeKeywords",
	//   "request": {
	//     "$ref": "NegativeKeyword"
	//   },
	//   "response": {
	//     "$ref": "NegativeKeyword"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.delete":

type AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall struct {
	s                     *Service
	advertiserId          int64
	negativeKeywordListId int64
	keywordValue          string
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Delete: Deletes a negative keyword from a negative keyword list.
func (r *AdvertisersNegativeKeywordListsNegativeKeywordsService) Delete(advertiserId int64, negativeKeywordListId int64, keywordValue string) *AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall {
	c := &AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.negativeKeywordListId = negativeKeywordListId
	c.keywordValue = keywordValue
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/negativeKeywordLists/{+negativeKeywordListId}/negativeKeywords/{+keywordValue}")
	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),
		"negativeKeywordListId": strconv.FormatInt(c.negativeKeywordListId, 10),
		"keywordValue":          c.keywordValue,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.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 *AdvertisersNegativeKeywordListsNegativeKeywordsDeleteCall) 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 negative keyword from a negative keyword list.",
	//   "flatPath": "v1/advertisers/{advertiserId}/negativeKeywordLists/{negativeKeywordListsId}/negativeKeywords/{negativeKeywordsId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.delete",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "negativeKeywordListId",
	//     "keywordValue"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the parent negative keyword list\nbelongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "keywordValue": {
	//       "description": "Required. The keyword value of the negative keyword to delete.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "negativeKeywordListId": {
	//       "description": "Required. The ID of the parent negative keyword list to which the negative keyword\nbelongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{advertiserId}/negativeKeywordLists/{+negativeKeywordListId}/negativeKeywords/{+keywordValue}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.list":

type AdvertisersNegativeKeywordListsNegativeKeywordsListCall struct {
	s                     *Service
	advertiserId          int64
	negativeKeywordListId int64
	urlParams_            gensupport.URLParams
	ifNoneMatch_          string
	ctx_                  context.Context
	header_               http.Header
}

// List: Lists negative keywords in a negative keyword list.
func (r *AdvertisersNegativeKeywordListsNegativeKeywordsService) List(advertiserId int64, negativeKeywordListId int64) *AdvertisersNegativeKeywordListsNegativeKeywordsListCall {
	c := &AdvertisersNegativeKeywordListsNegativeKeywordsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.negativeKeywordListId = negativeKeywordListId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// negative keyword fields.
//
// Supported syntax:
//
// * Filter expressions for negative keyword currently can only contain
// at
// most one
// * restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `keywordValue`
//
// Examples:
//
// * All negative keywords for which the keyword value contains
// "google":
// `keywordValue : "google"
func (c *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) Filter(filter string) *AdvertisersNegativeKeywordListsNegativeKeywordsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `keywordValue` (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:
// `keywordValue desc`.
func (c *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) OrderBy(orderBy string) *AdvertisersNegativeKeywordListsNegativeKeywordsListCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) PageSize(pageSize int64) *AdvertisersNegativeKeywordListsNegativeKeywordsListCall {
	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 `ListNegativeKeywords` method. If not
// specified,
// the first page of results will be returned.
func (c *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) PageToken(pageToken string) *AdvertisersNegativeKeywordListsNegativeKeywordsListCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) Fields(s ...googleapi.Field) *AdvertisersNegativeKeywordListsNegativeKeywordsListCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) IfNoneMatch(entityTag string) *AdvertisersNegativeKeywordListsNegativeKeywordsListCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) Context(ctx context.Context) *AdvertisersNegativeKeywordListsNegativeKeywordsListCall {
	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 *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/negativeKeywords")
	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.negativeKeywords.list" call.
// Exactly one of *ListNegativeKeywordsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListNegativeKeywordsResponse.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 *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) Do(opts ...googleapi.CallOption) (*ListNegativeKeywordsResponse, 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 := &ListNegativeKeywordsResponse{
		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 keywords in a negative keyword list.",
	//   "flatPath": "v1/advertisers/{advertisersId}/negativeKeywordLists/{negativeKeywordListsId}/negativeKeywords",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.negativeKeywordLists.negativeKeywords.list",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "negativeKeywordListId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the DV360 advertiser to which the parent negative keyword list\nbelongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by negative keyword fields.\n\nSupported syntax:\n\n* Filter expressions for negative keyword currently can only contain at\nmost one\n* restriction.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `CONTAINS (:)`.\n* Supported fields:\n    - `keywordValue`\n\nExamples:\n\n* All negative keywords for which the keyword value contains \"google\":\n`keywordValue : \"google\"`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "negativeKeywordListId": {
	//       "description": "Required. The ID of the parent negative keyword list to which the requested negative\nkeywords belong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `keywordValue` (default)\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`keywordValue 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.\n\nTypically, this is the value of\nnext_page_token returned\nfrom the previous call to `ListNegativeKeywords` method. If not specified,\nthe first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/negativeKeywordLists/{+negativeKeywordListId}/negativeKeywords",
	//   "response": {
	//     "$ref": "ListNegativeKeywordsResponse"
	//   },
	//   "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 *AdvertisersNegativeKeywordListsNegativeKeywordsListCall) Pages(ctx context.Context, f func(*ListNegativeKeywordsResponse) 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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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.create":

type InventorySourceGroupsCreateCall struct {
	s                    *Service
	inventorysourcegroup *InventorySourceGroup
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Create: Creates a new inventory source group. Returns the newly
// created inventory
// source group if successful.
func (r *InventorySourceGroupsService) Create(inventorysourcegroup *InventorySourceGroup) *InventorySourceGroupsCreateCall {
	c := &InventorySourceGroupsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.inventorysourcegroup = inventorysourcegroup
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the inventory source group.
//
// The parent partner will not have access to this group.
func (c *InventorySourceGroupsCreateCall) AdvertiserId(advertiserId int64) *InventorySourceGroupsCreateCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the inventory source group.
//
// Only this partner will have write access to this group. Only
// advertisers
// to which this group is explicitly shared will have read access to
// this
// group.
func (c *InventorySourceGroupsCreateCall) PartnerId(partnerId int64) *InventorySourceGroupsCreateCall {
	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 *InventorySourceGroupsCreateCall) Fields(s ...googleapi.Field) *InventorySourceGroupsCreateCall {
	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 *InventorySourceGroupsCreateCall) Context(ctx context.Context) *InventorySourceGroupsCreateCall {
	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 *InventorySourceGroupsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.inventorysourcegroup)
	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/inventorySourceGroups")
	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.inventorySourceGroups.create" 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 *InventorySourceGroupsCreateCall) 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": "Creates a new inventory source group. Returns the newly created inventory\nsource group if successful.",
	//   "flatPath": "v1/inventorySourceGroups",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.inventorySourceGroups.create",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the inventory source group.\n\nThe parent partner will not have access to this group.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the inventory source group.\n\nOnly this partner will have write access to this group. Only advertisers\nto which this group is explicitly shared will have read access to this\ngroup.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySourceGroups",
	//   "request": {
	//     "$ref": "InventorySourceGroup"
	//   },
	//   "response": {
	//     "$ref": "InventorySourceGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.inventorySourceGroups.delete":

type InventorySourceGroupsDeleteCall struct {
	s                      *Service
	inventorySourceGroupId int64
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Delete: Deletes an inventory source group.
func (r *InventorySourceGroupsService) Delete(inventorySourceGroupId int64) *InventorySourceGroupsDeleteCall {
	c := &InventorySourceGroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.inventorySourceGroupId = inventorySourceGroupId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the inventory source group.
//
// The parent partner does not have access to this group.
func (c *InventorySourceGroupsDeleteCall) AdvertiserId(advertiserId int64) *InventorySourceGroupsDeleteCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the inventory source group.
//
// Only this partner has write access to this group.
func (c *InventorySourceGroupsDeleteCall) PartnerId(partnerId int64) *InventorySourceGroupsDeleteCall {
	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 *InventorySourceGroupsDeleteCall) Fields(s ...googleapi.Field) *InventorySourceGroupsDeleteCall {
	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 *InventorySourceGroupsDeleteCall) Context(ctx context.Context) *InventorySourceGroupsDeleteCall {
	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 *InventorySourceGroupsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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/inventorySourceGroups/{+inventorySourceGroupId}")
	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{
		"inventorySourceGroupId": strconv.FormatInt(c.inventorySourceGroupId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySourceGroups.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 *InventorySourceGroupsDeleteCall) 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 inventory source group.",
	//   "flatPath": "v1/inventorySourceGroups/{inventorySourceGroupsId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.inventorySourceGroups.delete",
	//   "parameterOrder": [
	//     "inventorySourceGroupId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the inventory source group.\n\nThe parent partner does not have access to this group.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "inventorySourceGroupId": {
	//       "description": "Required. The ID of the inventory source group to delete.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the inventory source group.\n\nOnly this partner has write access to this group.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySourceGroups/{+inventorySourceGroupId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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/20200715")
	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/20200715")
	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.inventorySourceGroups.patch":

type InventorySourceGroupsPatchCall struct {
	s                      *Service
	inventorySourceGroupId int64
	inventorysourcegroup   *InventorySourceGroup
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Patch: Updates an inventory source group. Returns the updated
// inventory source
// group if successful.
func (r *InventorySourceGroupsService) Patch(inventorySourceGroupId int64, inventorysourcegroup *InventorySourceGroup) *InventorySourceGroupsPatchCall {
	c := &InventorySourceGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.inventorySourceGroupId = inventorySourceGroupId
	c.inventorysourcegroup = inventorysourcegroup
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the inventory source group.
//
// The parent partner does not have access to this group.
func (c *InventorySourceGroupsPatchCall) AdvertiserId(advertiserId int64) *InventorySourceGroupsPatchCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the inventory source group.
//
// Only this partner has write access to this group.
func (c *InventorySourceGroupsPatchCall) PartnerId(partnerId int64) *InventorySourceGroupsPatchCall {
	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 *InventorySourceGroupsPatchCall) UpdateMask(updateMask string) *InventorySourceGroupsPatchCall {
	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 *InventorySourceGroupsPatchCall) Fields(s ...googleapi.Field) *InventorySourceGroupsPatchCall {
	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 *InventorySourceGroupsPatchCall) Context(ctx context.Context) *InventorySourceGroupsPatchCall {
	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 *InventorySourceGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.inventorysourcegroup)
	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/inventorySourceGroups/{inventorySourceGroupId}")
	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{
		"inventorySourceGroupId": strconv.FormatInt(c.inventorySourceGroupId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySourceGroups.patch" 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 *InventorySourceGroupsPatchCall) 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": "Updates an inventory source group. Returns the updated inventory source\ngroup if successful.",
	//   "flatPath": "v1/inventorySourceGroups/{inventorySourceGroupId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.inventorySourceGroups.patch",
	//   "parameterOrder": [
	//     "inventorySourceGroupId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the inventory source group.\n\nThe parent partner does not have access to this group.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "inventorySourceGroupId": {
	//       "description": "Output only. The unique ID of the inventory source group. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the inventory source group.\n\nOnly this partner has write access to this group.",
	//       "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/inventorySourceGroups/{inventorySourceGroupId}",
	//   "request": {
	//     "$ref": "InventorySourceGroup"
	//   },
	//   "response": {
	//     "$ref": "InventorySourceGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.inventorySourceGroups.assignedInventorySources.bulkEdit":

type InventorySourceGroupsAssignedInventorySourcesBulkEditCall struct {
	s                                       *Service
	inventorySourceGroupId                  int64
	bulkeditassignedinventorysourcesrequest *BulkEditAssignedInventorySourcesRequest
	urlParams_                              gensupport.URLParams
	ctx_                                    context.Context
	header_                                 http.Header
}

// BulkEdit: Bulk edits multiple assignments between inventory sources
// and a single
// inventory source group.
//
// The operation will delete the assigned inventory sources provided
// in
// BulkEditAssignedInventorySourcesRequest.deleted_assigned_inventory_
// sources
// and then create the assigned inventory sources provided
// in
// BulkEditAssignedInventorySourcesRequest.created_assigned_inventory_
// sources.
func (r *InventorySourceGroupsAssignedInventorySourcesService) BulkEdit(inventorySourceGroupId int64, bulkeditassignedinventorysourcesrequest *BulkEditAssignedInventorySourcesRequest) *InventorySourceGroupsAssignedInventorySourcesBulkEditCall {
	c := &InventorySourceGroupsAssignedInventorySourcesBulkEditCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.inventorySourceGroupId = inventorySourceGroupId
	c.bulkeditassignedinventorysourcesrequest = bulkeditassignedinventorysourcesrequest
	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 *InventorySourceGroupsAssignedInventorySourcesBulkEditCall) Fields(s ...googleapi.Field) *InventorySourceGroupsAssignedInventorySourcesBulkEditCall {
	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 *InventorySourceGroupsAssignedInventorySourcesBulkEditCall) Context(ctx context.Context) *InventorySourceGroupsAssignedInventorySourcesBulkEditCall {
	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 *InventorySourceGroupsAssignedInventorySourcesBulkEditCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsAssignedInventorySourcesBulkEditCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.bulkeditassignedinventorysourcesrequest)
	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/inventorySourceGroups/{+inventorySourceGroupId}/assignedInventorySources:bulkEdit")
	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{
		"inventorySourceGroupId": strconv.FormatInt(c.inventorySourceGroupId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySourceGroups.assignedInventorySources.bulkEdit" call.
// Exactly one of *BulkEditAssignedInventorySourcesResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *BulkEditAssignedInventorySourcesResponse.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 *InventorySourceGroupsAssignedInventorySourcesBulkEditCall) Do(opts ...googleapi.CallOption) (*BulkEditAssignedInventorySourcesResponse, 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 := &BulkEditAssignedInventorySourcesResponse{
		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 multiple assignments between inventory sources and a single\ninventory source group.\n\nThe operation will delete the assigned inventory sources provided in\nBulkEditAssignedInventorySourcesRequest.deleted_assigned_inventory_sources\nand then create the assigned inventory sources provided in\nBulkEditAssignedInventorySourcesRequest.created_assigned_inventory_sources.",
	//   "flatPath": "v1/inventorySourceGroups/{inventorySourceGroupsId}/assignedInventorySources:bulkEdit",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.inventorySourceGroups.assignedInventorySources.bulkEdit",
	//   "parameterOrder": [
	//     "inventorySourceGroupId"
	//   ],
	//   "parameters": {
	//     "inventorySourceGroupId": {
	//       "description": "Required. The ID of the inventory source group to which the assignments are\nassigned.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySourceGroups/{+inventorySourceGroupId}/assignedInventorySources:bulkEdit",
	//   "request": {
	//     "$ref": "BulkEditAssignedInventorySourcesRequest"
	//   },
	//   "response": {
	//     "$ref": "BulkEditAssignedInventorySourcesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.inventorySourceGroups.assignedInventorySources.create":

type InventorySourceGroupsAssignedInventorySourcesCreateCall struct {
	s                       *Service
	inventorySourceGroupId  int64
	assignedinventorysource *AssignedInventorySource
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Create: Creates an assignment between an inventory source and an
// inventory source
// group.
func (r *InventorySourceGroupsAssignedInventorySourcesService) Create(inventorySourceGroupId int64, assignedinventorysource *AssignedInventorySource) *InventorySourceGroupsAssignedInventorySourcesCreateCall {
	c := &InventorySourceGroupsAssignedInventorySourcesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.inventorySourceGroupId = inventorySourceGroupId
	c.assignedinventorysource = assignedinventorysource
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the parent inventory source group.
//
// The parent partner will not have access to this assigned
// inventory
// source.
func (c *InventorySourceGroupsAssignedInventorySourcesCreateCall) AdvertiserId(advertiserId int64) *InventorySourceGroupsAssignedInventorySourcesCreateCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the parent inventory source group.
//
// Only this partner will have write access to this assigned
// inventory
// source.
func (c *InventorySourceGroupsAssignedInventorySourcesCreateCall) PartnerId(partnerId int64) *InventorySourceGroupsAssignedInventorySourcesCreateCall {
	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 *InventorySourceGroupsAssignedInventorySourcesCreateCall) Fields(s ...googleapi.Field) *InventorySourceGroupsAssignedInventorySourcesCreateCall {
	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 *InventorySourceGroupsAssignedInventorySourcesCreateCall) Context(ctx context.Context) *InventorySourceGroupsAssignedInventorySourcesCreateCall {
	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 *InventorySourceGroupsAssignedInventorySourcesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsAssignedInventorySourcesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.assignedinventorysource)
	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/inventorySourceGroups/{+inventorySourceGroupId}/assignedInventorySources")
	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{
		"inventorySourceGroupId": strconv.FormatInt(c.inventorySourceGroupId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySourceGroups.assignedInventorySources.create" call.
// Exactly one of *AssignedInventorySource or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AssignedInventorySource.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 *InventorySourceGroupsAssignedInventorySourcesCreateCall) Do(opts ...googleapi.CallOption) (*AssignedInventorySource, 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 := &AssignedInventorySource{
		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 assignment between an inventory source and an inventory source\ngroup.",
	//   "flatPath": "v1/inventorySourceGroups/{inventorySourceGroupsId}/assignedInventorySources",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.inventorySourceGroups.assignedInventorySources.create",
	//   "parameterOrder": [
	//     "inventorySourceGroupId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent inventory source group.\n\nThe parent partner will not have access to this assigned inventory\nsource.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "inventorySourceGroupId": {
	//       "description": "Required. The ID of the inventory source group to which the assignment will be\nassigned.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the parent inventory source group.\n\nOnly this partner will have write access to this assigned inventory\nsource.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySourceGroups/{+inventorySourceGroupId}/assignedInventorySources",
	//   "request": {
	//     "$ref": "AssignedInventorySource"
	//   },
	//   "response": {
	//     "$ref": "AssignedInventorySource"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.inventorySourceGroups.assignedInventorySources.delete":

type InventorySourceGroupsAssignedInventorySourcesDeleteCall struct {
	s                         *Service
	inventorySourceGroupId    int64
	assignedInventorySourceId int64
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Delete: Deletes the assignment between an inventory source and an
// inventory source
// group.
func (r *InventorySourceGroupsAssignedInventorySourcesService) Delete(inventorySourceGroupId int64, assignedInventorySourceId int64) *InventorySourceGroupsAssignedInventorySourcesDeleteCall {
	c := &InventorySourceGroupsAssignedInventorySourcesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.inventorySourceGroupId = inventorySourceGroupId
	c.assignedInventorySourceId = assignedInventorySourceId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the parent inventory source group.
//
// The parent partner does not have access to this assigned
// inventory
// source.
func (c *InventorySourceGroupsAssignedInventorySourcesDeleteCall) AdvertiserId(advertiserId int64) *InventorySourceGroupsAssignedInventorySourcesDeleteCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that owns the parent inventory source group.
//
// Only this partner has write access to this assigned inventory source.
func (c *InventorySourceGroupsAssignedInventorySourcesDeleteCall) PartnerId(partnerId int64) *InventorySourceGroupsAssignedInventorySourcesDeleteCall {
	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 *InventorySourceGroupsAssignedInventorySourcesDeleteCall) Fields(s ...googleapi.Field) *InventorySourceGroupsAssignedInventorySourcesDeleteCall {
	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 *InventorySourceGroupsAssignedInventorySourcesDeleteCall) Context(ctx context.Context) *InventorySourceGroupsAssignedInventorySourcesDeleteCall {
	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 *InventorySourceGroupsAssignedInventorySourcesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsAssignedInventorySourcesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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/inventorySourceGroups/{+inventorySourceGroupId}/assignedInventorySources/{+assignedInventorySourceId}")
	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{
		"inventorySourceGroupId":    strconv.FormatInt(c.inventorySourceGroupId, 10),
		"assignedInventorySourceId": strconv.FormatInt(c.assignedInventorySourceId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.inventorySourceGroups.assignedInventorySources.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 *InventorySourceGroupsAssignedInventorySourcesDeleteCall) 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 the assignment between an inventory source and an inventory source\ngroup.",
	//   "flatPath": "v1/inventorySourceGroups/{inventorySourceGroupsId}/assignedInventorySources/{assignedInventorySourcesId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.inventorySourceGroups.assignedInventorySources.delete",
	//   "parameterOrder": [
	//     "inventorySourceGroupId",
	//     "assignedInventorySourceId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent inventory source group.\n\nThe parent partner does not have access to this assigned inventory\nsource.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "assignedInventorySourceId": {
	//       "description": "Required. The ID of the assigned inventory source to delete.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "inventorySourceGroupId": {
	//       "description": "Required. The ID of the inventory source group to which this assignment is assigned.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the parent inventory source group.\n\nOnly this partner has write access to this assigned inventory source.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySourceGroups/{+inventorySourceGroupId}/assignedInventorySources/{+assignedInventorySourceId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.inventorySourceGroups.assignedInventorySources.list":

type InventorySourceGroupsAssignedInventorySourcesListCall struct {
	s                      *Service
	inventorySourceGroupId int64
	urlParams_             gensupport.URLParams
	ifNoneMatch_           string
	ctx_                   context.Context
	header_                http.Header
}

// List: Lists inventory sources assigned to an inventory source group.
func (r *InventorySourceGroupsAssignedInventorySourcesService) List(inventorySourceGroupId int64) *InventorySourceGroupsAssignedInventorySourcesListCall {
	c := &InventorySourceGroupsAssignedInventorySourcesListCall{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 assignment.
//
// If the parent inventory source group is partner-owned, only
// advertisers
// to which the parent group is explicitly shared can access the
// assigned
// inventory source.
func (c *InventorySourceGroupsAssignedInventorySourcesListCall) AdvertiserId(advertiserId int64) *InventorySourceGroupsAssignedInventorySourcesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by
// assigned inventory source fields.
//
// 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:
//     - `assignedInventorySourceId`
//
// The length of this field should be no more than 500 characters.
func (c *InventorySourceGroupsAssignedInventorySourcesListCall) Filter(filter string) *InventorySourceGroupsAssignedInventorySourcesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `assignedInventorySourceId` (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:
// `assignedInventorySourceId desc`.
func (c *InventorySourceGroupsAssignedInventorySourcesListCall) OrderBy(orderBy string) *InventorySourceGroupsAssignedInventorySourcesListCall {
	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 *InventorySourceGroupsAssignedInventorySourcesListCall) PageSize(pageSize int64) *InventorySourceGroupsAssignedInventorySourcesListCall {
	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
// `ListAssignedInventorySources`
// method. If not specified, the first page of results will be returned.
func (c *InventorySourceGroupsAssignedInventorySourcesListCall) PageToken(pageToken string) *InventorySourceGroupsAssignedInventorySourcesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PartnerId sets the optional parameter "partnerId": The ID of the
// partner that has access to the assignment.
//
// If the parent inventory source group is advertiser-owned, the
// assignment
// cannot be accessed via a partner.
func (c *InventorySourceGroupsAssignedInventorySourcesListCall) PartnerId(partnerId int64) *InventorySourceGroupsAssignedInventorySourcesListCall {
	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 *InventorySourceGroupsAssignedInventorySourcesListCall) Fields(s ...googleapi.Field) *InventorySourceGroupsAssignedInventorySourcesListCall {
	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 *InventorySourceGroupsAssignedInventorySourcesListCall) IfNoneMatch(entityTag string) *InventorySourceGroupsAssignedInventorySourcesListCall {
	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 *InventorySourceGroupsAssignedInventorySourcesListCall) Context(ctx context.Context) *InventorySourceGroupsAssignedInventorySourcesListCall {
	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 *InventorySourceGroupsAssignedInventorySourcesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventorySourceGroupsAssignedInventorySourcesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/assignedInventorySources")
	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.assignedInventorySources.list" call.
// Exactly one of *ListAssignedInventorySourcesResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListAssignedInventorySourcesResponse.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 *InventorySourceGroupsAssignedInventorySourcesListCall) Do(opts ...googleapi.CallOption) (*ListAssignedInventorySourcesResponse, 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 := &ListAssignedInventorySourcesResponse{
		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 assigned to an inventory source group.",
	//   "flatPath": "v1/inventorySourceGroups/{inventorySourceGroupsId}/assignedInventorySources",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.inventorySourceGroups.assignedInventorySources.list",
	//   "parameterOrder": [
	//     "inventorySourceGroupId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that has access to the assignment.\n\nIf the parent inventory source group is partner-owned, only advertisers\nto which the parent group is explicitly shared can access the assigned\ninventory source.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by assigned inventory source fields.\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    - `assignedInventorySourceId`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "inventorySourceGroupId": {
	//       "description": "Required. The ID of the inventory source group to which these assignments are\nassigned.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `assignedInventorySourceId` (default)\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`assignedInventorySourceId 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.\n\nTypically, this is the value of\nnext_page_token\nreturned from the previous call to `ListAssignedInventorySources`\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 assignment.\n\nIf the parent inventory source group is advertiser-owned, the assignment\ncannot be accessed via a partner.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/inventorySourceGroups/{+inventorySourceGroupId}/assignedInventorySources",
	//   "response": {
	//     "$ref": "ListAssignedInventorySourcesResponse"
	//   },
	//   "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 *InventorySourceGroupsAssignedInventorySourcesListCall) Pages(ctx context.Context, f func(*ListAssignedInventorySourcesResponse) 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/20200715")
	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/20200715")
	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/20200715")
	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.create":

type PartnersChannelsCreateCall struct {
	s          *Service
	partnerId  int64
	channel    *Channel
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a new channel. Returns the newly created channel if
// successful.
func (r *PartnersChannelsService) Create(partnerId int64, channel *Channel) *PartnersChannelsCreateCall {
	c := &PartnersChannelsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.partnerId = partnerId
	c.channel = channel
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the created channel.
func (c *PartnersChannelsCreateCall) AdvertiserId(advertiserId int64) *PartnersChannelsCreateCall {
	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 *PartnersChannelsCreateCall) Fields(s ...googleapi.Field) *PartnersChannelsCreateCall {
	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 *PartnersChannelsCreateCall) Context(ctx context.Context) *PartnersChannelsCreateCall {
	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 *PartnersChannelsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PartnersChannelsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.channel)
	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/partners/{+partnerId}/channels")
	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{
		"partnerId": strconv.FormatInt(c.partnerId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.partners.channels.create" 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 *PartnersChannelsCreateCall) 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": "Creates a new channel. Returns the newly created channel if successful.",
	//   "flatPath": "v1/partners/{partnersId}/channels",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.partners.channels.create",
	//   "parameterOrder": [
	//     "partnerId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the created channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the created channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/partners/{+partnerId}/channels",
	//   "request": {
	//     "$ref": "Channel"
	//   },
	//   "response": {
	//     "$ref": "Channel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// 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/20200715")
	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/20200715")
	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.partners.channels.patch":

type PartnersChannelsPatchCall struct {
	s          *Service
	partnerId  int64
	channelId  int64
	channel    *Channel
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates a channel. Returns the updated channel if successful.
func (r *PartnersChannelsService) Patch(partnerId int64, channelId int64, channel *Channel) *PartnersChannelsPatchCall {
	c := &PartnersChannelsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.partnerId = partnerId
	c.channelId = channelId
	c.channel = channel
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the created channel.
func (c *PartnersChannelsPatchCall) AdvertiserId(advertiserId int64) *PartnersChannelsPatchCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *PartnersChannelsPatchCall) UpdateMask(updateMask string) *PartnersChannelsPatchCall {
	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 *PartnersChannelsPatchCall) Fields(s ...googleapi.Field) *PartnersChannelsPatchCall {
	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 *PartnersChannelsPatchCall) Context(ctx context.Context) *PartnersChannelsPatchCall {
	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 *PartnersChannelsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PartnersChannelsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.channel)
	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/partners/{+partnerId}/channels/{channelId}")
	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{
		"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.patch" 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 *PartnersChannelsPatchCall) 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": "Updates a channel. Returns the updated channel if successful.",
	//   "flatPath": "v1/partners/{partnersId}/channels/{channelId}",
	//   "httpMethod": "PATCH",
	//   "id": "displayvideo.partners.channels.patch",
	//   "parameterOrder": [
	//     "partnerId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the created channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Output only. The unique ID of the channel. Assigned by the system.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the created channel.",
	//       "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/partners/{+partnerId}/channels/{channelId}",
	//   "request": {
	//     "$ref": "Channel"
	//   },
	//   "response": {
	//     "$ref": "Channel"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.partners.channels.sites.bulkEdit":

type PartnersChannelsSitesBulkEditCall struct {
	s                    *Service
	partnerId            int64
	channelId            int64
	bulkeditsitesrequest *BulkEditSitesRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// BulkEdit: Bulk edits sites under a single channel.
//
// The operation will delete the sites provided
// in
// BulkEditSitesRequest.deleted_sites and then create the sites
// provided in BulkEditSitesRequest.created_sites.
func (r *PartnersChannelsSitesService) BulkEdit(partnerId int64, channelId int64, bulkeditsitesrequest *BulkEditSitesRequest) *PartnersChannelsSitesBulkEditCall {
	c := &PartnersChannelsSitesBulkEditCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.partnerId = partnerId
	c.channelId = channelId
	c.bulkeditsitesrequest = bulkeditsitesrequest
	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 *PartnersChannelsSitesBulkEditCall) Fields(s ...googleapi.Field) *PartnersChannelsSitesBulkEditCall {
	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 *PartnersChannelsSitesBulkEditCall) Context(ctx context.Context) *PartnersChannelsSitesBulkEditCall {
	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 *PartnersChannelsSitesBulkEditCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PartnersChannelsSitesBulkEditCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.bulkeditsitesrequest)
	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/partners/{partnerId}/channels/{+channelId}/sites:bulkEdit")
	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{
		"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.sites.bulkEdit" call.
// Exactly one of *BulkEditSitesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BulkEditSitesResponse.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 *PartnersChannelsSitesBulkEditCall) Do(opts ...googleapi.CallOption) (*BulkEditSitesResponse, 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 := &BulkEditSitesResponse{
		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 sites under a single channel.\n\nThe operation will delete the sites provided in\nBulkEditSitesRequest.deleted_sites and then create the sites\nprovided in BulkEditSitesRequest.created_sites.",
	//   "flatPath": "v1/partners/{partnerId}/channels/{channelsId}/sites:bulkEdit",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.partners.channels.sites.bulkEdit",
	//   "parameterOrder": [
	//     "partnerId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "channelId": {
	//       "description": "Required. The ID of the parent channel to which the sites belong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the parent channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/partners/{partnerId}/channels/{+channelId}/sites:bulkEdit",
	//   "request": {
	//     "$ref": "BulkEditSitesRequest"
	//   },
	//   "response": {
	//     "$ref": "BulkEditSitesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.partners.channels.sites.create":

type PartnersChannelsSitesCreateCall struct {
	s          *Service
	partnerId  int64
	channelId  int64
	site       *Site
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a site in a channel.
func (r *PartnersChannelsSitesService) Create(partnerId int64, channelId int64, site *Site) *PartnersChannelsSitesCreateCall {
	c := &PartnersChannelsSitesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.partnerId = partnerId
	c.channelId = channelId
	c.site = site
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the parent channel.
func (c *PartnersChannelsSitesCreateCall) AdvertiserId(advertiserId int64) *PartnersChannelsSitesCreateCall {
	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 *PartnersChannelsSitesCreateCall) Fields(s ...googleapi.Field) *PartnersChannelsSitesCreateCall {
	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 *PartnersChannelsSitesCreateCall) Context(ctx context.Context) *PartnersChannelsSitesCreateCall {
	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 *PartnersChannelsSitesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PartnersChannelsSitesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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.site)
	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/partners/{partnerId}/channels/{+channelId}/sites")
	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{
		"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.sites.create" call.
// Exactly one of *Site or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Site.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 *PartnersChannelsSitesCreateCall) Do(opts ...googleapi.CallOption) (*Site, 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 := &Site{
		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 site in a channel.",
	//   "flatPath": "v1/partners/{partnerId}/channels/{channelsId}/sites",
	//   "httpMethod": "POST",
	//   "id": "displayvideo.partners.channels.sites.create",
	//   "parameterOrder": [
	//     "partnerId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the parent channel in which the site will be created.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the parent channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/partners/{partnerId}/channels/{+channelId}/sites",
	//   "request": {
	//     "$ref": "Site"
	//   },
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.partners.channels.sites.delete":

type PartnersChannelsSitesDeleteCall struct {
	s          *Service
	partnerId  int64
	channelId  int64
	urlOrAppId string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a site from a channel.
func (r *PartnersChannelsSitesService) Delete(partnerId int64, channelId int64, urlOrAppId string) *PartnersChannelsSitesDeleteCall {
	c := &PartnersChannelsSitesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.partnerId = partnerId
	c.channelId = channelId
	c.urlOrAppId = urlOrAppId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": The ID of
// the advertiser that owns the parent channel.
func (c *PartnersChannelsSitesDeleteCall) AdvertiserId(advertiserId int64) *PartnersChannelsSitesDeleteCall {
	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 *PartnersChannelsSitesDeleteCall) Fields(s ...googleapi.Field) *PartnersChannelsSitesDeleteCall {
	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 *PartnersChannelsSitesDeleteCall) Context(ctx context.Context) *PartnersChannelsSitesDeleteCall {
	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 *PartnersChannelsSitesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PartnersChannelsSitesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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/partners/{partnerId}/channels/{+channelId}/sites/{+urlOrAppId}")
	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{
		"partnerId":  strconv.FormatInt(c.partnerId, 10),
		"channelId":  strconv.FormatInt(c.channelId, 10),
		"urlOrAppId": c.urlOrAppId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.partners.channels.sites.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 *PartnersChannelsSitesDeleteCall) 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 site from a channel.",
	//   "flatPath": "v1/partners/{partnerId}/channels/{channelsId}/sites/{sitesId}",
	//   "httpMethod": "DELETE",
	//   "id": "displayvideo.partners.channels.sites.delete",
	//   "parameterOrder": [
	//     "partnerId",
	//     "channelId",
	//     "urlOrAppId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the parent channel to which the site belongs.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "partnerId": {
	//       "description": "The ID of the partner that owns the parent channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "urlOrAppId": {
	//       "description": "Required. The URL or app ID of the site to delete.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/partners/{partnerId}/channels/{+channelId}/sites/{+urlOrAppId}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.partners.channels.sites.list":

type PartnersChannelsSitesListCall struct {
	s            *Service
	partnerId    int64
	channelId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists sites in a channel.
func (r *PartnersChannelsSitesService) List(partnerId int64, channelId int64) *PartnersChannelsSitesListCall {
	c := &PartnersChannelsSitesListCall{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 parent channel.
func (c *PartnersChannelsSitesListCall) AdvertiserId(advertiserId int64) *PartnersChannelsSitesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by site
// fields.
//
// Supported syntax:
//
// * Filter expressions for site currently can only contain at most
// one
// * restriction.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `CONTAINS (:)`.
// * Supported fields:
//     - `urlOrAppId`
//
// Examples:
//
// * All sites for which the URL or app ID contains
// "google":
// `urlOrAppId : "google"
func (c *PartnersChannelsSitesListCall) Filter(filter string) *PartnersChannelsSitesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * `urlOrAppId` (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:
// `urlOrAppId desc`.
func (c *PartnersChannelsSitesListCall) OrderBy(orderBy string) *PartnersChannelsSitesListCall {
	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 *PartnersChannelsSitesListCall) PageSize(pageSize int64) *PartnersChannelsSitesListCall {
	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 `ListSites` method. If not specified, the first
// page
// of results will be returned.
func (c *PartnersChannelsSitesListCall) PageToken(pageToken string) *PartnersChannelsSitesListCall {
	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 *PartnersChannelsSitesListCall) Fields(s ...googleapi.Field) *PartnersChannelsSitesListCall {
	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 *PartnersChannelsSitesListCall) IfNoneMatch(entityTag string) *PartnersChannelsSitesListCall {
	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 *PartnersChannelsSitesListCall) Context(ctx context.Context) *PartnersChannelsSitesListCall {
	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 *PartnersChannelsSitesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PartnersChannelsSitesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200715")
	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}/sites")
	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.sites.list" call.
// Exactly one of *ListSitesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListSitesResponse.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 *PartnersChannelsSitesListCall) Do(opts ...googleapi.CallOption) (*ListSitesResponse, 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 := &ListSitesResponse{
		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 sites in a channel.",
	//   "flatPath": "v1/partners/{partnersId}/channels/{channelsId}/sites",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.partners.channels.sites.list",
	//   "parameterOrder": [
	//     "partnerId",
	//     "channelId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "The ID of the advertiser that owns the parent channel.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "channelId": {
	//       "description": "Required. The ID of the parent channel to which the requested sites belong.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by site fields.\n\nSupported syntax:\n\n* Filter expressions for site 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    - `urlOrAppId`\n\nExamples:\n\n* All sites for which the URL or app ID contains \"google\":\n`urlOrAppId : \"google\"`",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* `urlOrAppId` (default)\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`urlOrAppId 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.\n\nTypically, this is the value of\nnext_page_token returned from the\nprevious call to `ListSites` 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 parent channel.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/partners/{+partnerId}/channels/{+channelId}/sites",
	//   "response": {
	//     "$ref": "ListSitesResponse"
	//   },
	//   "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 *PartnersChannelsSitesListCall) Pages(ctx context.Context, f func(*ListSitesResponse) 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/20200715")
	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/20200715")
	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/20200715")
	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/20200715")
	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)
	}
}
