// 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.
	// Must be greater than or equal to a billable unit of the given
	// currency and
	// smaller or equal to upper bounds. Each
	// performance_goal_type
	// has its upper bound:
	//
	// * when
	// performance_goal_type
	// is `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPA`,
	// upper bound is 10000.00 USD.
	// * when
	// performance_goal_type
	// is `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_CPC`,
	// upper bound is 1000.00 USD.
	// * when
	// performance_goal_type
	// is `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM`, upper bound
	// is
	// 1000.00 USD.
	//
	// Example: If set
	// to
	// `BIDDING_STRATEGY_PERFORMANCE_GOAL_TYPE_VIEWABLE_CPM`, the bid price
	// will
	// be based on the probability that each available impression will
	// be
	// viewable. For example, if viewable CPM target is $2 and an impression
	// is
	// 40% likely to be viewable, the bid price will be $0.80 CPM (40% of
	// $2).
	//
	// For example, 1500000 represents 1.5 standard units of the currency.
	PerformanceGoalAmountMicros int64 `json:"performanceGoalAmountMicros,omitempty,string"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// Version: Required. The version of SDF being used.
	//
	// Possible values:
	//   "SDF_VERSION_UNSPECIFIED" - SDF version value is not specified or
	// is unknown in this version.
	//   "SDF_VERSION_3_1" - SDF version 3.1
	//   "SDF_VERSION_4" - SDF version 4
	//   "SDF_VERSION_4_1" - SDF version 4.1
	//   "SDF_VERSION_4_2" - SDF version 4.2
	//   "SDF_VERSION_5" - SDF version 5.
	//   "SDF_VERSION_5_1" - SDF version 5.1
	//   "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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
		"lineItemId":   strconv.FormatInt(c.lineItemId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "displayvideo.advertisers.lineItems.get" call.
// Exactly one of *LineItem or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *LineItem.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertisersLineItemsGetCall) Do(opts ...googleapi.CallOption) (*LineItem, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LineItem{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a line item.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems/{lineItemsId}",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.lineItems.get",
	//   "parameterOrder": [
	//     "advertiserId",
	//     "lineItemId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser this line item belongs to.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "lineItemId": {
	//       "description": "Required. The ID of the line item to fetch.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems/{+lineItemId}",
	//   "response": {
	//     "$ref": "LineItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// method id "displayvideo.advertisers.lineItems.list":

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

// List: Lists line items in an advertiser.
//
// The order is defined by the order_by
// parameter.
// If a filter by
// entity_status is not specified, line items
// with
// `ENTITY_STATUS_ARCHIVED` will not be included in the results.
func (r *AdvertisersLineItemsService) List(advertiserId int64) *AdvertisersLineItemsListCall {
	c := &AdvertisersLineItemsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	return c
}

// Filter sets the optional parameter "filter": Allows filtering by line
// item properties.
//
// Supported syntax:
//
// * Filter expressions are made up of one or more restrictions.
// * Restrictions can be combined by `AND` or `OR` logical operators.
// A
// sequence of restrictions implicitly uses `AND`.
// * A restriction has the form of `{field} {operator} {value}`.
// * The operator must be `EQUALS (=)`.
// * Supported fields:
//     - `campaignId`
//     - `insertionOrderId`
//     - `entityStatus`
//     - `lineItemType`.
//
// Examples:
//
// * All line items under an insertion order:
// `insertionOrderId="1234"
// * All `ENTITY_STATUS_ACTIVE` or `ENTITY_STATUS_PAUSED`
// and `LINE_ITEM_TYPE_DISPLAY_DEFAULT` line items under an
// advertiser:
// `(entityStatus="ENTITY_STATUS_ACTIVE"
// OR
// entityStatus="ENTITY_STATUS_PAUSED")
// AND
// lineItemType="LINE_ITEM_TYPE_DISPLAY_DEFAULT"
//
// The length of this field should be no more than 500 characters.
func (c *AdvertisersLineItemsListCall) Filter(filter string) *AdvertisersLineItemsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// OrderBy sets the optional parameter "orderBy": Field by which to sort
// the list.
// Acceptable values are:
//
// * "displayName" (default)
// * "entityStatus"
//
// The default sorting order is ascending. To specify descending order
// for
// a field, a suffix "desc" should be added to the field name.
// Example:
// `displayName desc`.
func (c *AdvertisersLineItemsListCall) OrderBy(orderBy string) *AdvertisersLineItemsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Must be between `1` and `100`. If unspecified will
// default to `100`. Returns error code `INVALID_ARGUMENT` if an invalid
// value
// is specified.
func (c *AdvertisersLineItemsListCall) PageSize(pageSize int64) *AdvertisersLineItemsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results the server should return.
// Typically, this is the value of
// next_page_token
// returned from the previous call to `ListLineItems` method.
// If not specified, the first page of results will be returned.
func (c *AdvertisersLineItemsListCall) PageToken(pageToken string) *AdvertisersLineItemsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

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

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

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

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

// Do executes the "displayvideo.advertisers.lineItems.list" call.
// Exactly one of *ListLineItemsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListLineItemsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertisersLineItemsListCall) Do(opts ...googleapi.CallOption) (*ListLineItemsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListLineItemsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists line items in an advertiser.\n\nThe order is defined by the order_by\nparameter.\nIf a filter by\nentity_status is not specified, line items with\n`ENTITY_STATUS_ARCHIVED` will not be included in the results.",
	//   "flatPath": "v1/advertisers/{advertisersId}/lineItems",
	//   "httpMethod": "GET",
	//   "id": "displayvideo.advertisers.lineItems.list",
	//   "parameterOrder": [
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Required. The ID of the advertiser to list line items for.",
	//       "format": "int64",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "Allows filtering by line item properties.\n\nSupported syntax:\n\n* Filter expressions are made up of one or more restrictions.\n* Restrictions can be combined by `AND` or `OR` logical operators. A\nsequence of restrictions implicitly uses `AND`.\n* A restriction has the form of `{field} {operator} {value}`.\n* The operator must be `EQUALS (=)`.\n* Supported fields:\n    - `campaignId`\n    - `insertionOrderId`\n    - `entityStatus`\n    - `lineItemType`.\n\nExamples:\n\n* All line items under an insertion order: `insertionOrderId=\"1234\"`\n* All `ENTITY_STATUS_ACTIVE` or `ENTITY_STATUS_PAUSED`\nand `LINE_ITEM_TYPE_DISPLAY_DEFAULT` line items under an advertiser:\n`(entityStatus=\"ENTITY_STATUS_ACTIVE\" OR\nentityStatus=\"ENTITY_STATUS_PAUSED\") AND\nlineItemType=\"LINE_ITEM_TYPE_DISPLAY_DEFAULT\"`\n\nThe length of this field should be no more than 500 characters.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "Field by which to sort the list.\nAcceptable values are:\n\n* \"displayName\" (default)\n* \"entityStatus\"\n\nThe default sorting order is ascending. To specify descending order for\na field, a suffix \"desc\" should be added to the field name. Example:\n`displayName desc`.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Must be between `1` and `100`. If unspecified will\ndefault to `100`. Returns error code `INVALID_ARGUMENT` if an invalid value\nis specified.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results the server should return.\nTypically, this is the value of\nnext_page_token\nreturned from the previous call to `ListLineItems` method.\nIf not specified, the first page of results will be returned.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/advertisers/{+advertiserId}/lineItems",
	//   "response": {
	//     "$ref": "ListLineItemsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/display-video"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AdvertisersLineItemsListCall) Pages(ctx context.Context, f func(*ListLineItemsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "displayvideo.advertisers.lineItems.patch":

type AdvertisersLineItemsPatchCall struct {
	s            *Service
	advertiserId int64
	lineItemId   int64
	lineitem     *LineItem
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Patch: Updates an existing line item.
// Returns the updated line item if successful.
func (r *AdvertisersLineItemsService) Patch(advertiserId int64, lineItemId int64, lineitem *LineItem) *AdvertisersLineItemsPatchCall {
	c := &AdvertisersLineItemsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.advertiserId = advertiserId
	c.lineItemId = lineItemId
	c.lineitem = lineitem
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields to update.
func (c *AdvertisersLineItemsPatchCall) UpdateMask(updateMask string) *AdvertisersLineItemsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

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

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

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

func (c *AdvertisersLineItemsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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/20200708")
	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)
	}
}
