// 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 dfareporting provides access to the DCM/DFA Reporting And Trafficking API.
//
// For product documentation, see: https://developers.google.com/doubleclick-advertisers/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/dfareporting/v3.4"
//   ...
//   ctx := context.Background()
//   dfareportingService, err := dfareporting.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:
//
//   dfareportingService, err := dfareporting.NewService(ctx, option.WithScopes(dfareporting.DfatraffickingScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   dfareportingService, err := dfareporting.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, ...)
//   dfareportingService, err := dfareporting.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package dfareporting // import "google.golang.org/api/dfareporting/v3.4"

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 = "dfareporting:v3.4"
const apiName = "dfareporting"
const apiVersion = "v3.4"
const basePath = "https://dfareporting.googleapis.com/dfareporting/v3.4/"
const mtlsBasePath = "https://dfareporting.mtls.googleapis.com/dfareporting/v3.4/"

// OAuth2 scopes used by this API.
const (
	// Manage DoubleClick Digital Marketing conversions
	DdmconversionsScope = "https://www.googleapis.com/auth/ddmconversions"

	// View and manage DoubleClick for Advertisers reports
	DfareportingScope = "https://www.googleapis.com/auth/dfareporting"

	// View and manage your DoubleClick Campaign Manager's (DCM) display ad
	// campaigns
	DfatraffickingScope = "https://www.googleapis.com/auth/dfatrafficking"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/ddmconversions",
		"https://www.googleapis.com/auth/dfareporting",
		"https://www.googleapis.com/auth/dfatrafficking",
	)
	// 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.AccountActiveAdSummaries = NewAccountActiveAdSummariesService(s)
	s.AccountPermissionGroups = NewAccountPermissionGroupsService(s)
	s.AccountPermissions = NewAccountPermissionsService(s)
	s.AccountUserProfiles = NewAccountUserProfilesService(s)
	s.Accounts = NewAccountsService(s)
	s.Ads = NewAdsService(s)
	s.AdvertiserGroups = NewAdvertiserGroupsService(s)
	s.AdvertiserLandingPages = NewAdvertiserLandingPagesService(s)
	s.Advertisers = NewAdvertisersService(s)
	s.Browsers = NewBrowsersService(s)
	s.CampaignCreativeAssociations = NewCampaignCreativeAssociationsService(s)
	s.Campaigns = NewCampaignsService(s)
	s.ChangeLogs = NewChangeLogsService(s)
	s.Cities = NewCitiesService(s)
	s.ConnectionTypes = NewConnectionTypesService(s)
	s.ContentCategories = NewContentCategoriesService(s)
	s.Conversions = NewConversionsService(s)
	s.Countries = NewCountriesService(s)
	s.CreativeAssets = NewCreativeAssetsService(s)
	s.CreativeFieldValues = NewCreativeFieldValuesService(s)
	s.CreativeFields = NewCreativeFieldsService(s)
	s.CreativeGroups = NewCreativeGroupsService(s)
	s.Creatives = NewCreativesService(s)
	s.CustomEvents = NewCustomEventsService(s)
	s.DimensionValues = NewDimensionValuesService(s)
	s.DirectorySites = NewDirectorySitesService(s)
	s.DynamicTargetingKeys = NewDynamicTargetingKeysService(s)
	s.EventTags = NewEventTagsService(s)
	s.Files = NewFilesService(s)
	s.FloodlightActivities = NewFloodlightActivitiesService(s)
	s.FloodlightActivityGroups = NewFloodlightActivityGroupsService(s)
	s.FloodlightConfigurations = NewFloodlightConfigurationsService(s)
	s.InventoryItems = NewInventoryItemsService(s)
	s.Languages = NewLanguagesService(s)
	s.Metros = NewMetrosService(s)
	s.MobileApps = NewMobileAppsService(s)
	s.MobileCarriers = NewMobileCarriersService(s)
	s.OperatingSystemVersions = NewOperatingSystemVersionsService(s)
	s.OperatingSystems = NewOperatingSystemsService(s)
	s.OrderDocuments = NewOrderDocumentsService(s)
	s.Orders = NewOrdersService(s)
	s.PlacementGroups = NewPlacementGroupsService(s)
	s.PlacementStrategies = NewPlacementStrategiesService(s)
	s.Placements = NewPlacementsService(s)
	s.PlatformTypes = NewPlatformTypesService(s)
	s.PostalCodes = NewPostalCodesService(s)
	s.Projects = NewProjectsService(s)
	s.Regions = NewRegionsService(s)
	s.RemarketingListShares = NewRemarketingListSharesService(s)
	s.RemarketingLists = NewRemarketingListsService(s)
	s.Reports = NewReportsService(s)
	s.Sites = NewSitesService(s)
	s.Sizes = NewSizesService(s)
	s.Subaccounts = NewSubaccountsService(s)
	s.TargetableRemarketingLists = NewTargetableRemarketingListsService(s)
	s.TargetingTemplates = NewTargetingTemplatesService(s)
	s.UserProfiles = NewUserProfilesService(s)
	s.UserRolePermissionGroups = NewUserRolePermissionGroupsService(s)
	s.UserRolePermissions = NewUserRolePermissionsService(s)
	s.UserRoles = NewUserRolesService(s)
	s.VideoFormats = NewVideoFormatsService(s)
	return s, nil
}

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

	AccountActiveAdSummaries *AccountActiveAdSummariesService

	AccountPermissionGroups *AccountPermissionGroupsService

	AccountPermissions *AccountPermissionsService

	AccountUserProfiles *AccountUserProfilesService

	Accounts *AccountsService

	Ads *AdsService

	AdvertiserGroups *AdvertiserGroupsService

	AdvertiserLandingPages *AdvertiserLandingPagesService

	Advertisers *AdvertisersService

	Browsers *BrowsersService

	CampaignCreativeAssociations *CampaignCreativeAssociationsService

	Campaigns *CampaignsService

	ChangeLogs *ChangeLogsService

	Cities *CitiesService

	ConnectionTypes *ConnectionTypesService

	ContentCategories *ContentCategoriesService

	Conversions *ConversionsService

	Countries *CountriesService

	CreativeAssets *CreativeAssetsService

	CreativeFieldValues *CreativeFieldValuesService

	CreativeFields *CreativeFieldsService

	CreativeGroups *CreativeGroupsService

	Creatives *CreativesService

	CustomEvents *CustomEventsService

	DimensionValues *DimensionValuesService

	DirectorySites *DirectorySitesService

	DynamicTargetingKeys *DynamicTargetingKeysService

	EventTags *EventTagsService

	Files *FilesService

	FloodlightActivities *FloodlightActivitiesService

	FloodlightActivityGroups *FloodlightActivityGroupsService

	FloodlightConfigurations *FloodlightConfigurationsService

	InventoryItems *InventoryItemsService

	Languages *LanguagesService

	Metros *MetrosService

	MobileApps *MobileAppsService

	MobileCarriers *MobileCarriersService

	OperatingSystemVersions *OperatingSystemVersionsService

	OperatingSystems *OperatingSystemsService

	OrderDocuments *OrderDocumentsService

	Orders *OrdersService

	PlacementGroups *PlacementGroupsService

	PlacementStrategies *PlacementStrategiesService

	Placements *PlacementsService

	PlatformTypes *PlatformTypesService

	PostalCodes *PostalCodesService

	Projects *ProjectsService

	Regions *RegionsService

	RemarketingListShares *RemarketingListSharesService

	RemarketingLists *RemarketingListsService

	Reports *ReportsService

	Sites *SitesService

	Sizes *SizesService

	Subaccounts *SubaccountsService

	TargetableRemarketingLists *TargetableRemarketingListsService

	TargetingTemplates *TargetingTemplatesService

	UserProfiles *UserProfilesService

	UserRolePermissionGroups *UserRolePermissionGroupsService

	UserRolePermissions *UserRolePermissionsService

	UserRoles *UserRolesService

	VideoFormats *VideoFormatsService
}

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

func NewAccountActiveAdSummariesService(s *Service) *AccountActiveAdSummariesService {
	rs := &AccountActiveAdSummariesService{s: s}
	return rs
}

type AccountActiveAdSummariesService struct {
	s *Service
}

func NewAccountPermissionGroupsService(s *Service) *AccountPermissionGroupsService {
	rs := &AccountPermissionGroupsService{s: s}
	return rs
}

type AccountPermissionGroupsService struct {
	s *Service
}

func NewAccountPermissionsService(s *Service) *AccountPermissionsService {
	rs := &AccountPermissionsService{s: s}
	return rs
}

type AccountPermissionsService struct {
	s *Service
}

func NewAccountUserProfilesService(s *Service) *AccountUserProfilesService {
	rs := &AccountUserProfilesService{s: s}
	return rs
}

type AccountUserProfilesService struct {
	s *Service
}

func NewAccountsService(s *Service) *AccountsService {
	rs := &AccountsService{s: s}
	return rs
}

type AccountsService struct {
	s *Service
}

func NewAdsService(s *Service) *AdsService {
	rs := &AdsService{s: s}
	return rs
}

type AdsService struct {
	s *Service
}

func NewAdvertiserGroupsService(s *Service) *AdvertiserGroupsService {
	rs := &AdvertiserGroupsService{s: s}
	return rs
}

type AdvertiserGroupsService struct {
	s *Service
}

func NewAdvertiserLandingPagesService(s *Service) *AdvertiserLandingPagesService {
	rs := &AdvertiserLandingPagesService{s: s}
	return rs
}

type AdvertiserLandingPagesService struct {
	s *Service
}

func NewAdvertisersService(s *Service) *AdvertisersService {
	rs := &AdvertisersService{s: s}
	return rs
}

type AdvertisersService struct {
	s *Service
}

func NewBrowsersService(s *Service) *BrowsersService {
	rs := &BrowsersService{s: s}
	return rs
}

type BrowsersService struct {
	s *Service
}

func NewCampaignCreativeAssociationsService(s *Service) *CampaignCreativeAssociationsService {
	rs := &CampaignCreativeAssociationsService{s: s}
	return rs
}

type CampaignCreativeAssociationsService struct {
	s *Service
}

func NewCampaignsService(s *Service) *CampaignsService {
	rs := &CampaignsService{s: s}
	return rs
}

type CampaignsService struct {
	s *Service
}

func NewChangeLogsService(s *Service) *ChangeLogsService {
	rs := &ChangeLogsService{s: s}
	return rs
}

type ChangeLogsService struct {
	s *Service
}

func NewCitiesService(s *Service) *CitiesService {
	rs := &CitiesService{s: s}
	return rs
}

type CitiesService struct {
	s *Service
}

func NewConnectionTypesService(s *Service) *ConnectionTypesService {
	rs := &ConnectionTypesService{s: s}
	return rs
}

type ConnectionTypesService struct {
	s *Service
}

func NewContentCategoriesService(s *Service) *ContentCategoriesService {
	rs := &ContentCategoriesService{s: s}
	return rs
}

type ContentCategoriesService struct {
	s *Service
}

func NewConversionsService(s *Service) *ConversionsService {
	rs := &ConversionsService{s: s}
	return rs
}

type ConversionsService struct {
	s *Service
}

func NewCountriesService(s *Service) *CountriesService {
	rs := &CountriesService{s: s}
	return rs
}

type CountriesService struct {
	s *Service
}

func NewCreativeAssetsService(s *Service) *CreativeAssetsService {
	rs := &CreativeAssetsService{s: s}
	return rs
}

type CreativeAssetsService struct {
	s *Service
}

func NewCreativeFieldValuesService(s *Service) *CreativeFieldValuesService {
	rs := &CreativeFieldValuesService{s: s}
	return rs
}

type CreativeFieldValuesService struct {
	s *Service
}

func NewCreativeFieldsService(s *Service) *CreativeFieldsService {
	rs := &CreativeFieldsService{s: s}
	return rs
}

type CreativeFieldsService struct {
	s *Service
}

func NewCreativeGroupsService(s *Service) *CreativeGroupsService {
	rs := &CreativeGroupsService{s: s}
	return rs
}

type CreativeGroupsService struct {
	s *Service
}

func NewCreativesService(s *Service) *CreativesService {
	rs := &CreativesService{s: s}
	return rs
}

type CreativesService struct {
	s *Service
}

func NewCustomEventsService(s *Service) *CustomEventsService {
	rs := &CustomEventsService{s: s}
	return rs
}

type CustomEventsService struct {
	s *Service
}

func NewDimensionValuesService(s *Service) *DimensionValuesService {
	rs := &DimensionValuesService{s: s}
	return rs
}

type DimensionValuesService struct {
	s *Service
}

func NewDirectorySitesService(s *Service) *DirectorySitesService {
	rs := &DirectorySitesService{s: s}
	return rs
}

type DirectorySitesService struct {
	s *Service
}

func NewDynamicTargetingKeysService(s *Service) *DynamicTargetingKeysService {
	rs := &DynamicTargetingKeysService{s: s}
	return rs
}

type DynamicTargetingKeysService struct {
	s *Service
}

func NewEventTagsService(s *Service) *EventTagsService {
	rs := &EventTagsService{s: s}
	return rs
}

type EventTagsService struct {
	s *Service
}

func NewFilesService(s *Service) *FilesService {
	rs := &FilesService{s: s}
	return rs
}

type FilesService struct {
	s *Service
}

func NewFloodlightActivitiesService(s *Service) *FloodlightActivitiesService {
	rs := &FloodlightActivitiesService{s: s}
	return rs
}

type FloodlightActivitiesService struct {
	s *Service
}

func NewFloodlightActivityGroupsService(s *Service) *FloodlightActivityGroupsService {
	rs := &FloodlightActivityGroupsService{s: s}
	return rs
}

type FloodlightActivityGroupsService struct {
	s *Service
}

func NewFloodlightConfigurationsService(s *Service) *FloodlightConfigurationsService {
	rs := &FloodlightConfigurationsService{s: s}
	return rs
}

type FloodlightConfigurationsService struct {
	s *Service
}

func NewInventoryItemsService(s *Service) *InventoryItemsService {
	rs := &InventoryItemsService{s: s}
	return rs
}

type InventoryItemsService struct {
	s *Service
}

func NewLanguagesService(s *Service) *LanguagesService {
	rs := &LanguagesService{s: s}
	return rs
}

type LanguagesService struct {
	s *Service
}

func NewMetrosService(s *Service) *MetrosService {
	rs := &MetrosService{s: s}
	return rs
}

type MetrosService struct {
	s *Service
}

func NewMobileAppsService(s *Service) *MobileAppsService {
	rs := &MobileAppsService{s: s}
	return rs
}

type MobileAppsService struct {
	s *Service
}

func NewMobileCarriersService(s *Service) *MobileCarriersService {
	rs := &MobileCarriersService{s: s}
	return rs
}

type MobileCarriersService struct {
	s *Service
}

func NewOperatingSystemVersionsService(s *Service) *OperatingSystemVersionsService {
	rs := &OperatingSystemVersionsService{s: s}
	return rs
}

type OperatingSystemVersionsService struct {
	s *Service
}

func NewOperatingSystemsService(s *Service) *OperatingSystemsService {
	rs := &OperatingSystemsService{s: s}
	return rs
}

type OperatingSystemsService struct {
	s *Service
}

func NewOrderDocumentsService(s *Service) *OrderDocumentsService {
	rs := &OrderDocumentsService{s: s}
	return rs
}

type OrderDocumentsService struct {
	s *Service
}

func NewOrdersService(s *Service) *OrdersService {
	rs := &OrdersService{s: s}
	return rs
}

type OrdersService struct {
	s *Service
}

func NewPlacementGroupsService(s *Service) *PlacementGroupsService {
	rs := &PlacementGroupsService{s: s}
	return rs
}

type PlacementGroupsService struct {
	s *Service
}

func NewPlacementStrategiesService(s *Service) *PlacementStrategiesService {
	rs := &PlacementStrategiesService{s: s}
	return rs
}

type PlacementStrategiesService struct {
	s *Service
}

func NewPlacementsService(s *Service) *PlacementsService {
	rs := &PlacementsService{s: s}
	return rs
}

type PlacementsService struct {
	s *Service
}

func NewPlatformTypesService(s *Service) *PlatformTypesService {
	rs := &PlatformTypesService{s: s}
	return rs
}

type PlatformTypesService struct {
	s *Service
}

func NewPostalCodesService(s *Service) *PostalCodesService {
	rs := &PostalCodesService{s: s}
	return rs
}

type PostalCodesService struct {
	s *Service
}

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	return rs
}

type ProjectsService struct {
	s *Service
}

func NewRegionsService(s *Service) *RegionsService {
	rs := &RegionsService{s: s}
	return rs
}

type RegionsService struct {
	s *Service
}

func NewRemarketingListSharesService(s *Service) *RemarketingListSharesService {
	rs := &RemarketingListSharesService{s: s}
	return rs
}

type RemarketingListSharesService struct {
	s *Service
}

func NewRemarketingListsService(s *Service) *RemarketingListsService {
	rs := &RemarketingListsService{s: s}
	return rs
}

type RemarketingListsService struct {
	s *Service
}

func NewReportsService(s *Service) *ReportsService {
	rs := &ReportsService{s: s}
	rs.CompatibleFields = NewReportsCompatibleFieldsService(s)
	rs.Files = NewReportsFilesService(s)
	return rs
}

type ReportsService struct {
	s *Service

	CompatibleFields *ReportsCompatibleFieldsService

	Files *ReportsFilesService
}

func NewReportsCompatibleFieldsService(s *Service) *ReportsCompatibleFieldsService {
	rs := &ReportsCompatibleFieldsService{s: s}
	return rs
}

type ReportsCompatibleFieldsService struct {
	s *Service
}

func NewReportsFilesService(s *Service) *ReportsFilesService {
	rs := &ReportsFilesService{s: s}
	return rs
}

type ReportsFilesService struct {
	s *Service
}

func NewSitesService(s *Service) *SitesService {
	rs := &SitesService{s: s}
	return rs
}

type SitesService struct {
	s *Service
}

func NewSizesService(s *Service) *SizesService {
	rs := &SizesService{s: s}
	return rs
}

type SizesService struct {
	s *Service
}

func NewSubaccountsService(s *Service) *SubaccountsService {
	rs := &SubaccountsService{s: s}
	return rs
}

type SubaccountsService struct {
	s *Service
}

func NewTargetableRemarketingListsService(s *Service) *TargetableRemarketingListsService {
	rs := &TargetableRemarketingListsService{s: s}
	return rs
}

type TargetableRemarketingListsService struct {
	s *Service
}

func NewTargetingTemplatesService(s *Service) *TargetingTemplatesService {
	rs := &TargetingTemplatesService{s: s}
	return rs
}

type TargetingTemplatesService struct {
	s *Service
}

func NewUserProfilesService(s *Service) *UserProfilesService {
	rs := &UserProfilesService{s: s}
	return rs
}

type UserProfilesService struct {
	s *Service
}

func NewUserRolePermissionGroupsService(s *Service) *UserRolePermissionGroupsService {
	rs := &UserRolePermissionGroupsService{s: s}
	return rs
}

type UserRolePermissionGroupsService struct {
	s *Service
}

func NewUserRolePermissionsService(s *Service) *UserRolePermissionsService {
	rs := &UserRolePermissionsService{s: s}
	return rs
}

type UserRolePermissionsService struct {
	s *Service
}

func NewUserRolesService(s *Service) *UserRolesService {
	rs := &UserRolesService{s: s}
	return rs
}

type UserRolesService struct {
	s *Service
}

func NewVideoFormatsService(s *Service) *VideoFormatsService {
	rs := &VideoFormatsService{s: s}
	return rs
}

type VideoFormatsService struct {
	s *Service
}

// Account: Contains properties of a Campaign Manager account.
type Account struct {
	// AccountPermissionIds: Account permissions assigned to this account.
	AccountPermissionIds googleapi.Int64s `json:"accountPermissionIds,omitempty"`

	// AccountProfile: Profile for this account. This is a read-only field
	// that can be left blank.
	//
	// Possible values:
	//   "ACCOUNT_PROFILE_BASIC"
	//   "ACCOUNT_PROFILE_STANDARD"
	AccountProfile string `json:"accountProfile,omitempty"`

	// Active: Whether this account is active.
	Active bool `json:"active,omitempty"`

	// ActiveAdsLimitTier: Maximum number of active ads allowed for this
	// account.
	//
	// Possible values:
	//   "ACTIVE_ADS_TIER_40K"
	//   "ACTIVE_ADS_TIER_75K"
	//   "ACTIVE_ADS_TIER_100K"
	//   "ACTIVE_ADS_TIER_200K"
	//   "ACTIVE_ADS_TIER_300K"
	//   "ACTIVE_ADS_TIER_500K"
	//   "ACTIVE_ADS_TIER_750K"
	//   "ACTIVE_ADS_TIER_1M"
	ActiveAdsLimitTier string `json:"activeAdsLimitTier,omitempty"`

	// ActiveViewOptOut: Whether to serve creatives with Active View tags.
	// If disabled, viewability data will not be available for any
	// impressions.
	ActiveViewOptOut bool `json:"activeViewOptOut,omitempty"`

	// AvailablePermissionIds: User role permissions available to the user
	// roles of this account.
	AvailablePermissionIds googleapi.Int64s `json:"availablePermissionIds,omitempty"`

	// CountryId: ID of the country associated with this account.
	CountryId int64 `json:"countryId,omitempty,string"`

	// CurrencyId: ID of currency associated with this account. This is a
	// required field. Acceptable values are: - "1" for USD - "2" for GBP -
	// "3" for ESP - "4" for SEK - "5" for CAD - "6" for JPY - "7" for DEM -
	// "8" for AUD - "9" for FRF - "10" for ITL - "11" for DKK - "12" for
	// NOK - "13" for FIM - "14" for ZAR - "15" for IEP - "16" for NLG -
	// "17" for EUR - "18" for KRW - "19" for TWD - "20" for SGD - "21" for
	// CNY - "22" for HKD - "23" for NZD - "24" for MYR - "25" for BRL -
	// "26" for PTE - "28" for CLP - "29" for TRY - "30" for ARS - "31" for
	// PEN - "32" for ILS - "33" for CHF - "34" for VEF - "35" for COP -
	// "36" for GTQ - "37" for PLN - "39" for INR - "40" for THB - "41" for
	// IDR - "42" for CZK - "43" for RON - "44" for HUF - "45" for RUB -
	// "46" for AED - "47" for BGN - "48" for HRK - "49" for MXN - "50" for
	// NGN - "51" for EGP
	CurrencyId int64 `json:"currencyId,omitempty,string"`

	// DefaultCreativeSizeId: Default placement dimensions for this account.
	DefaultCreativeSizeId int64 `json:"defaultCreativeSizeId,omitempty,string"`

	// Description: Description of this account.
	Description string `json:"description,omitempty"`

	// Id: ID of this account. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#account".
	Kind string `json:"kind,omitempty"`

	// Locale: Locale of this account. Acceptable values are: - "cs" (Czech)
	// - "de" (German) - "en" (English) - "en-GB" (English United Kingdom) -
	// "es" (Spanish) - "fr" (French) - "it" (Italian) - "ja" (Japanese) -
	// "ko" (Korean) - "pl" (Polish) - "pt-BR" (Portuguese Brazil) - "ru"
	// (Russian) - "sv" (Swedish) - "tr" (Turkish) - "zh-CN" (Chinese
	// Simplified) - "zh-TW" (Chinese Traditional)
	Locale string `json:"locale,omitempty"`

	// MaximumImageSize: Maximum image size allowed for this account, in
	// kilobytes. Value must be greater than or equal to 1.
	MaximumImageSize int64 `json:"maximumImageSize,omitempty,string"`

	// Name: Name of this account. This is a required field, and must be
	// less than 128 characters long and be globally unique.
	Name string `json:"name,omitempty"`

	// NielsenOcrEnabled: Whether campaigns created in this account will be
	// enabled for Nielsen OCR reach ratings by default.
	NielsenOcrEnabled bool `json:"nielsenOcrEnabled,omitempty"`

	// ReportsConfiguration: Reporting configuration of this account.
	ReportsConfiguration *ReportsConfiguration `json:"reportsConfiguration,omitempty"`

	// ShareReportsWithTwitter: Share Path to Conversion reports with
	// Twitter.
	ShareReportsWithTwitter bool `json:"shareReportsWithTwitter,omitempty"`

	// TeaserSizeLimit: File size limit in kilobytes of Rich Media teaser
	// creatives. Acceptable values are 1 to 10240, inclusive.
	TeaserSizeLimit int64 `json:"teaserSizeLimit,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.
	// "AccountPermissionIds") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// AccountActiveAdSummary: Gets a summary of active ads in an account.
type AccountActiveAdSummary struct {
	// AccountId: ID of the account.
	AccountId int64 `json:"accountId,omitempty,string"`

	// ActiveAds: Ads that have been activated for the account
	ActiveAds int64 `json:"activeAds,omitempty,string"`

	// ActiveAdsLimitTier: Maximum number of active ads allowed for the
	// account.
	//
	// Possible values:
	//   "ACTIVE_ADS_TIER_40K"
	//   "ACTIVE_ADS_TIER_75K"
	//   "ACTIVE_ADS_TIER_100K"
	//   "ACTIVE_ADS_TIER_200K"
	//   "ACTIVE_ADS_TIER_300K"
	//   "ACTIVE_ADS_TIER_500K"
	//   "ACTIVE_ADS_TIER_750K"
	//   "ACTIVE_ADS_TIER_1M"
	ActiveAdsLimitTier string `json:"activeAdsLimitTier,omitempty"`

	// AvailableAds: Ads that can be activated for the account.
	AvailableAds int64 `json:"availableAds,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountActiveAdSummary".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// AccountPermission: AccountPermissions contains information about a
// particular account permission. Some features of Campaign Manager
// require an account permission to be present in the account.
type AccountPermission struct {
	// AccountProfiles: Account profiles associated with this account
	// permission. Possible values are: - "ACCOUNT_PROFILE_BASIC" -
	// "ACCOUNT_PROFILE_STANDARD"
	//
	// Possible values:
	//   "ACCOUNT_PROFILE_BASIC"
	//   "ACCOUNT_PROFILE_STANDARD"
	AccountProfiles []string `json:"accountProfiles,omitempty"`

	// Id: ID of this account permission.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountPermission".
	Kind string `json:"kind,omitempty"`

	// Level: Administrative level required to enable this account
	// permission.
	//
	// Possible values:
	//   "USER"
	//   "ADMINISTRATOR"
	Level string `json:"level,omitempty"`

	// Name: Name of this account permission.
	Name string `json:"name,omitempty"`

	// PermissionGroupId: Permission group of this account permission.
	PermissionGroupId int64 `json:"permissionGroupId,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. "AccountProfiles") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// AccountPermissionGroup: AccountPermissionGroups contains a mapping of
// permission group IDs to names. A permission group is a grouping of
// account permissions.
type AccountPermissionGroup struct {
	// Id: ID of this account permission group.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountPermissionGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this account permission 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. "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 *AccountPermissionGroup) MarshalJSON() ([]byte, error) {
	type NoMethod AccountPermissionGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AccountPermissionGroupsListResponse: Account Permission Group List
// Response
type AccountPermissionGroupsListResponse struct {
	// AccountPermissionGroups: Account permission group collection.
	AccountPermissionGroups []*AccountPermissionGroup `json:"accountPermissionGroups,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountPermissionGroupsListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// AccountPermissionsListResponse: Account Permission List Response
type AccountPermissionsListResponse struct {
	// AccountPermissions: Account permission collection.
	AccountPermissions []*AccountPermission `json:"accountPermissions,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountPermissionsListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// AccountUserProfile: AccountUserProfiles contains properties of a
// Campaign Manager user profile. This resource is specifically for
// managing user profiles, whereas UserProfiles is for accessing the
// API.
type AccountUserProfile struct {
	// AccountId: Account ID of the user profile. This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether this user profile is active. This defaults to false,
	// and must be set true on insert for the user profile to be usable.
	Active bool `json:"active,omitempty"`

	// AdvertiserFilter: Filter that describes which advertisers are visible
	// to the user profile.
	AdvertiserFilter *ObjectFilter `json:"advertiserFilter,omitempty"`

	// CampaignFilter: Filter that describes which campaigns are visible to
	// the user profile.
	CampaignFilter *ObjectFilter `json:"campaignFilter,omitempty"`

	// Comments: Comments for this user profile.
	Comments string `json:"comments,omitempty"`

	// Email: Email of the user profile. The email addresss must be linked
	// to a Google Account. This field is required on insertion and is
	// read-only after insertion.
	Email string `json:"email,omitempty"`

	// Id: ID of the user profile. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountUserProfile".
	Kind string `json:"kind,omitempty"`

	// Locale: Locale of the user profile. This is a required field.
	// Acceptable values are: - "cs" (Czech) - "de" (German) - "en"
	// (English) - "en-GB" (English United Kingdom) - "es" (Spanish) - "fr"
	// (French) - "it" (Italian) - "ja" (Japanese) - "ko" (Korean) - "pl"
	// (Polish) - "pt-BR" (Portuguese Brazil) - "ru" (Russian) - "sv"
	// (Swedish) - "tr" (Turkish) - "zh-CN" (Chinese Simplified) - "zh-TW"
	// (Chinese Traditional)
	Locale string `json:"locale,omitempty"`

	// Name: Name of the user profile. This is a required field. Must be
	// less than 64 characters long, must be globally unique, and cannot
	// contain whitespace or any of the following characters: "&;<>"#%,".
	Name string `json:"name,omitempty"`

	// SiteFilter: Filter that describes which sites are visible to the user
	// profile.
	SiteFilter *ObjectFilter `json:"siteFilter,omitempty"`

	// SubaccountId: Subaccount ID of the user profile. This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TraffickerType: Trafficker type of this user profile. This is a
	// read-only field.
	//
	// Possible values:
	//   "INTERNAL_NON_TRAFFICKER"
	//   "INTERNAL_TRAFFICKER"
	//   "EXTERNAL_TRAFFICKER"
	TraffickerType string `json:"traffickerType,omitempty"`

	// UserAccessType: User type of the user profile. This is a read-only
	// field that can be left blank.
	//
	// Possible values:
	//   "NORMAL_USER"
	//   "SUPER_USER"
	//   "INTERNAL_ADMINISTRATOR"
	//   "READ_ONLY_SUPER_USER"
	UserAccessType string `json:"userAccessType,omitempty"`

	// UserRoleFilter: Filter that describes which user roles are visible to
	// the user profile.
	UserRoleFilter *ObjectFilter `json:"userRoleFilter,omitempty"`

	// UserRoleId: User role ID of the user profile. This is a required
	// field.
	UserRoleId int64 `json:"userRoleId,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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// AccountUserProfilesListResponse: Account User Profile List Response
type AccountUserProfilesListResponse struct {
	// AccountUserProfiles: Account user profile collection.
	AccountUserProfiles []*AccountUserProfile `json:"accountUserProfiles,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountUserProfilesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "AccountUserProfiles")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// AccountsListResponse: Account List Response
type AccountsListResponse struct {
	// Accounts: Account collection.
	Accounts []*Account `json:"accounts,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "Accounts") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// Activities: Represents an activity group.
type Activities struct {
	// Filters: List of activity filters. The dimension values need to be
	// all either of type "dfa:activity" or "dfa:activityGroup".
	Filters []*DimensionValue `json:"filters,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#activities.
	Kind string `json:"kind,omitempty"`

	// MetricNames: List of names of floodlight activity metrics.
	MetricNames []string `json:"metricNames,omitempty"`

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

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

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

// Ad: Contains properties of a Campaign Manager ad.
type Ad struct {
	// AccountId: Account ID of this ad. This is a read-only field that can
	// be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether this ad is active. When true, archived must be false.
	Active bool `json:"active,omitempty"`

	// AdvertiserId: Advertiser ID of this ad. This is a required field on
	// insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Archived: Whether this ad is archived. When true, active must be
	// false.
	Archived bool `json:"archived,omitempty"`

	// AudienceSegmentId: Audience segment ID that is being targeted for
	// this ad. Applicable when type is AD_SERVING_STANDARD_AD.
	AudienceSegmentId int64 `json:"audienceSegmentId,omitempty,string"`

	// CampaignId: Campaign ID of this ad. This is a required field on
	// insertion.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CampaignIdDimensionValue: Dimension value for the ID of the campaign.
	// This is a read-only, auto-generated field.
	CampaignIdDimensionValue *DimensionValue `json:"campaignIdDimensionValue,omitempty"`

	// ClickThroughUrl: Click-through URL for this ad. This is a required
	// field on insertion. Applicable when type is AD_SERVING_CLICK_TRACKER.
	ClickThroughUrl *ClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// ClickThroughUrlSuffixProperties: Click-through URL suffix properties
	// for this ad. Applies to the URL in the ad or (if overriding ad
	// properties) the URL in the creative.
	ClickThroughUrlSuffixProperties *ClickThroughUrlSuffixProperties `json:"clickThroughUrlSuffixProperties,omitempty"`

	// Comments: Comments for this ad.
	Comments string `json:"comments,omitempty"`

	// Compatibility: Compatibility of this ad. Applicable when type is
	// AD_SERVING_DEFAULT_AD. DISPLAY and DISPLAY_INTERSTITIAL refer to
	// either rendering on desktop or on mobile devices or in mobile apps
	// for regular or interstitial ads, respectively. APP and
	// APP_INTERSTITIAL are only used for existing default ads. New mobile
	// placements must be assigned DISPLAY or DISPLAY_INTERSTITIAL and
	// default ads created for those placements will be limited to those
	// compatibility types. IN_STREAM_VIDEO refers to rendering in-stream
	// video ads developed with the VAST standard.
	//
	// Possible values:
	//   "DISPLAY"
	//   "DISPLAY_INTERSTITIAL"
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	//   "IN_STREAM_AUDIO"
	Compatibility string `json:"compatibility,omitempty"`

	// CreateInfo: Information about the creation of this ad. This is a
	// read-only field.
	CreateInfo *LastModifiedInfo `json:"createInfo,omitempty"`

	// CreativeGroupAssignments: Creative group assignments for this ad.
	// Applicable when type is AD_SERVING_CLICK_TRACKER. Only one assignment
	// per creative group number is allowed for a maximum of two
	// assignments.
	CreativeGroupAssignments []*CreativeGroupAssignment `json:"creativeGroupAssignments,omitempty"`

	// CreativeRotation: Creative rotation for this ad. Applicable when type
	// is AD_SERVING_DEFAULT_AD, AD_SERVING_STANDARD_AD, or
	// AD_SERVING_TRACKING. When type is AD_SERVING_DEFAULT_AD, this field
	// should have exactly one creativeAssignment .
	CreativeRotation *CreativeRotation `json:"creativeRotation,omitempty"`

	// DayPartTargeting: Time and day targeting information for this ad.
	// This field must be left blank if the ad is using a targeting
	// template. Applicable when type is AD_SERVING_STANDARD_AD.
	DayPartTargeting *DayPartTargeting `json:"dayPartTargeting,omitempty"`

	// DefaultClickThroughEventTagProperties: Default click-through event
	// tag properties for this ad.
	DefaultClickThroughEventTagProperties *DefaultClickThroughEventTagProperties `json:"defaultClickThroughEventTagProperties,omitempty"`

	// DeliverySchedule: Delivery schedule information for this ad.
	// Applicable when type is AD_SERVING_STANDARD_AD or
	// AD_SERVING_TRACKING. This field along with subfields priority and
	// impressionRatio are required on insertion when type is
	// AD_SERVING_STANDARD_AD.
	DeliverySchedule *DeliverySchedule `json:"deliverySchedule,omitempty"`

	// DynamicClickTracker: Whether this ad is a dynamic click tracker.
	// Applicable when type is AD_SERVING_CLICK_TRACKER. This is a required
	// field on insert, and is read-only after insert.
	DynamicClickTracker bool `json:"dynamicClickTracker,omitempty"`

	EndTime string `json:"endTime,omitempty"`

	// EventTagOverrides: Event tag overrides for this ad.
	EventTagOverrides []*EventTagOverride `json:"eventTagOverrides,omitempty"`

	// GeoTargeting: Geographical targeting information for this ad. This
	// field must be left blank if the ad is using a targeting template.
	// Applicable when type is AD_SERVING_STANDARD_AD.
	GeoTargeting *GeoTargeting `json:"geoTargeting,omitempty"`

	// Id: ID of this ad. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this ad. This is a
	// read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// KeyValueTargetingExpression: Key-value targeting information for this
	// ad. This field must be left blank if the ad is using a targeting
	// template. Applicable when type is AD_SERVING_STANDARD_AD.
	KeyValueTargetingExpression *KeyValueTargetingExpression `json:"keyValueTargetingExpression,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#ad".
	Kind string `json:"kind,omitempty"`

	// LanguageTargeting: Language targeting information for this ad. This
	// field must be left blank if the ad is using a targeting template.
	// Applicable when type is AD_SERVING_STANDARD_AD.
	LanguageTargeting *LanguageTargeting `json:"languageTargeting,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this ad. This is a read-only field.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this ad. This is a required field and must be less than
	// 256 characters long.
	Name string `json:"name,omitempty"`

	// PlacementAssignments: Placement assignments for this ad.
	PlacementAssignments []*PlacementAssignment `json:"placementAssignments,omitempty"`

	// RemarketingListExpression: Remarketing list targeting expression for
	// this ad. This field must be left blank if the ad is using a targeting
	// template. Applicable when type is AD_SERVING_STANDARD_AD.
	RemarketingListExpression *ListTargetingExpression `json:"remarketingListExpression,omitempty"`

	// Size: Size of this ad. Applicable when type is AD_SERVING_DEFAULT_AD.
	Size *Size `json:"size,omitempty"`

	// SslCompliant: Whether this ad is ssl compliant. This is a read-only
	// field that is auto-generated when the ad is inserted or updated.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// SslRequired: Whether this ad requires ssl. This is a read-only field
	// that is auto-generated when the ad is inserted or updated.
	SslRequired bool `json:"sslRequired,omitempty"`

	StartTime string `json:"startTime,omitempty"`

	// SubaccountId: Subaccount ID of this ad. This is a read-only field
	// that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TargetingTemplateId: Targeting template ID, used to apply
	// preconfigured targeting information to this ad. This cannot be set
	// while any of dayPartTargeting, geoTargeting,
	// keyValueTargetingExpression, languageTargeting,
	// remarketingListExpression, or technologyTargeting are set. Applicable
	// when type is AD_SERVING_STANDARD_AD.
	TargetingTemplateId int64 `json:"targetingTemplateId,omitempty,string"`

	// TechnologyTargeting: Technology platform targeting information for
	// this ad. This field must be left blank if the ad is using a targeting
	// template. Applicable when type is AD_SERVING_STANDARD_AD.
	TechnologyTargeting *TechnologyTargeting `json:"technologyTargeting,omitempty"`

	// Type: Type of ad. This is a required field on insertion. Note that
	// default ads ( AD_SERVING_DEFAULT_AD) cannot be created directly (see
	// Creative resource).
	//
	// Possible values:
	//   "AD_SERVING_STANDARD_AD"
	//   "AD_SERVING_DEFAULT_AD"
	//   "AD_SERVING_CLICK_TRACKER"
	//   "AD_SERVING_TRACKING"
	Type string `json:"type,omitempty"`

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

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

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

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

// AdBlockingConfiguration: Campaign ad blocking settings.
type AdBlockingConfiguration struct {
	// ClickThroughUrl: Click-through URL used by brand-neutral ads. This is
	// a required field when overrideClickThroughUrl is set to true.
	ClickThroughUrl string `json:"clickThroughUrl,omitempty"`

	// CreativeBundleId: ID of a creative bundle to use for this campaign.
	// If set, brand-neutral ads will select creatives from this bundle.
	// Otherwise, a default transparent pixel will be used.
	CreativeBundleId int64 `json:"creativeBundleId,omitempty,string"`

	// Enabled: Whether this campaign has enabled ad blocking. When true, ad
	// blocking is enabled for placements in the campaign, but this may be
	// overridden by site and placement settings. When false, ad blocking is
	// disabled for all placements under the campaign, regardless of site
	// and placement settings.
	Enabled bool `json:"enabled,omitempty"`

	// OverrideClickThroughUrl: Whether the brand-neutral ad's click-through
	// URL comes from the campaign's creative bundle or the override URL.
	// Must be set to true if ad blocking is enabled and no creative bundle
	// is configured.
	OverrideClickThroughUrl bool `json:"overrideClickThroughUrl,omitempty"`

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

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

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

// AdSlot: Ad Slot
type AdSlot struct {
	// Comment: Comment for this ad slot.
	Comment string `json:"comment,omitempty"`

	// Compatibility: Ad slot compatibility. DISPLAY and
	// DISPLAY_INTERSTITIAL refer to rendering either on desktop, mobile
	// devices or in mobile apps for regular or interstitial ads
	// respectively. APP and APP_INTERSTITIAL are for rendering in mobile
	// apps. IN_STREAM_VIDEO refers to rendering in in-stream video ads
	// developed with the VAST standard.
	//
	// Possible values:
	//   "DISPLAY"
	//   "DISPLAY_INTERSTITIAL"
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	//   "IN_STREAM_AUDIO"
	Compatibility string `json:"compatibility,omitempty"`

	// Height: Height of this ad slot.
	Height int64 `json:"height,omitempty,string"`

	// LinkedPlacementId: ID of the placement from an external platform that
	// is linked to this ad slot.
	LinkedPlacementId int64 `json:"linkedPlacementId,omitempty,string"`

	// Name: Name of this ad slot.
	Name string `json:"name,omitempty"`

	// PaymentSourceType: Payment source type of this ad slot.
	//
	// Possible values:
	//   "PLANNING_PAYMENT_SOURCE_TYPE_AGENCY_PAID"
	//   "PLANNING_PAYMENT_SOURCE_TYPE_PUBLISHER_PAID"
	PaymentSourceType string `json:"paymentSourceType,omitempty"`

	// Primary: Primary ad slot of a roadblock inventory item.
	Primary bool `json:"primary,omitempty"`

	// Width: Width of this ad slot.
	Width int64 `json:"width,omitempty,string"`

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

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

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

// AdsListResponse: Ad List Response
type AdsListResponse struct {
	// Ads: Ad collection.
	Ads []*Ad `json:"ads,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#adsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "Ads") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// Advertiser: Contains properties of a Campaign Manager advertiser.
type Advertiser struct {
	// AccountId: Account ID of this advertiser.This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserGroupId: ID of the advertiser group this advertiser belongs
	// to. You can group advertisers for reporting purposes, allowing you to
	// see aggregated information for all advertisers in each group.
	AdvertiserGroupId int64 `json:"advertiserGroupId,omitempty,string"`

	// ClickThroughUrlSuffix: Suffix added to click-through URL of ad
	// creative associations under this advertiser. Must be less than 129
	// characters long.
	ClickThroughUrlSuffix string `json:"clickThroughUrlSuffix,omitempty"`

	// DefaultClickThroughEventTagId: ID of the click-through event tag to
	// apply by default to the landing pages of this advertiser's campaigns.
	DefaultClickThroughEventTagId int64 `json:"defaultClickThroughEventTagId,omitempty,string"`

	// DefaultEmail: Default email address used in sender field for tag
	// emails.
	DefaultEmail string `json:"defaultEmail,omitempty"`

	// FloodlightConfigurationId: Floodlight configuration ID of this
	// advertiser. The floodlight configuration ID will be created
	// automatically, so on insert this field should be left blank. This
	// field can be set to another advertiser's floodlight configuration ID
	// in order to share that advertiser's floodlight configuration with
	// this advertiser, so long as: - This advertiser's original floodlight
	// configuration is not already associated with floodlight activities or
	// floodlight activity groups. - This advertiser's original floodlight
	// configuration is not already shared with another advertiser.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

	// FloodlightConfigurationIdDimensionValue: Dimension value for the ID
	// of the floodlight configuration. This is a read-only, auto-generated
	// field.
	FloodlightConfigurationIdDimensionValue *DimensionValue `json:"floodlightConfigurationIdDimensionValue,omitempty"`

	// Id: ID of this advertiser. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this advertiser. This
	// is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertiser".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this advertiser. This is a required field and must be
	// less than 256 characters long and unique among advertisers of the
	// same account.
	Name string `json:"name,omitempty"`

	// OriginalFloodlightConfigurationId: Original floodlight configuration
	// before any sharing occurred. Set the floodlightConfigurationId of
	// this advertiser to originalFloodlightConfigurationId to unshare the
	// advertiser's current floodlight configuration. You cannot unshare an
	// advertiser's floodlight configuration if the shared configuration has
	// activities associated with any campaign or placement.
	OriginalFloodlightConfigurationId int64 `json:"originalFloodlightConfigurationId,omitempty,string"`

	// Status: Status of this advertiser.
	//
	// Possible values:
	//   "APPROVED"
	//   "ON_HOLD"
	Status string `json:"status,omitempty"`

	// SubaccountId: Subaccount ID of this advertiser.This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// Suspended: Suspension status of this advertiser.
	Suspended bool `json:"suspended,omitempty"`

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

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

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

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

// AdvertiserGroup: Groups advertisers together so that reports can be
// generated for the entire group at once.
type AdvertiserGroup struct {
	// AccountId: Account ID of this advertiser group. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Id: ID of this advertiser group. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertiserGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this advertiser group. This is a required field and
	// must be less than 256 characters long and unique among advertiser
	// groups of the same account.
	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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// AdvertiserGroupsListResponse: Advertiser Group List Response
type AdvertiserGroupsListResponse struct {
	// AdvertiserGroups: Advertiser group collection.
	AdvertiserGroups []*AdvertiserGroup `json:"advertiserGroups,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertiserGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "AdvertiserGroups") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// AdvertiserLandingPagesListResponse: Landing Page List Response
type AdvertiserLandingPagesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertiserLandingPagesListResponse".
	Kind string `json:"kind,omitempty"`

	// LandingPages: Landing page collection
	LandingPages []*LandingPage `json:"landingPages,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// AdvertisersListResponse: Advertiser List Response
type AdvertisersListResponse struct {
	// Advertisers: Advertiser collection.
	Advertisers []*Advertiser `json:"advertisers,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertisersListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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 *AdvertisersListResponse) MarshalJSON() ([]byte, error) {
	type NoMethod AdvertisersListResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AudienceSegment: Audience Segment.
type AudienceSegment struct {
	// Allocation: Weight allocated to this segment. The weight assigned
	// will be understood in proportion to the weights assigned to other
	// segments in the same segment group. Acceptable values are 1 to 1000,
	// inclusive.
	Allocation int64 `json:"allocation,omitempty"`

	// Id: ID of this audience segment. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of this audience segment. This is a required field and
	// must be less than 65 characters long.
	Name string `json:"name,omitempty"`

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

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

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

// AudienceSegmentGroup: Audience Segment Group.
type AudienceSegmentGroup struct {
	// AudienceSegments: Audience segments assigned to this group. The
	// number of segments must be between 2 and 100.
	AudienceSegments []*AudienceSegment `json:"audienceSegments,omitempty"`

	// Id: ID of this audience segment group. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of this audience segment group. This is a required field
	// and must be less than 65 characters long.
	Name string `json:"name,omitempty"`

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

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

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

// Browser: Contains information about a browser that can be targeted by
// ads.
type Browser struct {
	// BrowserVersionId: ID referring to this grouping of browser and
	// version numbers. This is the ID used for targeting.
	BrowserVersionId int64 `json:"browserVersionId,omitempty,string"`

	// DartId: DART ID of this browser. This is the ID used when generating
	// reports.
	DartId int64 `json:"dartId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#browser".
	Kind string `json:"kind,omitempty"`

	// MajorVersion: Major version number (leftmost number) of this browser.
	// For example, for Chrome 5.0.376.86 beta, this field should be set to
	// 5. An asterisk (*) may be used to target any version number, and a
	// question mark (?) may be used to target cases where the version
	// number cannot be identified. For example, Chrome *.* targets any
	// version of Chrome: 1.2, 2.5, 3.5, and so on. Chrome 3.* targets
	// Chrome 3.1, 3.5, but not 4.0. Firefox ?.? targets cases where the ad
	// server knows the browser is Firefox but can't tell which version it
	// is.
	MajorVersion string `json:"majorVersion,omitempty"`

	// MinorVersion: Minor version number (number after first dot on left)
	// of this browser. For example, for Chrome 5.0.375.86 beta, this field
	// should be set to 0. An asterisk (*) may be used to target any version
	// number, and a question mark (?) may be used to target cases where the
	// version number cannot be identified. For example, Chrome *.* targets
	// any version of Chrome: 1.2, 2.5, 3.5, and so on. Chrome 3.* targets
	// Chrome 3.1, 3.5, but not 4.0. Firefox ?.? targets cases where the ad
	// server knows the browser is Firefox but can't tell which version it
	// is.
	MinorVersion string `json:"minorVersion,omitempty"`

	// Name: Name of this browser.
	Name string `json:"name,omitempty"`

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

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

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

// BrowsersListResponse: Browser List Response
type BrowsersListResponse struct {
	// Browsers: Browser collection.
	Browsers []*Browser `json:"browsers,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#browsersListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// Campaign: Contains properties of a Campaign Manager campaign.
type Campaign struct {
	// AccountId: Account ID of this campaign. This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdBlockingConfiguration: Ad blocking settings for this campaign.
	AdBlockingConfiguration *AdBlockingConfiguration `json:"adBlockingConfiguration,omitempty"`

	// AdditionalCreativeOptimizationConfigurations: Additional creative
	// optimization configurations for the campaign.
	AdditionalCreativeOptimizationConfigurations []*CreativeOptimizationConfiguration `json:"additionalCreativeOptimizationConfigurations,omitempty"`

	// AdvertiserGroupId: Advertiser group ID of the associated advertiser.
	AdvertiserGroupId int64 `json:"advertiserGroupId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this campaign. This is a required
	// field.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the advertiser ID of
	// this campaign. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Archived: Whether this campaign has been archived.
	Archived bool `json:"archived,omitempty"`

	// AudienceSegmentGroups: Audience segment groups assigned to this
	// campaign. Cannot have more than 300 segment groups.
	AudienceSegmentGroups []*AudienceSegmentGroup `json:"audienceSegmentGroups,omitempty"`

	// BillingInvoiceCode: Billing invoice code included in the Campaign
	// Manager client billing invoices associated with the campaign.
	BillingInvoiceCode string `json:"billingInvoiceCode,omitempty"`

	// ClickThroughUrlSuffixProperties: Click-through URL suffix override
	// properties for this campaign.
	ClickThroughUrlSuffixProperties *ClickThroughUrlSuffixProperties `json:"clickThroughUrlSuffixProperties,omitempty"`

	// Comment: Arbitrary comments about this campaign. Must be less than
	// 256 characters long.
	Comment string `json:"comment,omitempty"`

	// CreateInfo: Information about the creation of this campaign. This is
	// a read-only field.
	CreateInfo *LastModifiedInfo `json:"createInfo,omitempty"`

	// CreativeGroupIds: List of creative group IDs that are assigned to the
	// campaign.
	CreativeGroupIds googleapi.Int64s `json:"creativeGroupIds,omitempty"`

	// CreativeOptimizationConfiguration: Creative optimization
	// configuration for the campaign.
	CreativeOptimizationConfiguration *CreativeOptimizationConfiguration `json:"creativeOptimizationConfiguration,omitempty"`

	// DefaultClickThroughEventTagProperties: Click-through event tag ID
	// override properties for this campaign.
	DefaultClickThroughEventTagProperties *DefaultClickThroughEventTagProperties `json:"defaultClickThroughEventTagProperties,omitempty"`

	// DefaultLandingPageId: The default landing page ID for this campaign.
	DefaultLandingPageId int64 `json:"defaultLandingPageId,omitempty,string"`

	EndDate string `json:"endDate,omitempty"`

	// EventTagOverrides: Overrides that can be used to activate or
	// deactivate advertiser event tags.
	EventTagOverrides []*EventTagOverride `json:"eventTagOverrides,omitempty"`

	// ExternalId: External ID for this campaign.
	ExternalId string `json:"externalId,omitempty"`

	// Id: ID of this campaign. This is a read-only auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this campaign. This
	// is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaign".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this campaign. This is a read-only field.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this campaign. This is a required field and must be
	// less than 256 characters long and unique among campaigns of the same
	// advertiser.
	Name string `json:"name,omitempty"`

	// NielsenOcrEnabled: Whether Nielsen reports are enabled for this
	// campaign.
	NielsenOcrEnabled bool `json:"nielsenOcrEnabled,omitempty"`

	StartDate string `json:"startDate,omitempty"`

	// SubaccountId: Subaccount ID of this campaign. This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TraffickerEmails: Campaign trafficker contact emails.
	TraffickerEmails []string `json:"traffickerEmails,omitempty"`

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

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

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

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

// CampaignCreativeAssociation: Identifies a creative which has been
// associated with a given campaign.
type CampaignCreativeAssociation struct {
	// CreativeId: ID of the creative associated with the campaign. This is
	// a required field.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaignCreativeAssociation".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// CampaignCreativeAssociationsListResponse: Campaign Creative
// Association List Response
type CampaignCreativeAssociationsListResponse struct {
	// CampaignCreativeAssociations: Campaign creative association
	// collection
	CampaignCreativeAssociations []*CampaignCreativeAssociation `json:"campaignCreativeAssociations,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaignCreativeAssociationsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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.
	// "CampaignCreativeAssociations") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// CampaignManagerIds: Campaign Manager IDs related to the custom event.
type CampaignManagerIds struct {
	// AdId: Ad ID for Campaign Manager.
	AdId int64 `json:"adId,omitempty,string"`

	// CampaignId: Campaign ID for Campaign Manager.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CreativeId: Creative ID for Campaign Manager.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaignManagerIds".
	Kind string `json:"kind,omitempty"`

	// PlacementId: Placement ID for Campaign Manager.
	PlacementId int64 `json:"placementId,omitempty,string"`

	// SiteId: Site ID for Campaign Manager.
	SiteId int64 `json:"siteId,omitempty,string"`

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

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

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

// CampaignsListResponse: Campaign List Response
type CampaignsListResponse struct {
	// Campaigns: Campaign collection.
	Campaigns []*Campaign `json:"campaigns,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaignsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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 *CampaignsListResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CampaignsListResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ChangeLog: Describes a change that a user has made to a resource.
type ChangeLog struct {
	// AccountId: Account ID of the modified object.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Action: Action which caused the change.
	Action string `json:"action,omitempty"`

	ChangeTime string `json:"changeTime,omitempty"`

	// FieldName: Field name of the object which changed.
	FieldName string `json:"fieldName,omitempty"`

	// Id: ID of this change log.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#changeLog".
	Kind string `json:"kind,omitempty"`

	// NewValue: New value of the object field.
	NewValue string `json:"newValue,omitempty"`

	// ObjectId: ID of the object of this change log. The object could be a
	// campaign, placement, ad, or other type.
	ObjectId int64 `json:"objectId,omitempty,string"`

	// ObjectType: Object type of the change log.
	ObjectType string `json:"objectType,omitempty"`

	// OldValue: Old value of the object field.
	OldValue string `json:"oldValue,omitempty"`

	// SubaccountId: Subaccount ID of the modified object.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TransactionId: Transaction ID of this change log. When a single API
	// call results in many changes, each change will have a separate ID in
	// the change log but will share the same transactionId.
	TransactionId int64 `json:"transactionId,omitempty,string"`

	// UserProfileId: ID of the user who modified the object.
	UserProfileId int64 `json:"userProfileId,omitempty,string"`

	// UserProfileName: User profile name of the user who modified the
	// object.
	UserProfileName string `json:"userProfileName,omitempty"`

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

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

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

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

// ChangeLogsListResponse: Change Log List Response
type ChangeLogsListResponse struct {
	// ChangeLogs: Change log collection.
	ChangeLogs []*ChangeLog `json:"changeLogs,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#changeLogsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "ChangeLogs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// ChannelGrouping: Represents a DfaReporting channel grouping.
type ChannelGrouping struct {
	// FallbackName: ChannelGrouping fallback name.
	FallbackName string `json:"fallbackName,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#channelGrouping.
	Kind string `json:"kind,omitempty"`

	// Name: ChannelGrouping name.
	Name string `json:"name,omitempty"`

	// Rules: The rules contained within this channel grouping.
	Rules []*ChannelGroupingRule `json:"rules,omitempty"`

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

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

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

// ChannelGroupingRule: Represents a DfaReporting channel grouping rule.
type ChannelGroupingRule struct {
	// DisjunctiveMatchStatements: The disjunctive match statements
	// contained within this rule.
	DisjunctiveMatchStatements []*DisjunctiveMatchStatement `json:"disjunctiveMatchStatements,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#channelGroupingRule.
	Kind string `json:"kind,omitempty"`

	// Name: Rule name.
	Name string `json:"name,omitempty"`

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

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

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

// CitiesListResponse: City List Response
type CitiesListResponse struct {
	// Cities: City collection.
	Cities []*City `json:"cities,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#citiesListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// City: Contains information about a city that can be targeted by ads.
type City struct {
	// CountryCode: Country code of the country to which this city belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this city belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// DartId: DART ID of this city. This is the ID used for targeting and
	// generating reports.
	DartId int64 `json:"dartId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#city".
	Kind string `json:"kind,omitempty"`

	// MetroCode: Metro region code of the metro region (DMA) to which this
	// city belongs.
	MetroCode string `json:"metroCode,omitempty"`

	// MetroDmaId: ID of the metro region (DMA) to which this city belongs.
	MetroDmaId int64 `json:"metroDmaId,omitempty,string"`

	// Name: Name of this city.
	Name string `json:"name,omitempty"`

	// RegionCode: Region code of the region to which this city belongs.
	RegionCode string `json:"regionCode,omitempty"`

	// RegionDartId: DART ID of the region to which this city belongs.
	RegionDartId int64 `json:"regionDartId,omitempty,string"`

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

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

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

// ClickTag: Creative Click Tag.
type ClickTag struct {
	// ClickThroughUrl: Parameter value for the specified click tag. This
	// field contains a click-through url.
	ClickThroughUrl *CreativeClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// EventName: Advertiser event name associated with the click tag. This
	// field is used by DISPLAY_IMAGE_GALLERY and HTML5_BANNER creatives.
	// Applicable to DISPLAY when the primary asset type is not HTML_IMAGE.
	EventName string `json:"eventName,omitempty"`

	// Name: Parameter name for the specified click tag. For
	// DISPLAY_IMAGE_GALLERY creative assets, this field must match the
	// value of the creative asset's creativeAssetId.name field.
	Name string `json:"name,omitempty"`

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

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

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

// ClickThroughUrl: Click-through URL
type ClickThroughUrl struct {
	// ComputedClickThroughUrl: Read-only convenience field representing the
	// actual URL that will be used for this click-through. The URL is
	// computed as follows: - If defaultLandingPage is enabled then the
	// campaign's default landing page URL is assigned to this field. - If
	// defaultLandingPage is not enabled and a landingPageId is specified
	// then that landing page's URL is assigned to this field. - If neither
	// of the above cases apply, then the customClickThroughUrl is assigned
	// to this field.
	ComputedClickThroughUrl string `json:"computedClickThroughUrl,omitempty"`

	// CustomClickThroughUrl: Custom click-through URL. Applicable if the
	// defaultLandingPage field is set to false and the landingPageId field
	// is left unset.
	CustomClickThroughUrl string `json:"customClickThroughUrl,omitempty"`

	// DefaultLandingPage: Whether the campaign default landing page is
	// used.
	DefaultLandingPage bool `json:"defaultLandingPage,omitempty"`

	// LandingPageId: ID of the landing page for the click-through URL.
	// Applicable if the defaultLandingPage field is set to false.
	LandingPageId int64 `json:"landingPageId,omitempty,string"`

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

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

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

// ClickThroughUrlSuffixProperties: Click Through URL Suffix settings.
type ClickThroughUrlSuffixProperties struct {
	// ClickThroughUrlSuffix: Click-through URL suffix to apply to all ads
	// in this entity's scope. Must be less than 128 characters long.
	ClickThroughUrlSuffix string `json:"clickThroughUrlSuffix,omitempty"`

	// OverrideInheritedSuffix: Whether this entity should override the
	// inherited click-through URL suffix with its own defined value.
	OverrideInheritedSuffix bool `json:"overrideInheritedSuffix,omitempty"`

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

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

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

// CompanionClickThroughOverride: Companion Click-through override.
type CompanionClickThroughOverride struct {
	// ClickThroughUrl: Click-through URL of this companion click-through
	// override.
	ClickThroughUrl *ClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// CreativeId: ID of the creative for this companion click-through
	// override.
	CreativeId int64 `json:"creativeId,omitempty,string"`

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

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

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

// CompanionSetting: Companion Settings
type CompanionSetting struct {
	// CompanionsDisabled: Whether companions are disabled for this
	// placement.
	CompanionsDisabled bool `json:"companionsDisabled,omitempty"`

	// EnabledSizes: Whitelist of companion sizes to be served to this
	// placement. Set this list to null or empty to serve all companion
	// sizes.
	EnabledSizes []*Size `json:"enabledSizes,omitempty"`

	// ImageOnly: Whether to serve only static images as companions.
	ImageOnly bool `json:"imageOnly,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#companionSetting".
	Kind string `json:"kind,omitempty"`

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

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

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

// CompatibleFields: Represents a response to the queryCompatibleFields
// method.
type CompatibleFields struct {
	// CrossDimensionReachReportCompatibleFields: Contains items that are
	// compatible to be selected for a report of type
	// "CROSS_DIMENSION_REACH".
	CrossDimensionReachReportCompatibleFields *CrossDimensionReachReportCompatibleFields `json:"crossDimensionReachReportCompatibleFields,omitempty"`

	// FloodlightReportCompatibleFields: Contains items that are compatible
	// to be selected for a report of type "FLOODLIGHT".
	FloodlightReportCompatibleFields *FloodlightReportCompatibleFields `json:"floodlightReportCompatibleFields,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#compatibleFields.
	Kind string `json:"kind,omitempty"`

	// PathAttributionReportCompatibleFields: Contains items that are
	// compatible to be selected for a report of type "PATH_ATTRIBUTION".
	PathAttributionReportCompatibleFields *PathReportCompatibleFields `json:"pathAttributionReportCompatibleFields,omitempty"`

	// PathReportCompatibleFields: Contains items that are compatible to be
	// selected for a report of type "PATH".
	PathReportCompatibleFields *PathReportCompatibleFields `json:"pathReportCompatibleFields,omitempty"`

	// PathToConversionReportCompatibleFields: Contains items that are
	// compatible to be selected for a report of type "PATH_TO_CONVERSION".
	PathToConversionReportCompatibleFields *PathToConversionReportCompatibleFields `json:"pathToConversionReportCompatibleFields,omitempty"`

	// ReachReportCompatibleFields: Contains items that are compatible to be
	// selected for a report of type "REACH".
	ReachReportCompatibleFields *ReachReportCompatibleFields `json:"reachReportCompatibleFields,omitempty"`

	// ReportCompatibleFields: Contains items that are compatible to be
	// selected for a report of type "STANDARD".
	ReportCompatibleFields *ReportCompatibleFields `json:"reportCompatibleFields,omitempty"`

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

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

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

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

// ConnectionType: Contains information about an internet connection
// type that can be targeted by ads. Clients can use the connection type
// to target mobile vs. broadband users.
type ConnectionType struct {
	// Id: ID of this connection type.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#connectionType".
	Kind string `json:"kind,omitempty"`

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

// ConnectionTypesListResponse: Connection Type List Response
type ConnectionTypesListResponse struct {
	// ConnectionTypes: Collection of connection types such as broadband and
	// mobile.
	ConnectionTypes []*ConnectionType `json:"connectionTypes,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#connectionTypesListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// ContentCategoriesListResponse: Content Category List Response
type ContentCategoriesListResponse struct {
	// ContentCategories: Content category collection.
	ContentCategories []*ContentCategory `json:"contentCategories,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#contentCategoriesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "ContentCategories")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// ContentCategory: Organizes placements according to the contents of
// their associated webpages.
type ContentCategory struct {
	// AccountId: Account ID of this content category. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Id: ID of this content category. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#contentCategory".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this content category. This is a required field and
	// must be less than 256 characters long and unique among content
	// categories of the same account.
	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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// Conversion: A Conversion represents when a user successfully performs
// a desired action after seeing an ad.
type Conversion struct {
	// ChildDirectedTreatment: Whether this particular request may come from
	// a user under the age of 13, under COPPA compliance.
	ChildDirectedTreatment bool `json:"childDirectedTreatment,omitempty"`

	// CustomVariables: Custom floodlight variables.
	CustomVariables []*CustomFloodlightVariable `json:"customVariables,omitempty"`

	// Dclid: The display click ID. This field is mutually exclusive with
	// encryptedUserId, encryptedUserIdCandidates[], matchId, mobileDeviceId
	// and gclid. This or encryptedUserId or encryptedUserIdCandidates[] or
	// matchId or mobileDeviceId or gclid is a required field.
	Dclid string `json:"dclid,omitempty"`

	// EncryptedUserId: The alphanumeric encrypted user ID. When set,
	// encryptionInfo should also be specified. This field is mutually
	// exclusive with encryptedUserIdCandidates[], matchId, mobileDeviceId,
	// gclid and dclid. This or encryptedUserIdCandidates[] or matchId or
	// mobileDeviceId or gclid or dclid is a required field.
	EncryptedUserId string `json:"encryptedUserId,omitempty"`

	// EncryptedUserIdCandidates: A list of the alphanumeric encrypted user
	// IDs. Any user ID with exposure prior to the conversion timestamp will
	// be used in the inserted conversion. If no such user ID is found then
	// the conversion will be rejected with INVALID_ARGUMENT error. When
	// set, encryptionInfo should also be specified. This field may only be
	// used when calling batchinsert; it is not supported by batchupdate.
	// This field is mutually exclusive with encryptedUserId, matchId,
	// mobileDeviceId, gclid and dclid. This or encryptedUserId or matchId
	// or mobileDeviceId or gclid or dclid is a required field.
	EncryptedUserIdCandidates []string `json:"encryptedUserIdCandidates,omitempty"`

	// FloodlightActivityId: Floodlight Activity ID of this conversion. This
	// is a required field.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// FloodlightConfigurationId: Floodlight Configuration ID of this
	// conversion. This is a required field.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

	// Gclid: The Google click ID. This field is mutually exclusive with
	// encryptedUserId, encryptedUserIdCandidates[], matchId, mobileDeviceId
	// and dclid. This or encryptedUserId or encryptedUserIdCandidates[] or
	// matchId or mobileDeviceId or dclid is a required field.
	Gclid string `json:"gclid,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#conversion".
	Kind string `json:"kind,omitempty"`

	// LimitAdTracking: Whether Limit Ad Tracking is enabled. When set to
	// true, the conversion will be used for reporting but not targeting.
	// This will prevent remarketing.
	LimitAdTracking bool `json:"limitAdTracking,omitempty"`

	// MatchId: The match ID field. A match ID is your own first-party
	// identifier that has been synced with Google using the match ID
	// feature in Floodlight. This field is mutually exclusive with
	// encryptedUserId, encryptedUserIdCandidates[],mobileDeviceId, gclid
	// and dclid. This or encryptedUserId or encryptedUserIdCandidates[] or
	// mobileDeviceId or gclid or dclid is a required field.
	MatchId string `json:"matchId,omitempty"`

	// MobileDeviceId: The mobile device ID. This field is mutually
	// exclusive with encryptedUserId, encryptedUserIdCandidates[], matchId,
	// gclid and dclid. This or encryptedUserId or
	// encryptedUserIdCandidates[] or matchId or gclid or dclid is a
	// required field.
	MobileDeviceId string `json:"mobileDeviceId,omitempty"`

	// NonPersonalizedAd: Whether the conversion was for a non personalized
	// ad.
	NonPersonalizedAd bool `json:"nonPersonalizedAd,omitempty"`

	// Ordinal: The ordinal of the conversion. Use this field to control how
	// conversions of the same user and day are de-duplicated. This is a
	// required field.
	Ordinal string `json:"ordinal,omitempty"`

	// Quantity: The quantity of the conversion.
	Quantity int64 `json:"quantity,omitempty,string"`

	// TimestampMicros: The timestamp of conversion, in Unix epoch micros.
	// This is a required field.
	TimestampMicros int64 `json:"timestampMicros,omitempty,string"`

	// TreatmentForUnderage: Whether this particular request may come from a
	// user under the age of 16 (may differ by country), under compliance
	// with the European Union's General Data Protection Regulation (GDPR).
	TreatmentForUnderage bool `json:"treatmentForUnderage,omitempty"`

	// Value: The value of the conversion.
	Value float64 `json:"value,omitempty"`

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

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

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

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

// ConversionError: The error code and description for a conversion that
// failed to insert or update.
type ConversionError struct {
	// Code: The error code.
	//
	// Possible values:
	//   "INVALID_ARGUMENT"
	//   "INTERNAL"
	//   "PERMISSION_DENIED"
	//   "NOT_FOUND"
	Code string `json:"code,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#conversionError".
	Kind string `json:"kind,omitempty"`

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

// ConversionStatus: The original conversion that was inserted or
// updated and whether there were any errors.
type ConversionStatus struct {
	// Conversion: The original conversion that was inserted or updated.
	Conversion *Conversion `json:"conversion,omitempty"`

	// Errors: A list of errors related to this conversion.
	Errors []*ConversionError `json:"errors,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#conversionStatus".
	Kind string `json:"kind,omitempty"`

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

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

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

// ConversionsBatchInsertRequest: Insert Conversions Request.
type ConversionsBatchInsertRequest struct {
	// Conversions: The set of conversions to insert.
	Conversions []*Conversion `json:"conversions,omitempty"`

	// EncryptionInfo: Describes how encryptedUserId or
	// encryptedUserIdCandidates[] is encrypted. This is a required field if
	// encryptedUserId or encryptedUserIdCandidates[] is used.
	EncryptionInfo *EncryptionInfo `json:"encryptionInfo,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#conversionsBatchInsertRequest".
	Kind string `json:"kind,omitempty"`

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

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

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

// ConversionsBatchInsertResponse: Insert Conversions Response.
type ConversionsBatchInsertResponse struct {
	// HasFailures: Indicates that some or all conversions failed to insert.
	HasFailures bool `json:"hasFailures,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#conversionsBatchInsertResponse".
	Kind string `json:"kind,omitempty"`

	// Status: The insert status of each conversion. Statuses are returned
	// in the same order that conversions are inserted.
	Status []*ConversionStatus `json:"status,omitempty"`

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

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

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

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

// ConversionsBatchUpdateRequest: Update Conversions Request.
type ConversionsBatchUpdateRequest struct {
	// Conversions: The set of conversions to update.
	Conversions []*Conversion `json:"conversions,omitempty"`

	// EncryptionInfo: Describes how encryptedUserId is encrypted. This is a
	// required field if encryptedUserId is used.
	EncryptionInfo *EncryptionInfo `json:"encryptionInfo,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#conversionsBatchUpdateRequest".
	Kind string `json:"kind,omitempty"`

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

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

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

// ConversionsBatchUpdateResponse: Update Conversions Response.
type ConversionsBatchUpdateResponse struct {
	// HasFailures: Indicates that some or all conversions failed to update.
	HasFailures bool `json:"hasFailures,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#conversionsBatchUpdateResponse".
	Kind string `json:"kind,omitempty"`

	// Status: The update status of each conversion. Statuses are returned
	// in the same order that conversions are updated.
	Status []*ConversionStatus `json:"status,omitempty"`

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

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

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

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

// CountriesListResponse: Country List Response
type CountriesListResponse struct {
	// Countries: Country collection.
	Countries []*Country `json:"countries,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#countriesListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// Country: Contains information about a country that can be targeted by
// ads.
type Country struct {
	// CountryCode: Country code.
	CountryCode string `json:"countryCode,omitempty"`

	// DartId: DART ID of this country. This is the ID used for targeting
	// and generating reports.
	DartId int64 `json:"dartId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#country".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this country.
	Name string `json:"name,omitempty"`

	// SslEnabled: Whether ad serving supports secure servers in this
	// country.
	SslEnabled bool `json:"sslEnabled,omitempty"`

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

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

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

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

// Creative: Contains properties of a Creative.
type Creative struct {
	// AccountId: Account ID of this creative. This field, if left unset,
	// will be auto-generated for both insert and update operations.
	// Applicable to all creative types.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether the creative is active. Applicable to all creative
	// types.
	Active bool `json:"active,omitempty"`

	// AdParameters: Ad parameters user for VPAID creative. This is a
	// read-only field. Applicable to the following creative types: all
	// VPAID.
	AdParameters string `json:"adParameters,omitempty"`

	// AdTagKeys: Keywords for a Rich Media creative. Keywords let you
	// customize the creative settings of a Rich Media ad running on your
	// site without having to contact the advertiser. You can use keywords
	// to dynamically change the look or functionality of a creative.
	// Applicable to the following creative types: all RICH_MEDIA, and all
	// VPAID.
	AdTagKeys []string `json:"adTagKeys,omitempty"`

	// AdditionalSizes: Additional sizes associated with a responsive
	// creative. When inserting or updating a creative either the size ID
	// field or size width and height fields can be used. Applicable to
	// DISPLAY creatives when the primary asset type is HTML_IMAGE.
	AdditionalSizes []*Size `json:"additionalSizes,omitempty"`

	// AdvertiserId: Advertiser ID of this creative. This is a required
	// field. Applicable to all creative types.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AllowScriptAccess: Whether script access is allowed for this
	// creative. This is a read-only and deprecated field which will
	// automatically be set to true on update. Applicable to the following
	// creative types: FLASH_INPAGE.
	AllowScriptAccess bool `json:"allowScriptAccess,omitempty"`

	// Archived: Whether the creative is archived. Applicable to all
	// creative types.
	Archived bool `json:"archived,omitempty"`

	// ArtworkType: Type of artwork used for the creative. This is a
	// read-only field. Applicable to the following creative types: all
	// RICH_MEDIA, and all VPAID.
	//
	// Possible values:
	//   "ARTWORK_TYPE_FLASH"
	//   "ARTWORK_TYPE_HTML5"
	//   "ARTWORK_TYPE_MIXED"
	//   "ARTWORK_TYPE_IMAGE"
	ArtworkType string `json:"artworkType,omitempty"`

	// AuthoringSource: Source application where creative was authored.
	// Presently, only DBM authored creatives will have this field set.
	// Applicable to all creative types.
	//
	// Possible values:
	//   "CREATIVE_AUTHORING_SOURCE_DCM"
	//   "CREATIVE_AUTHORING_SOURCE_DBM"
	//   "CREATIVE_AUTHORING_SOURCE_STUDIO"
	AuthoringSource string `json:"authoringSource,omitempty"`

	// AuthoringTool: Authoring tool for HTML5 banner creatives. This is a
	// read-only field. Applicable to the following creative types:
	// HTML5_BANNER.
	//
	// Possible values:
	//   "NINJA"
	//   "SWIFFY"
	AuthoringTool string `json:"authoringTool,omitempty"`

	// AutoAdvanceImages: Whether images are automatically advanced for
	// image gallery creatives. Applicable to the following creative types:
	// DISPLAY_IMAGE_GALLERY.
	AutoAdvanceImages bool `json:"autoAdvanceImages,omitempty"`

	// BackgroundColor: The 6-character HTML color code, beginning with #,
	// for the background of the window area where the Flash file is
	// displayed. Default is white. Applicable to the following creative
	// types: FLASH_INPAGE.
	BackgroundColor string `json:"backgroundColor,omitempty"`

	// BackupImageClickThroughUrl: Click-through URL for backup image.
	// Applicable to ENHANCED_BANNER when the primary asset type is not
	// HTML_IMAGE.
	BackupImageClickThroughUrl *CreativeClickThroughUrl `json:"backupImageClickThroughUrl,omitempty"`

	// BackupImageFeatures: List of feature dependencies that will cause a
	// backup image to be served if the browser that serves the ad does not
	// support them. Feature dependencies are features that a browser must
	// be able to support in order to render your HTML5 creative asset
	// correctly. This field is initially auto-generated to contain all
	// features detected by Campaign Manager for all the assets of this
	// creative and can then be modified by the client. To reset this field,
	// copy over all the creativeAssets' detected features. Applicable to
	// the following creative types: HTML5_BANNER. Applicable to DISPLAY
	// when the primary asset type is not HTML_IMAGE.
	//
	// Possible values:
	//   "CSS_FONT_FACE"
	//   "CSS_BACKGROUND_SIZE"
	//   "CSS_BORDER_IMAGE"
	//   "CSS_BORDER_RADIUS"
	//   "CSS_BOX_SHADOW"
	//   "CSS_FLEX_BOX"
	//   "CSS_HSLA"
	//   "CSS_MULTIPLE_BGS"
	//   "CSS_OPACITY"
	//   "CSS_RGBA"
	//   "CSS_TEXT_SHADOW"
	//   "CSS_ANIMATIONS"
	//   "CSS_COLUMNS"
	//   "CSS_GENERATED_CONTENT"
	//   "CSS_GRADIENTS"
	//   "CSS_REFLECTIONS"
	//   "CSS_TRANSFORMS"
	//   "CSS_TRANSFORMS3D"
	//   "CSS_TRANSITIONS"
	//   "APPLICATION_CACHE"
	//   "CANVAS"
	//   "CANVAS_TEXT"
	//   "DRAG_AND_DROP"
	//   "HASH_CHANGE"
	//   "HISTORY"
	//   "AUDIO"
	//   "VIDEO"
	//   "INDEXED_DB"
	//   "INPUT_ATTR_AUTOCOMPLETE"
	//   "INPUT_ATTR_AUTOFOCUS"
	//   "INPUT_ATTR_LIST"
	//   "INPUT_ATTR_PLACEHOLDER"
	//   "INPUT_ATTR_MAX"
	//   "INPUT_ATTR_MIN"
	//   "INPUT_ATTR_MULTIPLE"
	//   "INPUT_ATTR_PATTERN"
	//   "INPUT_ATTR_REQUIRED"
	//   "INPUT_ATTR_STEP"
	//   "INPUT_TYPE_SEARCH"
	//   "INPUT_TYPE_TEL"
	//   "INPUT_TYPE_URL"
	//   "INPUT_TYPE_EMAIL"
	//   "INPUT_TYPE_DATETIME"
	//   "INPUT_TYPE_DATE"
	//   "INPUT_TYPE_MONTH"
	//   "INPUT_TYPE_WEEK"
	//   "INPUT_TYPE_TIME"
	//   "INPUT_TYPE_DATETIME_LOCAL"
	//   "INPUT_TYPE_NUMBER"
	//   "INPUT_TYPE_RANGE"
	//   "INPUT_TYPE_COLOR"
	//   "LOCAL_STORAGE"
	//   "POST_MESSAGE"
	//   "SESSION_STORAGE"
	//   "WEB_SOCKETS"
	//   "WEB_SQL_DATABASE"
	//   "WEB_WORKERS"
	//   "GEO_LOCATION"
	//   "INLINE_SVG"
	//   "SMIL"
	//   "SVG_HREF"
	//   "SVG_CLIP_PATHS"
	//   "TOUCH"
	//   "WEBGL"
	//   "SVG_FILTERS"
	//   "SVG_FE_IMAGE"
	BackupImageFeatures []string `json:"backupImageFeatures,omitempty"`

	// BackupImageReportingLabel: Reporting label used for HTML5 banner
	// backup image. Applicable to the following creative types: DISPLAY
	// when the primary asset type is not HTML_IMAGE.
	BackupImageReportingLabel string `json:"backupImageReportingLabel,omitempty"`

	// BackupImageTargetWindow: Target window for backup image. Applicable
	// to the following creative types: FLASH_INPAGE and HTML5_BANNER.
	// Applicable to DISPLAY when the primary asset type is not HTML_IMAGE.
	BackupImageTargetWindow *TargetWindow `json:"backupImageTargetWindow,omitempty"`

	// ClickTags: Click tags of the creative. For DISPLAY, FLASH_INPAGE, and
	// HTML5_BANNER creatives, this is a subset of detected click tags for
	// the assets associated with this creative. After creating a flash
	// asset, detected click tags will be returned in the
	// creativeAssetMetadata. When inserting the creative, populate the
	// creative clickTags field using the creativeAssetMetadata.clickTags
	// field. For DISPLAY_IMAGE_GALLERY creatives, there should be exactly
	// one entry in this list for each image creative asset. A click tag is
	// matched with a corresponding creative asset by matching the
	// clickTag.name field with the creativeAsset.assetIdentifier.name
	// field. Applicable to the following creative types:
	// DISPLAY_IMAGE_GALLERY, FLASH_INPAGE, HTML5_BANNER. Applicable to
	// DISPLAY when the primary asset type is not HTML_IMAGE.
	ClickTags []*ClickTag `json:"clickTags,omitempty"`

	// CommercialId: Industry standard ID assigned to creative for reach and
	// frequency. Applicable to INSTREAM_VIDEO_REDIRECT creatives.
	CommercialId string `json:"commercialId,omitempty"`

	// CompanionCreatives: List of companion creatives assigned to an
	// in-Stream video creative. Acceptable values include IDs of existing
	// flash and image creatives. Applicable to the following creative
	// types: all VPAID, all INSTREAM_AUDIO and all INSTREAM_VIDEO with
	// dynamicAssetSelection set to false.
	CompanionCreatives googleapi.Int64s `json:"companionCreatives,omitempty"`

	// Compatibility: Compatibilities associated with this creative. This is
	// a read-only field. DISPLAY and DISPLAY_INTERSTITIAL refer to
	// rendering either on desktop or on mobile devices or in mobile apps
	// for regular or interstitial ads, respectively. APP and
	// APP_INTERSTITIAL are for rendering in mobile apps. Only pre-existing
	// creatives may have these compatibilities since new creatives will
	// either be assigned DISPLAY or DISPLAY_INTERSTITIAL instead.
	// IN_STREAM_VIDEO refers to rendering in in-stream video ads developed
	// with the VAST standard. IN_STREAM_AUDIO refers to rendering in
	// in-stream audio ads developed with the VAST standard. Applicable to
	// all creative types. Acceptable values are: - "APP" -
	// "APP_INTERSTITIAL" - "IN_STREAM_VIDEO" - "IN_STREAM_AUDIO" -
	// "DISPLAY" - "DISPLAY_INTERSTITIAL"
	//
	// Possible values:
	//   "DISPLAY"
	//   "DISPLAY_INTERSTITIAL"
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	//   "IN_STREAM_AUDIO"
	Compatibility []string `json:"compatibility,omitempty"`

	// ConvertFlashToHtml5: Whether Flash assets associated with the
	// creative need to be automatically converted to HTML5. This flag is
	// enabled by default and users can choose to disable it if they don't
	// want the system to generate and use HTML5 asset for this creative.
	// Applicable to the following creative type: FLASH_INPAGE. Applicable
	// to DISPLAY when the primary asset type is not HTML_IMAGE.
	ConvertFlashToHtml5 bool `json:"convertFlashToHtml5,omitempty"`

	// CounterCustomEvents: List of counter events configured for the
	// creative. For DISPLAY_IMAGE_GALLERY creatives, these are read-only
	// and auto-generated from clickTags. Applicable to the following
	// creative types: DISPLAY_IMAGE_GALLERY, all RICH_MEDIA, and all VPAID.
	CounterCustomEvents []*CreativeCustomEvent `json:"counterCustomEvents,omitempty"`

	// CreativeAssetSelection: Required if dynamicAssetSelection is true.
	CreativeAssetSelection *CreativeAssetSelection `json:"creativeAssetSelection,omitempty"`

	// CreativeAssets: Assets associated with a creative. Applicable to all
	// but the following creative types: INTERNAL_REDIRECT,
	// INTERSTITIAL_INTERNAL_REDIRECT, and REDIRECT
	CreativeAssets []*CreativeAsset `json:"creativeAssets,omitempty"`

	// CreativeFieldAssignments: Creative field assignments for this
	// creative. Applicable to all creative types.
	CreativeFieldAssignments []*CreativeFieldAssignment `json:"creativeFieldAssignments,omitempty"`

	// CustomKeyValues: Custom key-values for a Rich Media creative.
	// Key-values let you customize the creative settings of a Rich Media ad
	// running on your site without having to contact the advertiser. You
	// can use key-values to dynamically change the look or functionality of
	// a creative. Applicable to the following creative types: all
	// RICH_MEDIA, and all VPAID.
	CustomKeyValues []string `json:"customKeyValues,omitempty"`

	// DynamicAssetSelection: Set this to true to enable the use of rules to
	// target individual assets in this creative. When set to true
	// creativeAssetSelection must be set. This also controls asset-level
	// companions. When this is true, companion creatives should be assigned
	// to creative assets. Learn more. Applicable to INSTREAM_VIDEO
	// creatives.
	DynamicAssetSelection bool `json:"dynamicAssetSelection,omitempty"`

	// ExitCustomEvents: List of exit events configured for the creative.
	// For DISPLAY and DISPLAY_IMAGE_GALLERY creatives, these are read-only
	// and auto-generated from clickTags, For DISPLAY, an event is also
	// created from the backupImageReportingLabel. Applicable to the
	// following creative types: DISPLAY_IMAGE_GALLERY, all RICH_MEDIA, and
	// all VPAID. Applicable to DISPLAY when the primary asset type is not
	// HTML_IMAGE.
	ExitCustomEvents []*CreativeCustomEvent `json:"exitCustomEvents,omitempty"`

	// FsCommand: OpenWindow FSCommand of this creative. This lets the SWF
	// file communicate with either Flash Player or the program hosting
	// Flash Player, such as a web browser. This is only triggered if
	// allowScriptAccess field is true. Applicable to the following creative
	// types: FLASH_INPAGE.
	FsCommand *FsCommand `json:"fsCommand,omitempty"`

	// HtmlCode: HTML code for the creative. This is a required field when
	// applicable. This field is ignored if htmlCodeLocked is true.
	// Applicable to the following creative types: all CUSTOM, FLASH_INPAGE,
	// and HTML5_BANNER, and all RICH_MEDIA.
	HtmlCode string `json:"htmlCode,omitempty"`

	// HtmlCodeLocked: Whether HTML code is generated by Campaign Manager or
	// manually entered. Set to true to ignore changes to htmlCode.
	// Applicable to the following creative types: FLASH_INPAGE and
	// HTML5_BANNER.
	HtmlCodeLocked bool `json:"htmlCodeLocked,omitempty"`

	// Id: ID of this creative. This is a read-only, auto-generated field.
	// Applicable to all creative types.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this creative. This
	// is a read-only field. Applicable to all creative types.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creative".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Creative last modification information. This is a
	// read-only field. Applicable to all creative types.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// LatestTraffickedCreativeId: Latest Studio trafficked creative ID
	// associated with rich media and VPAID creatives. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA,
	// and all VPAID.
	LatestTraffickedCreativeId int64 `json:"latestTraffickedCreativeId,omitempty,string"`

	// MediaDescription: Description of the audio or video ad. Applicable to
	// the following creative types: all INSTREAM_VIDEO, INSTREAM_AUDIO, and
	// all VPAID.
	MediaDescription string `json:"mediaDescription,omitempty"`

	// MediaDuration: Creative audio or video duration in seconds. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO, INSTREAM_AUDIO, all RICH_MEDIA, and all VPAID.
	MediaDuration float64 `json:"mediaDuration,omitempty"`

	// Name: Name of the creative. This is a required field and must be less
	// than 256 characters long. Applicable to all creative types.
	Name string `json:"name,omitempty"`

	// ObaIcon: Online behavioral advertising icon to be added to the
	// creative. Applicable to the following creative types: all
	// INSTREAM_VIDEO.
	ObaIcon *ObaIcon `json:"obaIcon,omitempty"`

	// OverrideCss: Override CSS value for rich media creatives. Applicable
	// to the following creative types: all RICH_MEDIA.
	OverrideCss string `json:"overrideCss,omitempty"`

	// ProgressOffset: Amount of time to play the video before counting a
	// view. Applicable to the following creative types: all INSTREAM_VIDEO.
	ProgressOffset *VideoOffset `json:"progressOffset,omitempty"`

	// RedirectUrl: URL of hosted image or hosted video or another ad tag.
	// For INSTREAM_VIDEO_REDIRECT creatives this is the in-stream video
	// redirect URL. The standard for a VAST (Video Ad Serving Template) ad
	// response allows for a redirect link to another VAST 2.0 or 3.0 call.
	// This is a required field when applicable. Applicable to the following
	// creative types: DISPLAY_REDIRECT, INTERNAL_REDIRECT,
	// INTERSTITIAL_INTERNAL_REDIRECT, and INSTREAM_VIDEO_REDIRECT
	RedirectUrl string `json:"redirectUrl,omitempty"`

	// RenderingId: ID of current rendering version. This is a read-only
	// field. Applicable to all creative types.
	RenderingId int64 `json:"renderingId,omitempty,string"`

	// RenderingIdDimensionValue: Dimension value for the rendering ID of
	// this creative. This is a read-only field. Applicable to all creative
	// types.
	RenderingIdDimensionValue *DimensionValue `json:"renderingIdDimensionValue,omitempty"`

	// RequiredFlashPluginVersion: The minimum required Flash plugin version
	// for this creative. For example, 11.2.202.235. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA,
	// and all VPAID.
	RequiredFlashPluginVersion string `json:"requiredFlashPluginVersion,omitempty"`

	// RequiredFlashVersion: The internal Flash version for this creative as
	// calculated by Studio. This is a read-only field. Applicable to the
	// following creative types: FLASH_INPAGE all RICH_MEDIA, and all VPAID.
	// Applicable to DISPLAY when the primary asset type is not HTML_IMAGE.
	RequiredFlashVersion int64 `json:"requiredFlashVersion,omitempty"`

	// Size: Size associated with this creative. When inserting or updating
	// a creative either the size ID field or size width and height fields
	// can be used. This is a required field when applicable; however for
	// IMAGE, FLASH_INPAGE creatives, and for DISPLAY creatives with a
	// primary asset of type HTML_IMAGE, if left blank, this field will be
	// automatically set using the actual size of the associated image
	// assets. Applicable to the following creative types: DISPLAY,
	// DISPLAY_IMAGE_GALLERY, FLASH_INPAGE, HTML5_BANNER, IMAGE, and all
	// RICH_MEDIA.
	Size *Size `json:"size,omitempty"`

	// SkipOffset: Amount of time to play the video before the skip button
	// appears. Applicable to the following creative types: all
	// INSTREAM_VIDEO.
	SkipOffset *VideoOffset `json:"skipOffset,omitempty"`

	// Skippable: Whether the user can choose to skip the creative.
	// Applicable to the following creative types: all INSTREAM_VIDEO and
	// all VPAID.
	Skippable bool `json:"skippable,omitempty"`

	// SslCompliant: Whether the creative is SSL-compliant. This is a
	// read-only field. Applicable to all creative types.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// SslOverride: Whether creative should be treated as SSL compliant even
	// if the system scan shows it's not. Applicable to all creative types.
	SslOverride bool `json:"sslOverride,omitempty"`

	// StudioAdvertiserId: Studio advertiser ID associated with rich media
	// and VPAID creatives. This is a read-only field. Applicable to the
	// following creative types: all RICH_MEDIA, and all VPAID.
	StudioAdvertiserId int64 `json:"studioAdvertiserId,omitempty,string"`

	// StudioCreativeId: Studio creative ID associated with rich media and
	// VPAID creatives. This is a read-only field. Applicable to the
	// following creative types: all RICH_MEDIA, and all VPAID.
	StudioCreativeId int64 `json:"studioCreativeId,omitempty,string"`

	// StudioTraffickedCreativeId: Studio trafficked creative ID associated
	// with rich media and VPAID creatives. This is a read-only field.
	// Applicable to the following creative types: all RICH_MEDIA, and all
	// VPAID.
	StudioTraffickedCreativeId int64 `json:"studioTraffickedCreativeId,omitempty,string"`

	// SubaccountId: Subaccount ID of this creative. This field, if left
	// unset, will be auto-generated for both insert and update operations.
	// Applicable to all creative types.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// ThirdPartyBackupImageImpressionsUrl: Third-party URL used to record
	// backup image impressions. Applicable to the following creative types:
	// all RICH_MEDIA.
	ThirdPartyBackupImageImpressionsUrl string `json:"thirdPartyBackupImageImpressionsUrl,omitempty"`

	// ThirdPartyRichMediaImpressionsUrl: Third-party URL used to record
	// rich media impressions. Applicable to the following creative types:
	// all RICH_MEDIA.
	ThirdPartyRichMediaImpressionsUrl string `json:"thirdPartyRichMediaImpressionsUrl,omitempty"`

	// ThirdPartyUrls: Third-party URLs for tracking in-stream creative
	// events. Applicable to the following creative types: all
	// INSTREAM_VIDEO, all INSTREAM_AUDIO, and all VPAID.
	ThirdPartyUrls []*ThirdPartyTrackingUrl `json:"thirdPartyUrls,omitempty"`

	// TimerCustomEvents: List of timer events configured for the creative.
	// For DISPLAY_IMAGE_GALLERY creatives, these are read-only and
	// auto-generated from clickTags. Applicable to the following creative
	// types: DISPLAY_IMAGE_GALLERY, all RICH_MEDIA, and all VPAID.
	// Applicable to DISPLAY when the primary asset is not HTML_IMAGE.
	TimerCustomEvents []*CreativeCustomEvent `json:"timerCustomEvents,omitempty"`

	// TotalFileSize: Combined size of all creative assets. This is a
	// read-only field. Applicable to the following creative types: all
	// RICH_MEDIA, and all VPAID.
	TotalFileSize int64 `json:"totalFileSize,omitempty,string"`

	// Type: Type of this creative. This is a required field. Applicable to
	// all creative types. *Note:* FLASH_INPAGE, HTML5_BANNER, and IMAGE are
	// only used for existing creatives. New creatives should use DISPLAY as
	// a replacement for these types.
	//
	// Possible values:
	//   "IMAGE"
	//   "DISPLAY_REDIRECT"
	//   "CUSTOM_DISPLAY"
	//   "INTERNAL_REDIRECT"
	//   "CUSTOM_DISPLAY_INTERSTITIAL"
	//   "INTERSTITIAL_INTERNAL_REDIRECT"
	//   "TRACKING_TEXT"
	//   "RICH_MEDIA_DISPLAY_BANNER"
	//   "RICH_MEDIA_INPAGE_FLOATING"
	//   "RICH_MEDIA_IM_EXPAND"
	//   "RICH_MEDIA_DISPLAY_EXPANDING"
	//   "RICH_MEDIA_DISPLAY_INTERSTITIAL"
	//   "RICH_MEDIA_DISPLAY_MULTI_FLOATING_INTERSTITIAL"
	//   "RICH_MEDIA_MOBILE_IN_APP"
	//   "FLASH_INPAGE"
	//   "INSTREAM_VIDEO"
	//   "VPAID_LINEAR_VIDEO"
	//   "VPAID_NON_LINEAR_VIDEO"
	//   "INSTREAM_VIDEO_REDIRECT"
	//   "RICH_MEDIA_PEEL_DOWN"
	//   "HTML5_BANNER"
	//   "DISPLAY"
	//   "DISPLAY_IMAGE_GALLERY"
	//   "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO"
	//   "INSTREAM_AUDIO"
	Type string `json:"type,omitempty"`

	// UniversalAdId: A Universal Ad ID as per the VAST 4.0 spec. Applicable
	// to the following creative types: INSTREAM_AUDIO and INSTREAM_VIDEO
	// and VPAID.
	UniversalAdId *UniversalAdId `json:"universalAdId,omitempty"`

	// Version: The version number helps you keep track of multiple versions
	// of your creative in your reports. The version number will always be
	// auto-generated during insert operations to start at 1. For tracking
	// creatives the version cannot be incremented and will always remain at
	// 1. For all other creative types the version can be incremented only
	// by 1 during update operations. In addition, the version will be
	// automatically incremented by 1 when undergoing Rich Media creative
	// merging. Applicable to all creative types.
	Version int64 `json:"version,omitempty"`

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

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

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

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

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

// CreativeAsset: Creative Asset.
type CreativeAsset struct {
	// ActionScript3: Whether ActionScript3 is enabled for the flash asset.
	// This is a read-only field. Applicable to the following creative type:
	// FLASH_INPAGE. Applicable to DISPLAY when the primary asset type is
	// not HTML_IMAGE.
	ActionScript3 bool `json:"actionScript3,omitempty"`

	// Active: Whether the video or audio asset is active. This is a
	// read-only field for VPAID_NON_LINEAR_VIDEO assets. Applicable to the
	// following creative types: INSTREAM_AUDIO, INSTREAM_VIDEO and all
	// VPAID.
	Active bool `json:"active,omitempty"`

	// AdditionalSizes: Additional sizes associated with this creative
	// asset. HTML5 asset generated by compatible software such as GWD will
	// be able to support more sizes this creative asset can render.
	AdditionalSizes []*Size `json:"additionalSizes,omitempty"`

	// Alignment: Possible alignments for an asset. This is a read-only
	// field. Applicable to the following creative types:
	// RICH_MEDIA_DISPLAY_MULTI_FLOATING_INTERSTITIAL .
	//
	// Possible values:
	//   "ALIGNMENT_TOP"
	//   "ALIGNMENT_RIGHT"
	//   "ALIGNMENT_BOTTOM"
	//   "ALIGNMENT_LEFT"
	Alignment string `json:"alignment,omitempty"`

	// ArtworkType: Artwork type of rich media creative. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "ARTWORK_TYPE_FLASH"
	//   "ARTWORK_TYPE_HTML5"
	//   "ARTWORK_TYPE_MIXED"
	//   "ARTWORK_TYPE_IMAGE"
	ArtworkType string `json:"artworkType,omitempty"`

	// AssetIdentifier: Identifier of this asset. This is the same
	// identifier returned during creative asset insert operation. This is a
	// required field. Applicable to all but the following creative types:
	// all REDIRECT and TRACKING_TEXT.
	AssetIdentifier *CreativeAssetId `json:"assetIdentifier,omitempty"`

	// AudioBitRate: Audio stream bit rate in kbps. This is a read-only
	// field. Applicable to the following creative types: INSTREAM_AUDIO,
	// INSTREAM_VIDEO and all VPAID.
	AudioBitRate int64 `json:"audioBitRate,omitempty"`

	// AudioSampleRate: Audio sample bit rate in hertz. This is a read-only
	// field. Applicable to the following creative types: INSTREAM_AUDIO,
	// INSTREAM_VIDEO and all VPAID.
	AudioSampleRate int64 `json:"audioSampleRate,omitempty"`

	// BackupImageExit: Exit event configured for the backup image.
	// Applicable to the following creative types: all RICH_MEDIA.
	BackupImageExit *CreativeCustomEvent `json:"backupImageExit,omitempty"`

	// BitRate: Detected bit-rate for audio or video asset. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_AUDIO, INSTREAM_VIDEO and all VPAID.
	BitRate int64 `json:"bitRate,omitempty"`

	// ChildAssetType: Rich media child asset type. This is a read-only
	// field. Applicable to the following creative types: all VPAID.
	//
	// Possible values:
	//   "CHILD_ASSET_TYPE_FLASH"
	//   "CHILD_ASSET_TYPE_VIDEO"
	//   "CHILD_ASSET_TYPE_IMAGE"
	//   "CHILD_ASSET_TYPE_DATA"
	ChildAssetType string `json:"childAssetType,omitempty"`

	// CollapsedSize: Size of an asset when collapsed. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA and
	// all VPAID. Additionally, applicable to assets whose displayType is
	// ASSET_DISPLAY_TYPE_EXPANDING or ASSET_DISPLAY_TYPE_PEEL_DOWN.
	CollapsedSize *Size `json:"collapsedSize,omitempty"`

	// CompanionCreativeIds: List of companion creatives assigned to an
	// in-stream video creative asset. Acceptable values include IDs of
	// existing flash and image creatives. Applicable to INSTREAM_VIDEO
	// creative type with dynamicAssetSelection set to true.
	CompanionCreativeIds googleapi.Int64s `json:"companionCreativeIds,omitempty"`

	// CustomStartTimeValue: Custom start time in seconds for making the
	// asset visible. Applicable to the following creative types: all
	// RICH_MEDIA. Value must be greater than or equal to 0.
	CustomStartTimeValue int64 `json:"customStartTimeValue,omitempty"`

	// DetectedFeatures: List of feature dependencies for the creative asset
	// that are detected by Campaign Manager. Feature dependencies are
	// features that a browser must be able to support in order to render
	// your HTML5 creative correctly. This is a read-only, auto-generated
	// field. Applicable to the following creative types: HTML5_BANNER.
	// Applicable to DISPLAY when the primary asset type is not HTML_IMAGE.
	//
	// Possible values:
	//   "CSS_FONT_FACE"
	//   "CSS_BACKGROUND_SIZE"
	//   "CSS_BORDER_IMAGE"
	//   "CSS_BORDER_RADIUS"
	//   "CSS_BOX_SHADOW"
	//   "CSS_FLEX_BOX"
	//   "CSS_HSLA"
	//   "CSS_MULTIPLE_BGS"
	//   "CSS_OPACITY"
	//   "CSS_RGBA"
	//   "CSS_TEXT_SHADOW"
	//   "CSS_ANIMATIONS"
	//   "CSS_COLUMNS"
	//   "CSS_GENERATED_CONTENT"
	//   "CSS_GRADIENTS"
	//   "CSS_REFLECTIONS"
	//   "CSS_TRANSFORMS"
	//   "CSS_TRANSFORMS3D"
	//   "CSS_TRANSITIONS"
	//   "APPLICATION_CACHE"
	//   "CANVAS"
	//   "CANVAS_TEXT"
	//   "DRAG_AND_DROP"
	//   "HASH_CHANGE"
	//   "HISTORY"
	//   "AUDIO"
	//   "VIDEO"
	//   "INDEXED_DB"
	//   "INPUT_ATTR_AUTOCOMPLETE"
	//   "INPUT_ATTR_AUTOFOCUS"
	//   "INPUT_ATTR_LIST"
	//   "INPUT_ATTR_PLACEHOLDER"
	//   "INPUT_ATTR_MAX"
	//   "INPUT_ATTR_MIN"
	//   "INPUT_ATTR_MULTIPLE"
	//   "INPUT_ATTR_PATTERN"
	//   "INPUT_ATTR_REQUIRED"
	//   "INPUT_ATTR_STEP"
	//   "INPUT_TYPE_SEARCH"
	//   "INPUT_TYPE_TEL"
	//   "INPUT_TYPE_URL"
	//   "INPUT_TYPE_EMAIL"
	//   "INPUT_TYPE_DATETIME"
	//   "INPUT_TYPE_DATE"
	//   "INPUT_TYPE_MONTH"
	//   "INPUT_TYPE_WEEK"
	//   "INPUT_TYPE_TIME"
	//   "INPUT_TYPE_DATETIME_LOCAL"
	//   "INPUT_TYPE_NUMBER"
	//   "INPUT_TYPE_RANGE"
	//   "INPUT_TYPE_COLOR"
	//   "LOCAL_STORAGE"
	//   "POST_MESSAGE"
	//   "SESSION_STORAGE"
	//   "WEB_SOCKETS"
	//   "WEB_SQL_DATABASE"
	//   "WEB_WORKERS"
	//   "GEO_LOCATION"
	//   "INLINE_SVG"
	//   "SMIL"
	//   "SVG_HREF"
	//   "SVG_CLIP_PATHS"
	//   "TOUCH"
	//   "WEBGL"
	//   "SVG_FILTERS"
	//   "SVG_FE_IMAGE"
	DetectedFeatures []string `json:"detectedFeatures,omitempty"`

	// DisplayType: Type of rich media asset. This is a read-only field.
	// Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "ASSET_DISPLAY_TYPE_INPAGE"
	//   "ASSET_DISPLAY_TYPE_FLOATING"
	//   "ASSET_DISPLAY_TYPE_OVERLAY"
	//   "ASSET_DISPLAY_TYPE_EXPANDING"
	//   "ASSET_DISPLAY_TYPE_FLASH_IN_FLASH"
	//   "ASSET_DISPLAY_TYPE_FLASH_IN_FLASH_EXPANDING"
	//   "ASSET_DISPLAY_TYPE_PEEL_DOWN"
	//   "ASSET_DISPLAY_TYPE_VPAID_LINEAR"
	//   "ASSET_DISPLAY_TYPE_VPAID_NON_LINEAR"
	//   "ASSET_DISPLAY_TYPE_BACKDROP"
	DisplayType string `json:"displayType,omitempty"`

	// Duration: Duration in seconds for which an asset will be displayed.
	// Applicable to the following creative types: INSTREAM_AUDIO,
	// INSTREAM_VIDEO and VPAID_LINEAR_VIDEO. Value must be greater than or
	// equal to 1.
	Duration int64 `json:"duration,omitempty"`

	// DurationType: Duration type for which an asset will be displayed.
	// Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "ASSET_DURATION_TYPE_AUTO"
	//   "ASSET_DURATION_TYPE_NONE"
	//   "ASSET_DURATION_TYPE_CUSTOM"
	DurationType string `json:"durationType,omitempty"`

	// ExpandedDimension: Detected expanded dimension for video asset. This
	// is a read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO and all VPAID.
	ExpandedDimension *Size `json:"expandedDimension,omitempty"`

	// FileSize: File size associated with this creative asset. This is a
	// read-only field. Applicable to all but the following creative types:
	// all REDIRECT and TRACKING_TEXT.
	FileSize int64 `json:"fileSize,omitempty,string"`

	// FlashVersion: Flash version of the asset. This is a read-only field.
	// Applicable to the following creative types: FLASH_INPAGE, all
	// RICH_MEDIA, and all VPAID. Applicable to DISPLAY when the primary
	// asset type is not HTML_IMAGE.
	FlashVersion int64 `json:"flashVersion,omitempty"`

	// FrameRate: Video frame rate for video asset in frames per second.
	// This is a read-only field. Applicable to the following creative
	// types: INSTREAM_VIDEO and all VPAID.
	FrameRate float64 `json:"frameRate,omitempty"`

	// HideFlashObjects: Whether to hide Flash objects flag for an asset.
	// Applicable to the following creative types: all RICH_MEDIA.
	HideFlashObjects bool `json:"hideFlashObjects,omitempty"`

	// HideSelectionBoxes: Whether to hide selection boxes flag for an
	// asset. Applicable to the following creative types: all RICH_MEDIA.
	HideSelectionBoxes bool `json:"hideSelectionBoxes,omitempty"`

	// HorizontallyLocked: Whether the asset is horizontally locked. This is
	// a read-only field. Applicable to the following creative types: all
	// RICH_MEDIA.
	HorizontallyLocked bool `json:"horizontallyLocked,omitempty"`

	// Id: Numeric ID of this creative asset. This is a required field and
	// should not be modified. Applicable to all but the following creative
	// types: all REDIRECT and TRACKING_TEXT.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of the asset. This is a
	// read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// MediaDuration: Detected duration for audio or video asset. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_AUDIO, INSTREAM_VIDEO and all VPAID.
	MediaDuration float64 `json:"mediaDuration,omitempty"`

	// MimeType: Detected MIME type for audio or video asset. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_AUDIO, INSTREAM_VIDEO and all VPAID.
	MimeType string `json:"mimeType,omitempty"`

	// Offset: Offset position for an asset in collapsed mode. This is a
	// read-only field. Applicable to the following creative types: all
	// RICH_MEDIA and all VPAID. Additionally, only applicable to assets
	// whose displayType is ASSET_DISPLAY_TYPE_EXPANDING or
	// ASSET_DISPLAY_TYPE_PEEL_DOWN.
	Offset *OffsetPosition `json:"offset,omitempty"`

	// Orientation: Orientation of video asset. This is a read-only,
	// auto-generated field.
	//
	// Possible values:
	//   "LANDSCAPE"
	//   "PORTRAIT"
	//   "SQUARE"
	Orientation string `json:"orientation,omitempty"`

	// OriginalBackup: Whether the backup asset is original or changed by
	// the user in Campaign Manager. Applicable to the following creative
	// types: all RICH_MEDIA.
	OriginalBackup bool `json:"originalBackup,omitempty"`

	// PoliteLoad: Whether this asset is used as a polite load asset.
	PoliteLoad bool `json:"politeLoad,omitempty"`

	// Position: Offset position for an asset. Applicable to the following
	// creative types: all RICH_MEDIA.
	Position *OffsetPosition `json:"position,omitempty"`

	// PositionLeftUnit: Offset left unit for an asset. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "OFFSET_UNIT_PIXEL"
	//   "OFFSET_UNIT_PERCENT"
	//   "OFFSET_UNIT_PIXEL_FROM_CENTER"
	PositionLeftUnit string `json:"positionLeftUnit,omitempty"`

	// PositionTopUnit: Offset top unit for an asset. This is a read-only
	// field if the asset displayType is ASSET_DISPLAY_TYPE_OVERLAY.
	// Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "OFFSET_UNIT_PIXEL"
	//   "OFFSET_UNIT_PERCENT"
	//   "OFFSET_UNIT_PIXEL_FROM_CENTER"
	PositionTopUnit string `json:"positionTopUnit,omitempty"`

	// ProgressiveServingUrl: Progressive URL for video asset. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO and all VPAID.
	ProgressiveServingUrl string `json:"progressiveServingUrl,omitempty"`

	// Pushdown: Whether the asset pushes down other content. Applicable to
	// the following creative types: all RICH_MEDIA. Additionally, only
	// applicable when the asset offsets are 0, the collapsedSize.width
	// matches size.width, and the collapsedSize.height is less than
	// size.height.
	Pushdown bool `json:"pushdown,omitempty"`

	// PushdownDuration: Pushdown duration in seconds for an asset.
	// Applicable to the following creative types: all
	// RICH_MEDIA.Additionally, only applicable when the asset pushdown
	// field is true, the offsets are 0, the collapsedSize.width matches
	// size.width, and the collapsedSize.height is less than size.height.
	// Acceptable values are 0 to 9.99, inclusive.
	PushdownDuration float64 `json:"pushdownDuration,omitempty"`

	// Role: Role of the asset in relation to creative. Applicable to all
	// but the following creative types: all REDIRECT and TRACKING_TEXT.
	// This is a required field. PRIMARY applies to DISPLAY, FLASH_INPAGE,
	// HTML5_BANNER, IMAGE, DISPLAY_IMAGE_GALLERY, all RICH_MEDIA (which may
	// contain multiple primary assets), and all VPAID creatives.
	// BACKUP_IMAGE applies to FLASH_INPAGE, HTML5_BANNER, all RICH_MEDIA,
	// and all VPAID creatives. Applicable to DISPLAY when the primary asset
	// type is not HTML_IMAGE. ADDITIONAL_IMAGE and ADDITIONAL_FLASH apply
	// to FLASH_INPAGE creatives. OTHER refers to assets from sources other
	// than Campaign Manager, such as Studio uploaded assets, applicable to
	// all RICH_MEDIA and all VPAID creatives. PARENT_VIDEO refers to videos
	// uploaded by the user in Campaign Manager and is applicable to
	// INSTREAM_VIDEO and VPAID_LINEAR_VIDEO creatives. TRANSCODED_VIDEO
	// refers to videos transcoded by Campaign Manager from PARENT_VIDEO
	// assets and is applicable to INSTREAM_VIDEO and VPAID_LINEAR_VIDEO
	// creatives. ALTERNATE_VIDEO refers to the Campaign Manager
	// representation of child asset videos from Studio, and is applicable
	// to VPAID_LINEAR_VIDEO creatives. These cannot be added or removed
	// within Campaign Manager. For VPAID_LINEAR_VIDEO creatives,
	// PARENT_VIDEO, TRANSCODED_VIDEO and ALTERNATE_VIDEO assets that are
	// marked active serve as backup in case the VPAID creative cannot be
	// served. Only PARENT_VIDEO assets can be added or removed for an
	// INSTREAM_VIDEO or VPAID_LINEAR_VIDEO creative. PARENT_AUDIO refers to
	// audios uploaded by the user in Campaign Manager and is applicable to
	// INSTREAM_AUDIO creatives. TRANSCODED_AUDIO refers to audios
	// transcoded by Campaign Manager from PARENT_AUDIO assets and is
	// applicable to INSTREAM_AUDIO creatives.
	//
	// Possible values:
	//   "PRIMARY"
	//   "BACKUP_IMAGE"
	//   "ADDITIONAL_IMAGE"
	//   "ADDITIONAL_FLASH"
	//   "PARENT_VIDEO"
	//   "TRANSCODED_VIDEO"
	//   "OTHER"
	//   "ALTERNATE_VIDEO"
	//   "PARENT_AUDIO"
	//   "TRANSCODED_AUDIO"
	Role string `json:"role,omitempty"`

	// Size: Size associated with this creative asset. This is a required
	// field when applicable; however for IMAGE and FLASH_INPAGE, creatives
	// if left blank, this field will be automatically set using the actual
	// size of the associated image asset. Applicable to the following
	// creative types: DISPLAY_IMAGE_GALLERY, FLASH_INPAGE, HTML5_BANNER,
	// IMAGE, and all RICH_MEDIA. Applicable to DISPLAY when the primary
	// asset type is not HTML_IMAGE.
	Size *Size `json:"size,omitempty"`

	// SslCompliant: Whether the asset is SSL-compliant. This is a read-only
	// field. Applicable to all but the following creative types: all
	// REDIRECT and TRACKING_TEXT.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// StartTimeType: Initial wait time type before making the asset
	// visible. Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "ASSET_START_TIME_TYPE_NONE"
	//   "ASSET_START_TIME_TYPE_CUSTOM"
	StartTimeType string `json:"startTimeType,omitempty"`

	// StreamingServingUrl: Streaming URL for video asset. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO and all VPAID.
	StreamingServingUrl string `json:"streamingServingUrl,omitempty"`

	// Transparency: Whether the asset is transparent. Applicable to the
	// following creative types: all RICH_MEDIA. Additionally, only
	// applicable to HTML5 assets.
	Transparency bool `json:"transparency,omitempty"`

	// VerticallyLocked: Whether the asset is vertically locked. This is a
	// read-only field. Applicable to the following creative types: all
	// RICH_MEDIA.
	VerticallyLocked bool `json:"verticallyLocked,omitempty"`

	// WindowMode: Window mode options for flash assets. Applicable to the
	// following creative types: FLASH_INPAGE, RICH_MEDIA_DISPLAY_EXPANDING,
	// RICH_MEDIA_IM_EXPAND, RICH_MEDIA_DISPLAY_BANNER, and
	// RICH_MEDIA_INPAGE_FLOATING.
	//
	// Possible values:
	//   "OPAQUE"
	//   "WINDOW"
	//   "TRANSPARENT"
	WindowMode string `json:"windowMode,omitempty"`

	// ZIndex: zIndex value of an asset. Applicable to the following
	// creative types: all RICH_MEDIA.Additionally, only applicable to
	// assets whose displayType is NOT one of the following types:
	// ASSET_DISPLAY_TYPE_INPAGE or ASSET_DISPLAY_TYPE_OVERLAY. Acceptable
	// values are -999999999 to 999999999, inclusive.
	ZIndex int64 `json:"zIndex,omitempty"`

	// ZipFilename: File name of zip file. This is a read-only field.
	// Applicable to the following creative types: HTML5_BANNER.
	ZipFilename string `json:"zipFilename,omitempty"`

	// ZipFilesize: Size of zip file. This is a read-only field. Applicable
	// to the following creative types: HTML5_BANNER.
	ZipFilesize string `json:"zipFilesize,omitempty"`

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

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

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

func (s *CreativeAsset) UnmarshalJSON(data []byte) error {
	type NoMethod CreativeAsset
	var s1 struct {
		FrameRate        gensupport.JSONFloat64 `json:"frameRate"`
		MediaDuration    gensupport.JSONFloat64 `json:"mediaDuration"`
		PushdownDuration gensupport.JSONFloat64 `json:"pushdownDuration"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.FrameRate = float64(s1.FrameRate)
	s.MediaDuration = float64(s1.MediaDuration)
	s.PushdownDuration = float64(s1.PushdownDuration)
	return nil
}

// CreativeAssetId: Creative Asset ID.
type CreativeAssetId struct {
	// Name: Name of the creative asset. This is a required field while
	// inserting an asset. After insertion, this assetIdentifier is used to
	// identify the uploaded asset. Characters in the name must be
	// alphanumeric or one of the following: ".-_ ". Spaces are allowed.
	Name string `json:"name,omitempty"`

	// Type: Type of asset to upload. This is a required field. FLASH and
	// IMAGE are no longer supported for new uploads. All image assets
	// should use HTML_IMAGE.
	//
	// Possible values:
	//   "IMAGE"
	//   "FLASH"
	//   "VIDEO"
	//   "HTML"
	//   "HTML_IMAGE"
	//   "AUDIO"
	Type string `json:"type,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 *CreativeAssetId) MarshalJSON() ([]byte, error) {
	type NoMethod CreativeAssetId
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreativeAssetMetadata: CreativeAssets contains properties of a
// creative asset file which will be uploaded or has already been
// uploaded. Refer to the creative sample code for how to upload assets
// and insert a creative.
type CreativeAssetMetadata struct {
	// AssetIdentifier: ID of the creative asset. This is a required field.
	AssetIdentifier *CreativeAssetId `json:"assetIdentifier,omitempty"`

	// ClickTags: List of detected click tags for assets. This is a
	// read-only, auto-generated field. This field is empty for a rich media
	// asset.
	ClickTags []*ClickTag `json:"clickTags,omitempty"`

	// CounterCustomEvents: List of counter events configured for the asset.
	// This is a read-only, auto-generated field and only applicable to a
	// rich media asset.
	CounterCustomEvents []*CreativeCustomEvent `json:"counterCustomEvents,omitempty"`

	// DetectedFeatures: List of feature dependencies for the creative asset
	// that are detected by Campaign Manager. Feature dependencies are
	// features that a browser must be able to support in order to render
	// your HTML5 creative correctly. This is a read-only, auto-generated
	// field.
	//
	// Possible values:
	//   "CSS_FONT_FACE"
	//   "CSS_BACKGROUND_SIZE"
	//   "CSS_BORDER_IMAGE"
	//   "CSS_BORDER_RADIUS"
	//   "CSS_BOX_SHADOW"
	//   "CSS_FLEX_BOX"
	//   "CSS_HSLA"
	//   "CSS_MULTIPLE_BGS"
	//   "CSS_OPACITY"
	//   "CSS_RGBA"
	//   "CSS_TEXT_SHADOW"
	//   "CSS_ANIMATIONS"
	//   "CSS_COLUMNS"
	//   "CSS_GENERATED_CONTENT"
	//   "CSS_GRADIENTS"
	//   "CSS_REFLECTIONS"
	//   "CSS_TRANSFORMS"
	//   "CSS_TRANSFORMS3D"
	//   "CSS_TRANSITIONS"
	//   "APPLICATION_CACHE"
	//   "CANVAS"
	//   "CANVAS_TEXT"
	//   "DRAG_AND_DROP"
	//   "HASH_CHANGE"
	//   "HISTORY"
	//   "AUDIO"
	//   "VIDEO"
	//   "INDEXED_DB"
	//   "INPUT_ATTR_AUTOCOMPLETE"
	//   "INPUT_ATTR_AUTOFOCUS"
	//   "INPUT_ATTR_LIST"
	//   "INPUT_ATTR_PLACEHOLDER"
	//   "INPUT_ATTR_MAX"
	//   "INPUT_ATTR_MIN"
	//   "INPUT_ATTR_MULTIPLE"
	//   "INPUT_ATTR_PATTERN"
	//   "INPUT_ATTR_REQUIRED"
	//   "INPUT_ATTR_STEP"
	//   "INPUT_TYPE_SEARCH"
	//   "INPUT_TYPE_TEL"
	//   "INPUT_TYPE_URL"
	//   "INPUT_TYPE_EMAIL"
	//   "INPUT_TYPE_DATETIME"
	//   "INPUT_TYPE_DATE"
	//   "INPUT_TYPE_MONTH"
	//   "INPUT_TYPE_WEEK"
	//   "INPUT_TYPE_TIME"
	//   "INPUT_TYPE_DATETIME_LOCAL"
	//   "INPUT_TYPE_NUMBER"
	//   "INPUT_TYPE_RANGE"
	//   "INPUT_TYPE_COLOR"
	//   "LOCAL_STORAGE"
	//   "POST_MESSAGE"
	//   "SESSION_STORAGE"
	//   "WEB_SOCKETS"
	//   "WEB_SQL_DATABASE"
	//   "WEB_WORKERS"
	//   "GEO_LOCATION"
	//   "INLINE_SVG"
	//   "SMIL"
	//   "SVG_HREF"
	//   "SVG_CLIP_PATHS"
	//   "TOUCH"
	//   "WEBGL"
	//   "SVG_FILTERS"
	//   "SVG_FE_IMAGE"
	DetectedFeatures []string `json:"detectedFeatures,omitempty"`

	// ExitCustomEvents: List of exit events configured for the asset. This
	// is a read-only, auto-generated field and only applicable to a rich
	// media asset.
	ExitCustomEvents []*CreativeCustomEvent `json:"exitCustomEvents,omitempty"`

	// Id: Numeric ID of the asset. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the numeric ID of the asset.
	// This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeAssetMetadata".
	Kind string `json:"kind,omitempty"`

	// RichMedia: True if the uploaded asset is a rich media asset. This is
	// a read-only, auto-generated field.
	RichMedia bool `json:"richMedia,omitempty"`

	// TimerCustomEvents: List of timer events configured for the asset.
	// This is a read-only, auto-generated field and only applicable to a
	// rich media asset.
	TimerCustomEvents []*CreativeCustomEvent `json:"timerCustomEvents,omitempty"`

	// WarnedValidationRules: Rules validated during code generation that
	// generated a warning. This is a read-only, auto-generated field.
	// Possible values are: - "ADMOB_REFERENCED" -
	// "ASSET_FORMAT_UNSUPPORTED_DCM" - "ASSET_INVALID" -
	// "CLICK_TAG_HARD_CODED" - "CLICK_TAG_INVALID" - "CLICK_TAG_IN_GWD" -
	// "CLICK_TAG_MISSING" - "CLICK_TAG_MORE_THAN_ONE" -
	// "CLICK_TAG_NON_TOP_LEVEL" - "COMPONENT_UNSUPPORTED_DCM" -
	// "ENABLER_UNSUPPORTED_METHOD_DCM" - "EXTERNAL_FILE_REFERENCED" -
	// "FILE_DETAIL_EMPTY" - "FILE_TYPE_INVALID" - "GWD_PROPERTIES_INVALID"
	// - "HTML5_FEATURE_UNSUPPORTED" - "LINKED_FILE_NOT_FOUND" -
	// "MAX_FLASH_VERSION_11" - "MRAID_REFERENCED" - "NOT_SSL_COMPLIANT" -
	// "ORPHANED_ASSET" - "PRIMARY_HTML_MISSING" - "SVG_INVALID" -
	// "ZIP_INVALID"
	//
	// Possible values:
	//   "CLICK_TAG_NON_TOP_LEVEL"
	//   "CLICK_TAG_MISSING"
	//   "CLICK_TAG_MORE_THAN_ONE"
	//   "CLICK_TAG_INVALID"
	//   "ORPHANED_ASSET"
	//   "PRIMARY_HTML_MISSING"
	//   "EXTERNAL_FILE_REFERENCED"
	//   "MRAID_REFERENCED"
	//   "ADMOB_REFERENCED"
	//   "FILE_TYPE_INVALID"
	//   "ZIP_INVALID"
	//   "LINKED_FILE_NOT_FOUND"
	//   "MAX_FLASH_VERSION_11"
	//   "NOT_SSL_COMPLIANT"
	//   "FILE_DETAIL_EMPTY"
	//   "ASSET_INVALID"
	//   "GWD_PROPERTIES_INVALID"
	//   "ENABLER_UNSUPPORTED_METHOD_DCM"
	//   "ASSET_FORMAT_UNSUPPORTED_DCM"
	//   "COMPONENT_UNSUPPORTED_DCM"
	//   "HTML5_FEATURE_UNSUPPORTED"
	//   "CLICK_TAG_IN_GWD"
	//   "CLICK_TAG_HARD_CODED"
	//   "SVG_INVALID"
	WarnedValidationRules []string `json:"warnedValidationRules,omitempty"`

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

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

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

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

// CreativeAssetSelection: Encapsulates the list of rules for asset
// selection and a default asset in case none of the rules match.
// Applicable to INSTREAM_VIDEO creatives.
type CreativeAssetSelection struct {
	// DefaultAssetId: A creativeAssets[].id. This should refer to one of
	// the parent assets in this creative, and will be served if none of the
	// rules match. This is a required field.
	DefaultAssetId int64 `json:"defaultAssetId,omitempty,string"`

	// Rules: Rules determine which asset will be served to a viewer. Rules
	// will be evaluated in the order in which they are stored in this list.
	// This list must contain at least one rule. Applicable to
	// INSTREAM_VIDEO creatives.
	Rules []*Rule `json:"rules,omitempty"`

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

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

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

// CreativeAssignment: Creative Assignment.
type CreativeAssignment struct {
	// Active: Whether this creative assignment is active. When true, the
	// creative will be included in the ad's rotation.
	Active bool `json:"active,omitempty"`

	// ApplyEventTags: Whether applicable event tags should fire when this
	// creative assignment is rendered. If this value is unset when the ad
	// is inserted or updated, it will default to true for all creative
	// types EXCEPT for INTERNAL_REDIRECT, INTERSTITIAL_INTERNAL_REDIRECT,
	// and INSTREAM_VIDEO.
	ApplyEventTags bool `json:"applyEventTags,omitempty"`

	// ClickThroughUrl: Click-through URL of the creative assignment.
	ClickThroughUrl *ClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// CompanionCreativeOverrides: Companion creative overrides for this
	// creative assignment. Applicable to video ads.
	CompanionCreativeOverrides []*CompanionClickThroughOverride `json:"companionCreativeOverrides,omitempty"`

	// CreativeGroupAssignments: Creative group assignments for this
	// creative assignment. Only one assignment per creative group number is
	// allowed for a maximum of two assignments.
	CreativeGroupAssignments []*CreativeGroupAssignment `json:"creativeGroupAssignments,omitempty"`

	// CreativeId: ID of the creative to be assigned. This is a required
	// field.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// CreativeIdDimensionValue: Dimension value for the ID of the creative.
	// This is a read-only, auto-generated field.
	CreativeIdDimensionValue *DimensionValue `json:"creativeIdDimensionValue,omitempty"`

	EndTime string `json:"endTime,omitempty"`

	// RichMediaExitOverrides: Rich media exit overrides for this creative
	// assignment. Applicable when the creative type is any of the
	// following: - DISPLAY - RICH_MEDIA_INPAGE - RICH_MEDIA_INPAGE_FLOATING
	// - RICH_MEDIA_IM_EXPAND - RICH_MEDIA_EXPANDING -
	// RICH_MEDIA_INTERSTITIAL_FLOAT - RICH_MEDIA_MOBILE_IN_APP -
	// RICH_MEDIA_MULTI_FLOATING - RICH_MEDIA_PEEL_DOWN - VPAID_LINEAR -
	// VPAID_NON_LINEAR
	RichMediaExitOverrides []*RichMediaExitOverride `json:"richMediaExitOverrides,omitempty"`

	// Sequence: Sequence number of the creative assignment, applicable when
	// the rotation type is CREATIVE_ROTATION_TYPE_SEQUENTIAL. Acceptable
	// values are 1 to 65535, inclusive.
	Sequence int64 `json:"sequence,omitempty"`

	// SslCompliant: Whether the creative to be assigned is SSL-compliant.
	// This is a read-only field that is auto-generated when the ad is
	// inserted or updated.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	StartTime string `json:"startTime,omitempty"`

	// Weight: Weight of the creative assignment, applicable when the
	// rotation type is CREATIVE_ROTATION_TYPE_RANDOM. Value must be greater
	// than or equal to 1.
	Weight int64 `json:"weight,omitempty"`

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

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

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

// CreativeClickThroughUrl: Click-through URL
type CreativeClickThroughUrl struct {
	// ComputedClickThroughUrl: Read-only convenience field representing the
	// actual URL that will be used for this click-through. The URL is
	// computed as follows: - If landingPageId is specified then that
	// landing page's URL is assigned to this field. - Otherwise, the
	// customClickThroughUrl is assigned to this field.
	ComputedClickThroughUrl string `json:"computedClickThroughUrl,omitempty"`

	// CustomClickThroughUrl: Custom click-through URL. Applicable if the
	// landingPageId field is left unset.
	CustomClickThroughUrl string `json:"customClickThroughUrl,omitempty"`

	// LandingPageId: ID of the landing page for the click-through URL.
	LandingPageId int64 `json:"landingPageId,omitempty,string"`

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

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

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

// CreativeCustomEvent: Creative Custom Event.
type CreativeCustomEvent struct {
	// AdvertiserCustomEventId: Unique ID of this event used by Reporting
	// and Data Transfer. This is a read-only field.
	AdvertiserCustomEventId int64 `json:"advertiserCustomEventId,omitempty,string"`

	// AdvertiserCustomEventName: User-entered name for the event.
	AdvertiserCustomEventName string `json:"advertiserCustomEventName,omitempty"`

	// AdvertiserCustomEventType: Type of the event. This is a read-only
	// field.
	//
	// Possible values:
	//   "ADVERTISER_EVENT_TIMER"
	//   "ADVERTISER_EVENT_EXIT"
	//   "ADVERTISER_EVENT_COUNTER"
	AdvertiserCustomEventType string `json:"advertiserCustomEventType,omitempty"`

	// ArtworkLabel: Artwork label column, used to link events in Campaign
	// Manager back to events in Studio. This is a required field and should
	// not be modified after insertion.
	ArtworkLabel string `json:"artworkLabel,omitempty"`

	// ArtworkType: Artwork type used by the creative.This is a read-only
	// field.
	//
	// Possible values:
	//   "ARTWORK_TYPE_FLASH"
	//   "ARTWORK_TYPE_HTML5"
	//   "ARTWORK_TYPE_MIXED"
	//   "ARTWORK_TYPE_IMAGE"
	ArtworkType string `json:"artworkType,omitempty"`

	// ExitClickThroughUrl: Exit click-through URL for the event. This field
	// is used only for exit events.
	ExitClickThroughUrl *CreativeClickThroughUrl `json:"exitClickThroughUrl,omitempty"`

	// Id: ID of this event. This is a required field and should not be
	// modified after insertion.
	Id int64 `json:"id,omitempty,string"`

	// PopupWindowProperties: Properties for rich media popup windows. This
	// field is used only for exit events.
	PopupWindowProperties *PopupWindowProperties `json:"popupWindowProperties,omitempty"`

	// TargetType: Target type used by the event.
	//
	// Possible values:
	//   "TARGET_BLANK"
	//   "TARGET_TOP"
	//   "TARGET_SELF"
	//   "TARGET_PARENT"
	//   "TARGET_POPUP"
	TargetType string `json:"targetType,omitempty"`

	// VideoReportingId: Video reporting ID, used to differentiate multiple
	// videos in a single creative. This is a read-only field.
	VideoReportingId string `json:"videoReportingId,omitempty"`

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

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

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

// CreativeField: Contains properties of a creative field.
type CreativeField struct {
	// AccountId: Account ID of this creative field. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this creative field. This is a
	// required field on insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Id: ID of this creative field. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeField".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this creative field. This is a required field and must
	// be less than 256 characters long and unique among creative fields of
	// the same advertiser.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this creative field. This is a
	// read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// CreativeFieldAssignment: Creative Field Assignment.
type CreativeFieldAssignment struct {
	// CreativeFieldId: ID of the creative field.
	CreativeFieldId int64 `json:"creativeFieldId,omitempty,string"`

	// CreativeFieldValueId: ID of the creative field value.
	CreativeFieldValueId int64 `json:"creativeFieldValueId,omitempty,string"`

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

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

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

// CreativeFieldValue: Contains properties of a creative field value.
type CreativeFieldValue struct {
	// Id: ID of this creative field value. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeFieldValue".
	Kind string `json:"kind,omitempty"`

	// Value: Value of this creative field value. It needs to be less than
	// 256 characters in length and unique per creative field.
	Value string `json:"value,omitempty"`

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

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

// CreativeFieldValuesListResponse: Creative Field Value List Response
type CreativeFieldValuesListResponse struct {
	// CreativeFieldValues: Creative field value collection.
	CreativeFieldValues []*CreativeFieldValue `json:"creativeFieldValues,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeFieldValuesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "CreativeFieldValues")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// CreativeFieldsListResponse: Creative Field List Response
type CreativeFieldsListResponse struct {
	// CreativeFields: Creative field collection.
	CreativeFields []*CreativeField `json:"creativeFields,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeFieldsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "CreativeFields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// CreativeGroup: Contains properties of a creative group.
type CreativeGroup struct {
	// AccountId: Account ID of this creative group. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this creative group. This is a
	// required field on insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// GroupNumber: Subgroup of the creative group. Assign your creative
	// groups to a subgroup in order to filter or manage them more easily.
	// This field is required on insertion and is read-only after insertion.
	// Acceptable values are 1 to 2, inclusive.
	GroupNumber int64 `json:"groupNumber,omitempty"`

	// Id: ID of this creative group. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this creative group. This is a required field and must
	// be less than 256 characters long and unique among creative groups of
	// the same advertiser.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this creative group. This is a
	// read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// CreativeGroupAssignment: Creative Group Assignment.
type CreativeGroupAssignment struct {
	// CreativeGroupId: ID of the creative group to be assigned.
	CreativeGroupId int64 `json:"creativeGroupId,omitempty,string"`

	// CreativeGroupNumber: Creative group number of the creative group
	// assignment.
	//
	// Possible values:
	//   "CREATIVE_GROUP_ONE"
	//   "CREATIVE_GROUP_TWO"
	CreativeGroupNumber string `json:"creativeGroupNumber,omitempty"`

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

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

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

// CreativeGroupsListResponse: Creative Group List Response
type CreativeGroupsListResponse struct {
	// CreativeGroups: Creative group collection.
	CreativeGroups []*CreativeGroup `json:"creativeGroups,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "CreativeGroups") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// CreativeOptimizationConfiguration: Creative optimization settings.
type CreativeOptimizationConfiguration struct {
	// Id: ID of this creative optimization config. This field is
	// auto-generated when the campaign is inserted or updated. It can be
	// null for existing campaigns.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of this creative optimization config. This is a required
	// field and must be less than 129 characters long.
	Name string `json:"name,omitempty"`

	// OptimizationActivitys: List of optimization activities associated
	// with this configuration.
	OptimizationActivitys []*OptimizationActivity `json:"optimizationActivitys,omitempty"`

	// OptimizationModel: Optimization model for this configuration.
	//
	// Possible values:
	//   "CLICK"
	//   "POST_CLICK"
	//   "POST_IMPRESSION"
	//   "POST_CLICK_AND_IMPRESSION"
	//   "VIDEO_COMPLETION"
	OptimizationModel string `json:"optimizationModel,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 *CreativeOptimizationConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod CreativeOptimizationConfiguration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreativeRotation: Creative Rotation.
type CreativeRotation struct {
	// CreativeAssignments: Creative assignments in this creative rotation.
	CreativeAssignments []*CreativeAssignment `json:"creativeAssignments,omitempty"`

	// CreativeOptimizationConfigurationId: Creative optimization
	// configuration that is used by this ad. It should refer to one of the
	// existing optimization configurations in the ad's campaign. If it is
	// unset or set to 0, then the campaign's default optimization
	// configuration will be used for this ad.
	CreativeOptimizationConfigurationId int64 `json:"creativeOptimizationConfigurationId,omitempty,string"`

	// Type: Type of creative rotation. Can be used to specify whether to
	// use sequential or random rotation.
	//
	// Possible values:
	//   "CREATIVE_ROTATION_TYPE_SEQUENTIAL"
	//   "CREATIVE_ROTATION_TYPE_RANDOM"
	Type string `json:"type,omitempty"`

	// WeightCalculationStrategy: Strategy for calculating weights. Used
	// with CREATIVE_ROTATION_TYPE_RANDOM.
	//
	// Possible values:
	//   "WEIGHT_STRATEGY_EQUAL"
	//   "WEIGHT_STRATEGY_CUSTOM"
	//   "WEIGHT_STRATEGY_HIGHEST_CTR"
	//   "WEIGHT_STRATEGY_OPTIMIZED"
	WeightCalculationStrategy string `json:"weightCalculationStrategy,omitempty"`

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

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

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

// CreativesListResponse: Creative List Response
type CreativesListResponse struct {
	// Creatives: Creative collection.
	Creatives []*Creative `json:"creatives,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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 *CreativesListResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreativesListResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CrossDimensionReachReportCompatibleFields: Represents fields that are
// compatible to be selected for a report of type
// "CROSS_DIMENSION_REACH".
type CrossDimensionReachReportCompatibleFields struct {
	// Breakdown: Dimensions which are compatible to be selected in the
	// "breakdown" section of the report.
	Breakdown []*Dimension `json:"breakdown,omitempty"`

	// DimensionFilters: Dimensions which are compatible to be selected in
	// the "dimensionFilters" section of the report.
	DimensionFilters []*Dimension `json:"dimensionFilters,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#crossDimensionReachReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// OverlapMetrics: Metrics which are compatible to be selected in the
	// "overlapMetricNames" section of the report.
	OverlapMetrics []*Metric `json:"overlapMetrics,omitempty"`

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

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

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

// CustomEvent: Experimental feature (no support provided) A custom
// event represents a third party impression, a third party click, an
// annotation on a first party impression, or an annotation on a first
// party click.
type CustomEvent struct {
	// AnnotateClickEvent: Annotate a click event. This field is mutually
	// exclusive with insertEvent and annotateImpressionEvent. This or
	// insertEvent and annotateImpressionEvent is a required field.
	AnnotateClickEvent *CustomEventClickAnnotation `json:"annotateClickEvent,omitempty"`

	// AnnotateImpressionEvent: Annotate an impression. This field is
	// mutually exclusive with insertEvent and annotateClickEvent. This or
	// insertEvent and annotateClickEvent is a required field.
	AnnotateImpressionEvent *CustomEventImpressionAnnotation `json:"annotateImpressionEvent,omitempty"`

	// CustomVariables: Custom variables associated with the event.
	CustomVariables []*CustomVariable `json:"customVariables,omitempty"`

	// EventType: The type of event. If INSERT, the fields in insertEvent
	// need to be populated. If ANNOTATE, the fields in either
	// annotateClickEvent or annotateImpressionEvent need to be populated.
	//
	// Possible values:
	//   "UNKNOWN"
	//   "INSERT"
	//   "ANNOTATE"
	EventType string `json:"eventType,omitempty"`

	// FloodlightConfigurationId: Floodlight configuration ID of the
	// advertiser the event is linked to. This is a required field.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

	// InsertEvent: Insert custom event. This field is mutually exclusive
	// with annotateClickEvent and annotateImpressionEvent. This or
	// annotateClickEvent and annotateImpressionEvent is a required field.
	InsertEvent *CustomEventInsert `json:"insertEvent,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customEvent".
	Kind string `json:"kind,omitempty"`

	// Ordinal: The ordinal of this custom event. This is a required field.
	Ordinal string `json:"ordinal,omitempty"`

	// TimestampMicros: The timestamp of this custom event, in Unix epoch
	// micros. This is a required field.
	TimestampMicros int64 `json:"timestampMicros,omitempty,string"`

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

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

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

// CustomEventClickAnnotation: Annotate a click event.
type CustomEventClickAnnotation struct {
	// Gclid: The Google click ID. Use this field to annotate the click
	// associated with the gclid.
	Gclid string `json:"gclid,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customEventClickAnnotation".
	Kind string `json:"kind,omitempty"`

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

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

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

// CustomEventError: The error code and description for a custom event
// that failed to insert.
type CustomEventError struct {
	// Code: The error code.
	//
	// Possible values:
	//   "UNKNOWN"
	//   "INVALID_ARGUMENT"
	//   "INTERNAL"
	//   "PERMISSION_DENIED"
	//   "NOT_FOUND"
	Code string `json:"code,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customEventError".
	Kind string `json:"kind,omitempty"`

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

// CustomEventImpressionAnnotation: Annotate an impression.
type CustomEventImpressionAnnotation struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customEventImpressionAnnotation".
	Kind string `json:"kind,omitempty"`

	// PathImpressionId: The path impression ID. Use this field to annotate
	// the impression associated with the pathImpressionId.
	PathImpressionId string `json:"pathImpressionId,omitempty"`

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

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

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

// CustomEventInsert: Custom event to be inserted.
type CustomEventInsert struct {
	// CmDimensions: Campaign Manager dimensions associated with the event.
	CmDimensions *CampaignManagerIds `json:"cmDimensions,omitempty"`

	// Dv3Dimensions: DV360 dimensions associated with the event.
	Dv3Dimensions *DV3Ids `json:"dv3Dimensions,omitempty"`

	// InsertEventType: The type of event to insert.
	//
	// Possible values:
	//   "UNKNOWN"
	//   "IMPRESSION"
	//   "CLICK"
	InsertEventType string `json:"insertEventType,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customEventInsert".
	Kind string `json:"kind,omitempty"`

	// MatchId: The match ID field. A match ID is your own first-party
	// identifier that has been synced with Google using the match ID
	// feature in Floodlight. This field is mutually exclusive with
	// mobileDeviceId, and at least one of the two fields is required.
	MatchId string `json:"matchId,omitempty"`

	// MobileDeviceId: The mobile device ID. This field is mutually
	// exclusive with matchId, and at least one of the two fields is
	// required.
	MobileDeviceId string `json:"mobileDeviceId,omitempty"`

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

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

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

// CustomEventStatus: The original custom event that was inserted and
// whether there were any errors.
type CustomEventStatus struct {
	// CustomEvent: The original custom event that was inserted.
	CustomEvent *CustomEvent `json:"customEvent,omitempty"`

	// Errors: A list of errors related to this custom event.
	Errors []*CustomEventError `json:"errors,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customEventStatus".
	Kind string `json:"kind,omitempty"`

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

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

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

// CustomEventsBatchInsertRequest: Insert Custom Events Request.
type CustomEventsBatchInsertRequest struct {
	// CustomEvents: The set of custom events to insert.
	CustomEvents []*CustomEvent `json:"customEvents,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customEventsBatchInsertRequest".
	Kind string `json:"kind,omitempty"`

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

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

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

// CustomEventsBatchInsertResponse: Insert Custom Events Response.
type CustomEventsBatchInsertResponse struct {
	// HasFailures: Indicates that some or all custom events failed to
	// insert.
	HasFailures bool `json:"hasFailures,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customEventsBatchInsertResponse".
	Kind string `json:"kind,omitempty"`

	// Status: The insert status of each custom event. Statuses are returned
	// in the same order that conversions are inserted.
	Status []*CustomEventStatus `json:"status,omitempty"`

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

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

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

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

// CustomFloodlightVariable: A custom floodlight variable.
type CustomFloodlightVariable struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customFloodlightVariable".
	Kind string `json:"kind,omitempty"`

	// Type: The type of custom floodlight variable to supply a value for.
	// These map to the "u[1-20]=" in the tags.
	//
	// Possible values:
	//   "U1"
	//   "U2"
	//   "U3"
	//   "U4"
	//   "U5"
	//   "U6"
	//   "U7"
	//   "U8"
	//   "U9"
	//   "U10"
	//   "U11"
	//   "U12"
	//   "U13"
	//   "U14"
	//   "U15"
	//   "U16"
	//   "U17"
	//   "U18"
	//   "U19"
	//   "U20"
	//   "U21"
	//   "U22"
	//   "U23"
	//   "U24"
	//   "U25"
	//   "U26"
	//   "U27"
	//   "U28"
	//   "U29"
	//   "U30"
	//   "U31"
	//   "U32"
	//   "U33"
	//   "U34"
	//   "U35"
	//   "U36"
	//   "U37"
	//   "U38"
	//   "U39"
	//   "U40"
	//   "U41"
	//   "U42"
	//   "U43"
	//   "U44"
	//   "U45"
	//   "U46"
	//   "U47"
	//   "U48"
	//   "U49"
	//   "U50"
	//   "U51"
	//   "U52"
	//   "U53"
	//   "U54"
	//   "U55"
	//   "U56"
	//   "U57"
	//   "U58"
	//   "U59"
	//   "U60"
	//   "U61"
	//   "U62"
	//   "U63"
	//   "U64"
	//   "U65"
	//   "U66"
	//   "U67"
	//   "U68"
	//   "U69"
	//   "U70"
	//   "U71"
	//   "U72"
	//   "U73"
	//   "U74"
	//   "U75"
	//   "U76"
	//   "U77"
	//   "U78"
	//   "U79"
	//   "U80"
	//   "U81"
	//   "U82"
	//   "U83"
	//   "U84"
	//   "U85"
	//   "U86"
	//   "U87"
	//   "U88"
	//   "U89"
	//   "U90"
	//   "U91"
	//   "U92"
	//   "U93"
	//   "U94"
	//   "U95"
	//   "U96"
	//   "U97"
	//   "U98"
	//   "U99"
	//   "U100"
	Type string `json:"type,omitempty"`

	// Value: The value of the custom floodlight variable. The length of
	// string must not exceed 50 characters.
	Value string `json:"value,omitempty"`

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

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

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

// CustomRichMediaEvents: Represents a Custom Rich Media Events group.
type CustomRichMediaEvents struct {
	// FilteredEventIds: List of custom rich media event IDs. Dimension
	// values must be all of type dfa:richMediaEventTypeIdAndName.
	FilteredEventIds []*DimensionValue `json:"filteredEventIds,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#customRichMediaEvents.
	Kind string `json:"kind,omitempty"`

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

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

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

// CustomVariable: Custom variable.
type CustomVariable struct {
	// Index: The index of the custom variable.
	Index int64 `json:"index,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customVariable".
	Kind string `json:"kind,omitempty"`

	// Value: The value of the custom variable. The length of string must
	// not exceed 50 characters.
	Value string `json:"value,omitempty"`

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

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

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

// CustomViewabilityMetric: Custom Viewability Metric
type CustomViewabilityMetric struct {
	// Configuration: Configuration of the custom viewability metric.
	Configuration *CustomViewabilityMetricConfiguration `json:"configuration,omitempty"`

	// Id: ID of the custom viewability metric.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of the custom viewability metric.
	Name string `json:"name,omitempty"`

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

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

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

// CustomViewabilityMetricConfiguration: The attributes, like playtime
// and percent onscreen, that define the Custom Viewability Metric.
type CustomViewabilityMetricConfiguration struct {
	// Audible: Whether the video must be audible to count an impression.
	Audible bool `json:"audible,omitempty"`

	// TimeMillis: The time in milliseconds the video must play for the
	// Custom Viewability Metric to count an impression. If both this and
	// timePercent are specified, the earlier of the two will be used.
	TimeMillis int64 `json:"timeMillis,omitempty"`

	// TimePercent: The percentage of video that must play for the Custom
	// Viewability Metric to count an impression. If both this and
	// timeMillis are specified, the earlier of the two will be used.
	TimePercent int64 `json:"timePercent,omitempty"`

	// ViewabilityPercent: The percentage of video that must be on screen
	// for the Custom Viewability Metric to count an impression.
	ViewabilityPercent int64 `json:"viewabilityPercent,omitempty"`

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

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

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

// DV3Ids: DV360 IDs related to the custom event.
type DV3Ids struct {
	// DvCampaignId: Campaign ID for DV360.
	DvCampaignId int64 `json:"dvCampaignId,omitempty,string"`

	// DvCreativeId: Creative ID for DV360.
	DvCreativeId int64 `json:"dvCreativeId,omitempty,string"`

	// DvInsertionOrderId: Insertion Order ID for DV360.
	DvInsertionOrderId int64 `json:"dvInsertionOrderId,omitempty,string"`

	// DvLineItemId: Line Item ID for DV360.
	DvLineItemId int64 `json:"dvLineItemId,omitempty,string"`

	// DvSiteId: Site ID for DV360.
	DvSiteId int64 `json:"dvSiteId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#dV3Ids".
	Kind string `json:"kind,omitempty"`

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

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

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

// DateRange: Represents a date range.
type DateRange struct {
	EndDate string `json:"endDate,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#dateRange.
	Kind string `json:"kind,omitempty"`

	// RelativeDateRange: The date range relative to the date of when the
	// report is run.
	//
	// Possible values:
	//   "TODAY"
	//   "YESTERDAY"
	//   "WEEK_TO_DATE"
	//   "MONTH_TO_DATE"
	//   "QUARTER_TO_DATE"
	//   "YEAR_TO_DATE"
	//   "PREVIOUS_WEEK"
	//   "PREVIOUS_MONTH"
	//   "PREVIOUS_QUARTER"
	//   "PREVIOUS_YEAR"
	//   "LAST_7_DAYS"
	//   "LAST_30_DAYS"
	//   "LAST_90_DAYS"
	//   "LAST_365_DAYS"
	//   "LAST_24_MONTHS"
	//   "LAST_14_DAYS"
	//   "LAST_60_DAYS"
	RelativeDateRange string `json:"relativeDateRange,omitempty"`

	StartDate string `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)
}

// DayPartTargeting: Day Part Targeting.
type DayPartTargeting struct {
	// DaysOfWeek: Days of the week when the ad will serve. Acceptable
	// values are: - "SUNDAY" - "MONDAY" - "TUESDAY" - "WEDNESDAY" -
	// "THURSDAY" - "FRIDAY" - "SATURDAY"
	//
	// Possible values:
	//   "MONDAY"
	//   "TUESDAY"
	//   "WEDNESDAY"
	//   "THURSDAY"
	//   "FRIDAY"
	//   "SATURDAY"
	//   "SUNDAY"
	DaysOfWeek []string `json:"daysOfWeek,omitempty"`

	// HoursOfDay: Hours of the day when the ad will serve, where 0 is
	// midnight to 1 AM and 23 is 11 PM to midnight. Can be specified with
	// days of week, in which case the ad would serve during these hours on
	// the specified days. For example if Monday, Wednesday, Friday are the
	// days of week specified and 9-10am, 3-5pm (hours 9, 15, and 16) is
	// specified, the ad would serve Monday, Wednesdays, and Fridays at
	// 9-10am and 3-5pm. Acceptable values are 0 to 23, inclusive.
	HoursOfDay []int64 `json:"hoursOfDay,omitempty"`

	// UserLocalTime: Whether or not to use the user's local time. If false,
	// the America/New York time zone applies.
	UserLocalTime bool `json:"userLocalTime,omitempty"`

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

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

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

// DeepLink: Contains information about a landing page deep link.
type DeepLink struct {
	// AppUrl: The URL of the mobile app being linked to.
	AppUrl string `json:"appUrl,omitempty"`

	// FallbackUrl: The fallback URL. This URL will be served to users who
	// do not have the mobile app installed.
	FallbackUrl string `json:"fallbackUrl,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#deepLink".
	Kind string `json:"kind,omitempty"`

	// MobileApp: The mobile app targeted by this deep link.
	MobileApp *MobileApp `json:"mobileApp,omitempty"`

	// RemarketingListIds: Ads served to users on these remarketing lists
	// will use this deep link. Applicable when mobileApp.directory is
	// APPLE_APP_STORE.
	RemarketingListIds googleapi.Int64s `json:"remarketingListIds,omitempty"`

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

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

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

// DefaultClickThroughEventTagProperties: Properties of inheriting and
// overriding the default click-through event tag. A campaign may
// override the event tag defined at the advertiser level, and an ad may
// also override the campaign's setting further.
type DefaultClickThroughEventTagProperties struct {
	// DefaultClickThroughEventTagId: ID of the click-through event tag to
	// apply to all ads in this entity's scope.
	DefaultClickThroughEventTagId int64 `json:"defaultClickThroughEventTagId,omitempty,string"`

	// OverrideInheritedEventTag: Whether this entity should override the
	// inherited default click-through event tag with its own defined value.
	OverrideInheritedEventTag bool `json:"overrideInheritedEventTag,omitempty"`

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

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

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

// DeliverySchedule: Delivery Schedule.
type DeliverySchedule struct {
	// FrequencyCap: Limit on the number of times an individual user can be
	// served the ad within a specified period of time.
	FrequencyCap *FrequencyCap `json:"frequencyCap,omitempty"`

	// HardCutoff: Whether or not hard cutoff is enabled. If true, the ad
	// will not serve after the end date and time. Otherwise the ad will
	// continue to be served until it has reached its delivery goals.
	HardCutoff bool `json:"hardCutoff,omitempty"`

	// ImpressionRatio: Impression ratio for this ad. This ratio determines
	// how often each ad is served relative to the others. For example, if
	// ad A has an impression ratio of 1 and ad B has an impression ratio of
	// 3, then Campaign Manager will serve ad B three times as often as ad
	// A. Acceptable values are 1 to 10, inclusive.
	ImpressionRatio int64 `json:"impressionRatio,omitempty,string"`

	// Priority: Serving priority of an ad, with respect to other ads. The
	// lower the priority number, the greater the priority with which it is
	// served.
	//
	// Possible values:
	//   "AD_PRIORITY_01"
	//   "AD_PRIORITY_02"
	//   "AD_PRIORITY_03"
	//   "AD_PRIORITY_04"
	//   "AD_PRIORITY_05"
	//   "AD_PRIORITY_06"
	//   "AD_PRIORITY_07"
	//   "AD_PRIORITY_08"
	//   "AD_PRIORITY_09"
	//   "AD_PRIORITY_10"
	//   "AD_PRIORITY_11"
	//   "AD_PRIORITY_12"
	//   "AD_PRIORITY_13"
	//   "AD_PRIORITY_14"
	//   "AD_PRIORITY_15"
	//   "AD_PRIORITY_16"
	Priority string `json:"priority,omitempty"`

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

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

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

// DfpSettings: Google Ad Manager Settings
type DfpSettings struct {
	// DfpNetworkCode: Ad Manager network code for this directory site.
	DfpNetworkCode string `json:"dfpNetworkCode,omitempty"`

	// DfpNetworkName: Ad Manager network name for this directory site.
	DfpNetworkName string `json:"dfpNetworkName,omitempty"`

	// ProgrammaticPlacementAccepted: Whether this directory site accepts
	// programmatic placements.
	ProgrammaticPlacementAccepted bool `json:"programmaticPlacementAccepted,omitempty"`

	// PubPaidPlacementAccepted: Whether this directory site accepts
	// publisher-paid tags.
	PubPaidPlacementAccepted bool `json:"pubPaidPlacementAccepted,omitempty"`

	// PublisherPortalOnly: Whether this directory site is available only
	// via Publisher Portal.
	PublisherPortalOnly bool `json:"publisherPortalOnly,omitempty"`

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

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

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

// Dimension: Represents a dimension.
type Dimension struct {
	// Kind: The kind of resource this is, in this case
	// dfareporting#dimension.
	Kind string `json:"kind,omitempty"`

	// Name: The dimension name, e.g. dfa:advertiser
	Name string `json:"name,omitempty"`

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

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

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

// DimensionFilter: Represents a dimension filter.
type DimensionFilter struct {
	// DimensionName: The name of the dimension to filter.
	DimensionName string `json:"dimensionName,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#dimensionFilter.
	Kind string `json:"kind,omitempty"`

	// Value: The value of the dimension to filter.
	Value string `json:"value,omitempty"`

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

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

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

// DimensionValue: Represents a DimensionValue resource.
type DimensionValue struct {
	// DimensionName: The name of the dimension.
	DimensionName string `json:"dimensionName,omitempty"`

	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Id: The ID associated with the value if available.
	Id string `json:"id,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#dimensionValue.
	Kind string `json:"kind,omitempty"`

	// MatchType: Determines how the 'value' field is matched when
	// filtering. If not specified, defaults to EXACT. If set to
	// WILDCARD_EXPRESSION, '*' is allowed as a placeholder for variable
	// length character sequences, and it can be escaped with a backslash.
	// Note, only paid search dimensions ('dfa:paidSearch*') allow a
	// matchType other than EXACT.
	//
	// Possible values:
	//   "EXACT"
	//   "BEGINS_WITH"
	//   "CONTAINS"
	//   "WILDCARD_EXPRESSION"
	MatchType string `json:"matchType,omitempty"`

	// Value: The value of the dimension.
	Value string `json:"value,omitempty"`

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

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

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

// DimensionValueList: Represents the list of DimensionValue resources.
type DimensionValueList struct {
	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Items: The dimension values returned in this response.
	Items []*DimensionValue `json:"items,omitempty"`

	// Kind: The kind of list this is, in this case
	// dfareporting#dimensionValueList.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Continuation token used to page through dimension
	// values. To retrieve the next page of results, set the next request's
	// "pageToken" to the value of this field. The page token is only valid
	// for a limited amount of time and should not be persisted.
	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. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// DimensionValueRequest: Represents a DimensionValuesRequest.
type DimensionValueRequest struct {
	// DimensionName: The name of the dimension for which values should be
	// requested.
	DimensionName string `json:"dimensionName,omitempty"`

	EndDate string `json:"endDate,omitempty"`

	// Filters: The list of filters by which to filter values. The filters
	// are ANDed.
	Filters []*DimensionFilter `json:"filters,omitempty"`

	// Kind: The kind of request this is, in this case
	// dfareporting#dimensionValueRequest .
	Kind string `json:"kind,omitempty"`

	StartDate string `json:"startDate,omitempty"`

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

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

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

// DirectorySite: DirectorySites contains properties of a website from
// the Site Directory. Sites need to be added to an account via the
// Sites resource before they can be assigned to a placement.
type DirectorySite struct {
	// Id: ID of this directory site. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this directory site.
	// This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// InpageTagFormats: Tag types for regular placements. Acceptable values
	// are: - "STANDARD" - "IFRAME_JAVASCRIPT_INPAGE" -
	// "INTERNAL_REDIRECT_INPAGE" - "JAVASCRIPT_INPAGE"
	//
	// Possible values:
	//   "STANDARD"
	//   "IFRAME_JAVASCRIPT_INPAGE"
	//   "INTERNAL_REDIRECT_INPAGE"
	//   "JAVASCRIPT_INPAGE"
	InpageTagFormats []string `json:"inpageTagFormats,omitempty"`

	// InterstitialTagFormats: Tag types for interstitial placements.
	// Acceptable values are: - "IFRAME_JAVASCRIPT_INTERSTITIAL" -
	// "INTERNAL_REDIRECT_INTERSTITIAL" - "JAVASCRIPT_INTERSTITIAL"
	//
	// Possible values:
	//   "IFRAME_JAVASCRIPT_INTERSTITIAL"
	//   "INTERNAL_REDIRECT_INTERSTITIAL"
	//   "JAVASCRIPT_INTERSTITIAL"
	InterstitialTagFormats []string `json:"interstitialTagFormats,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#directorySite".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this directory site.
	Name string `json:"name,omitempty"`

	// Settings: Directory site settings.
	Settings *DirectorySiteSettings `json:"settings,omitempty"`

	// Url: URL of this directory site.
	Url string `json:"url,omitempty"`

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

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

// DirectorySiteSettings: Directory Site Settings
type DirectorySiteSettings struct {
	// ActiveViewOptOut: Whether this directory site has disabled active
	// view creatives.
	ActiveViewOptOut bool `json:"activeViewOptOut,omitempty"`

	// DfpSettings: Directory site Ad Manager settings.
	DfpSettings *DfpSettings `json:"dfpSettings,omitempty"`

	// InstreamVideoPlacementAccepted: Whether this site accepts in-stream
	// video ads.
	InstreamVideoPlacementAccepted bool `json:"instreamVideoPlacementAccepted,omitempty"`

	// InterstitialPlacementAccepted: Whether this site accepts interstitial
	// ads.
	InterstitialPlacementAccepted bool `json:"interstitialPlacementAccepted,omitempty"`

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

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

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

// DirectorySitesListResponse: Directory Site List Response
type DirectorySitesListResponse struct {
	// DirectorySites: Directory site collection.
	DirectorySites []*DirectorySite `json:"directorySites,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#directorySitesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "DirectorySites") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// DisjunctiveMatchStatement: Represents a Disjunctive Match Statement
// resource, which is a conjunction (and) of disjunctive (or) boolean
// statements.
type DisjunctiveMatchStatement struct {
	// EventFilters: The event filters contained within this disjunctive
	// match statement.
	EventFilters []*EventFilter `json:"eventFilters,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#disjunctiveMatchStatement.
	Kind string `json:"kind,omitempty"`

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

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

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

// DynamicTargetingKey: Contains properties of a dynamic targeting key.
// Dynamic targeting keys are unique, user-friendly labels, created at
// the advertiser level in DCM, that can be assigned to ads, creatives,
// and placements and used for targeting with Studio dynamic creatives.
// Use these labels instead of numeric Campaign Manager IDs (such as
// placement IDs) to save time and avoid errors in your dynamic feeds.
type DynamicTargetingKey struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#dynamicTargetingKey".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this dynamic targeting key. This is a required field.
	// Must be less than 256 characters long and cannot contain commas. All
	// characters are converted to lowercase.
	Name string `json:"name,omitempty"`

	// ObjectId: ID of the object of this dynamic targeting key. This is a
	// required field.
	ObjectId int64 `json:"objectId,omitempty,string"`

	// ObjectType: Type of the object of this dynamic targeting key. This is
	// a required field.
	//
	// Possible values:
	//   "OBJECT_ADVERTISER"
	//   "OBJECT_AD"
	//   "OBJECT_CREATIVE"
	//   "OBJECT_PLACEMENT"
	ObjectType string `json:"objectType,omitempty"`

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

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

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

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

// DynamicTargetingKeysListResponse: Dynamic Targeting Key List Response
type DynamicTargetingKeysListResponse struct {
	// DynamicTargetingKeys: Dynamic targeting key collection.
	DynamicTargetingKeys []*DynamicTargetingKey `json:"dynamicTargetingKeys,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#dynamicTargetingKeysListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// EncryptionInfo: A description of how user IDs are encrypted.
type EncryptionInfo struct {
	// EncryptionEntityId: The encryption entity ID. This should match the
	// encryption configuration for ad serving or Data Transfer.
	EncryptionEntityId int64 `json:"encryptionEntityId,omitempty,string"`

	// EncryptionEntityType: The encryption entity type. This should match
	// the encryption configuration for ad serving or Data Transfer.
	//
	// Possible values:
	//   "ENCRYPTION_ENTITY_TYPE_UNKNOWN"
	//   "DCM_ACCOUNT"
	//   "DCM_ADVERTISER"
	//   "DBM_PARTNER"
	//   "DBM_ADVERTISER"
	//   "ADWORDS_CUSTOMER"
	//   "DFP_NETWORK_CODE"
	EncryptionEntityType string `json:"encryptionEntityType,omitempty"`

	// EncryptionSource: Describes whether the encrypted cookie was received
	// from ad serving (the %m macro) or from Data Transfer.
	//
	// Possible values:
	//   "ENCRYPTION_SCOPE_UNKNOWN"
	//   "AD_SERVING"
	//   "DATA_TRANSFER"
	EncryptionSource string `json:"encryptionSource,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#encryptionInfo".
	Kind string `json:"kind,omitempty"`

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

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

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

// EventFilter: Represents a DfaReporting event filter.
type EventFilter struct {
	// DimensionFilter: The dimension filter contained within this
	// EventFilter.
	DimensionFilter *PathReportDimensionValue `json:"dimensionFilter,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#eventFilter.
	Kind string `json:"kind,omitempty"`

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

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

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

// EventTag: Contains properties of an event tag.
type EventTag struct {
	// AccountId: Account ID of this event tag. This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this event tag. This field or the
	// campaignId field is required on insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// CampaignId: Campaign ID of this event tag. This field or the
	// advertiserId field is required on insertion.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CampaignIdDimensionValue: Dimension value for the ID of the campaign.
	// This is a read-only, auto-generated field.
	CampaignIdDimensionValue *DimensionValue `json:"campaignIdDimensionValue,omitempty"`

	// EnabledByDefault: Whether this event tag should be automatically
	// enabled for all of the advertiser's campaigns and ads.
	EnabledByDefault bool `json:"enabledByDefault,omitempty"`

	// ExcludeFromAdxRequests: Whether to remove this event tag from ads
	// that are trafficked through Display & Video 360 to Ad Exchange. This
	// may be useful if the event tag uses a pixel that is unapproved for Ad
	// Exchange bids on one or more networks, such as the Google Display
	// Network.
	ExcludeFromAdxRequests bool `json:"excludeFromAdxRequests,omitempty"`

	// Id: ID of this event tag. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#eventTag".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this event tag. This is a required field and must be
	// less than 256 characters long.
	Name string `json:"name,omitempty"`

	// SiteFilterType: Site filter type for this event tag. If no type is
	// specified then the event tag will be applied to all sites.
	//
	// Possible values:
	//   "WHITELIST"
	//   "BLACKLIST"
	SiteFilterType string `json:"siteFilterType,omitempty"`

	// SiteIds: Filter list of site IDs associated with this event tag. The
	// siteFilterType determines whether this is a allowlist or blocklist
	// filter.
	SiteIds googleapi.Int64s `json:"siteIds,omitempty"`

	// SslCompliant: Whether this tag is SSL-compliant or not. This is a
	// read-only field.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// Status: Status of this event tag. Must be ENABLED for this event tag
	// to fire. This is a required field.
	//
	// Possible values:
	//   "ENABLED"
	//   "DISABLED"
	Status string `json:"status,omitempty"`

	// SubaccountId: Subaccount ID of this event tag. This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// Type: Event tag type. Can be used to specify whether to use a
	// third-party pixel, a third-party JavaScript URL, or a third-party
	// click-through URL for either impression or click tracking. This is a
	// required field.
	//
	// Possible values:
	//   "IMPRESSION_IMAGE_EVENT_TAG"
	//   "IMPRESSION_JAVASCRIPT_EVENT_TAG"
	//   "CLICK_THROUGH_EVENT_TAG"
	Type string `json:"type,omitempty"`

	// Url: Payload URL for this event tag. The URL on a click-through event
	// tag should have a landing page URL appended to the end of it. This
	// field is required on insertion.
	Url string `json:"url,omitempty"`

	// UrlEscapeLevels: Number of times the landing page URL should be
	// URL-escaped before being appended to the click-through event tag URL.
	// Only applies to click-through event tags as specified by the event
	// tag type.
	UrlEscapeLevels int64 `json:"urlEscapeLevels,omitempty"`

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

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

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

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

// EventTagOverride: Event tag override information.
type EventTagOverride struct {
	// Enabled: Whether this override is enabled.
	Enabled bool `json:"enabled,omitempty"`

	// Id: ID of this event tag override. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

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

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

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

// EventTagsListResponse: Event Tag List Response
type EventTagsListResponse struct {
	// EventTags: Event tag collection.
	EventTags []*EventTag `json:"eventTags,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#eventTagsListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// File: Represents a File resource. A file contains the metadata for a
// report run. It shows the status of the run and holds the URLs to the
// generated report data if the run is finished and the status is
// "REPORT_AVAILABLE".
type File struct {
	// DateRange: The date range for which the file has report data. The
	// date range will always be the absolute date range for which the
	// report is run.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// FileName: The filename of the file.
	FileName string `json:"fileName,omitempty"`

	// Format: The output format of the report. Only available once the file
	// is available.
	//
	// Possible values:
	//   "CSV"
	//   "EXCEL"
	Format string `json:"format,omitempty"`

	// Id: The unique ID of this report file.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#file".
	Kind string `json:"kind,omitempty"`

	// LastModifiedTime: The timestamp in milliseconds since epoch when this
	// file was last modified.
	LastModifiedTime int64 `json:"lastModifiedTime,omitempty,string"`

	MediaRequestInfo *MediaRequestInfo `json:"mediaRequestInfo,omitempty"`

	MediaResponseInfo *MediaResponseInfo `json:"mediaResponseInfo,omitempty"`

	// ReportId: The ID of the report this file was generated from.
	ReportId int64 `json:"reportId,omitempty,string"`

	// Status: The status of the report file.
	//
	// Possible values:
	//   "PROCESSING"
	//   "REPORT_AVAILABLE"
	//   "FAILED"
	//   "CANCELLED"
	Status string `json:"status,omitempty"`

	// Urls: The URLs where the completed report file can be downloaded.
	Urls *FileUrls `json:"urls,omitempty"`

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

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

// FileUrls: The URLs where the completed report file can be downloaded.
type FileUrls struct {
	// ApiUrl: The URL for downloading the report data through the API.
	ApiUrl string `json:"apiUrl,omitempty"`

	// BrowserUrl: The URL for downloading the report data through a
	// browser.
	BrowserUrl string `json:"browserUrl,omitempty"`

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

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

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

// FileList: List of files for a report.
type FileList struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Items: The files returned in this response.
	Items []*File `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#fileList".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Continuation token used to page through files. To
	// retrieve the next page of results, set the next request's "pageToken"
	// to the value of this field. The page token is only valid for a
	// limited amount of time and should not be persisted.
	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. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// Flight: Flight
type Flight struct {
	EndDate string `json:"endDate,omitempty"`

	// RateOrCost: Rate or cost of this flight.
	RateOrCost int64 `json:"rateOrCost,omitempty,string"`

	StartDate string `json:"startDate,omitempty"`

	// Units: Units of this flight.
	Units int64 `json:"units,omitempty,string"`

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

// FloodlightActivitiesGenerateTagResponse: Floodlight Activity
// GenerateTag Response
type FloodlightActivitiesGenerateTagResponse struct {
	// FloodlightActivityTag: Generated tag for this Floodlight activity.
	// For global site tags, this is the event snippet.
	FloodlightActivityTag string `json:"floodlightActivityTag,omitempty"`

	// GlobalSiteTagGlobalSnippet: The global snippet section of a global
	// site tag. The global site tag sets new cookies on your domain, which
	// will store a unique identifier for a user or the ad click that
	// brought the user to your site. Learn more.
	GlobalSiteTagGlobalSnippet string `json:"globalSiteTagGlobalSnippet,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivitiesGenerateTagResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// FloodlightActivitiesListResponse: Floodlight Activity List Response
type FloodlightActivitiesListResponse struct {
	// FloodlightActivities: Floodlight activity collection.
	FloodlightActivities []*FloodlightActivity `json:"floodlightActivities,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivitiesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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.
	// "FloodlightActivities") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// FloodlightActivity: Contains properties of a Floodlight activity.
type FloodlightActivity struct {
	// AccountId: Account ID of this floodlight activity. This is a
	// read-only field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this floodlight activity. If this
	// field is left blank, the value will be copied over either from the
	// activity group's advertiser or the existing activity's advertiser.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// AttributionEnabled: Whether the activity is enabled for attribution.
	AttributionEnabled bool `json:"attributionEnabled,omitempty"`

	// CacheBustingType: Code type used for cache busting in the generated
	// tag. Applicable only when floodlightActivityGroupType is COUNTER and
	// countingMethod is STANDARD_COUNTING or UNIQUE_COUNTING.
	//
	// Possible values:
	//   "JAVASCRIPT"
	//   "ACTIVE_SERVER_PAGE"
	//   "JSP"
	//   "PHP"
	//   "COLD_FUSION"
	CacheBustingType string `json:"cacheBustingType,omitempty"`

	// CountingMethod: Counting method for conversions for this floodlight
	// activity. This is a required field.
	//
	// Possible values:
	//   "STANDARD_COUNTING"
	//   "UNIQUE_COUNTING"
	//   "SESSION_COUNTING"
	//   "TRANSACTIONS_COUNTING"
	//   "ITEMS_SOLD_COUNTING"
	CountingMethod string `json:"countingMethod,omitempty"`

	// DefaultTags: Dynamic floodlight tags.
	DefaultTags []*FloodlightActivityDynamicTag `json:"defaultTags,omitempty"`

	// ExpectedUrl: URL where this tag will be deployed. If specified, must
	// be less than 256 characters long.
	ExpectedUrl string `json:"expectedUrl,omitempty"`

	// FloodlightActivityGroupId: Floodlight activity group ID of this
	// floodlight activity. This is a required field.
	FloodlightActivityGroupId int64 `json:"floodlightActivityGroupId,omitempty,string"`

	// FloodlightActivityGroupName: Name of the associated floodlight
	// activity group. This is a read-only field.
	FloodlightActivityGroupName string `json:"floodlightActivityGroupName,omitempty"`

	// FloodlightActivityGroupTagString: Tag string of the associated
	// floodlight activity group. This is a read-only field.
	FloodlightActivityGroupTagString string `json:"floodlightActivityGroupTagString,omitempty"`

	// FloodlightActivityGroupType: Type of the associated floodlight
	// activity group. This is a read-only field.
	//
	// Possible values:
	//   "COUNTER"
	//   "SALE"
	FloodlightActivityGroupType string `json:"floodlightActivityGroupType,omitempty"`

	// FloodlightConfigurationId: Floodlight configuration ID of this
	// floodlight activity. If this field is left blank, the value will be
	// copied over either from the activity group's floodlight configuration
	// or from the existing activity's floodlight configuration.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

	// FloodlightConfigurationIdDimensionValue: Dimension value for the ID
	// of the floodlight configuration. This is a read-only, auto-generated
	// field.
	FloodlightConfigurationIdDimensionValue *DimensionValue `json:"floodlightConfigurationIdDimensionValue,omitempty"`

	// FloodlightTagType: The type of Floodlight tag this activity will
	// generate. This is a required field.
	//
	// Possible values:
	//   "IFRAME"
	//   "IMAGE"
	//   "GLOBAL_SITE_TAG"
	FloodlightTagType string `json:"floodlightTagType,omitempty"`

	// Id: ID of this floodlight activity. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this floodlight
	// activity. This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivity".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this floodlight activity. This is a required field.
	// Must be less than 129 characters long and cannot contain quotes.
	Name string `json:"name,omitempty"`

	// Notes: General notes or implementation instructions for the tag.
	Notes string `json:"notes,omitempty"`

	// PublisherTags: Publisher dynamic floodlight tags.
	PublisherTags []*FloodlightActivityPublisherDynamicTag `json:"publisherTags,omitempty"`

	// Secure: Whether this tag should use SSL.
	Secure bool `json:"secure,omitempty"`

	// SslCompliant: Whether the floodlight activity is SSL-compliant. This
	// is a read-only field, its value detected by the system from the
	// floodlight tags.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// SslRequired: Whether this floodlight activity must be SSL-compliant.
	SslRequired bool `json:"sslRequired,omitempty"`

	// Status: The status of the activity. This can only be set to ACTIVE or
	// ARCHIVED_AND_DISABLED. The ARCHIVED status is no longer supported and
	// cannot be set for Floodlight activities. The DISABLED_POLICY status
	// indicates that a Floodlight activity is violating Google policy.
	// Contact your account manager for more information.
	//
	// Possible values:
	//   "ACTIVE"
	//   "ARCHIVED_AND_DISABLED"
	//   "ARCHIVED"
	//   "DISABLED_POLICY"
	Status string `json:"status,omitempty"`

	// SubaccountId: Subaccount ID of this floodlight activity. This is a
	// read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TagFormat: Tag format type for the floodlight activity. If left
	// blank, the tag format will default to HTML.
	//
	// Possible values:
	//   "HTML"
	//   "XHTML"
	TagFormat string `json:"tagFormat,omitempty"`

	// TagString: Value of the cat= parameter in the floodlight tag, which
	// the ad servers use to identify the activity. This is optional: if
	// empty, a new tag string will be generated for you. This string must
	// be 1 to 8 characters long, with valid characters being a-z0-9[ _ ].
	// This tag string must also be unique among activities of the same
	// activity group. This field is read-only after insertion.
	TagString string `json:"tagString,omitempty"`

	// UserDefinedVariableTypes: List of the user-defined variables used by
	// this conversion tag. These map to the "u[1-100]=" in the tags. Each
	// of these can have a user defined type. Acceptable values are U1 to
	// U100, inclusive.
	//
	// Possible values:
	//   "U1"
	//   "U2"
	//   "U3"
	//   "U4"
	//   "U5"
	//   "U6"
	//   "U7"
	//   "U8"
	//   "U9"
	//   "U10"
	//   "U11"
	//   "U12"
	//   "U13"
	//   "U14"
	//   "U15"
	//   "U16"
	//   "U17"
	//   "U18"
	//   "U19"
	//   "U20"
	//   "U21"
	//   "U22"
	//   "U23"
	//   "U24"
	//   "U25"
	//   "U26"
	//   "U27"
	//   "U28"
	//   "U29"
	//   "U30"
	//   "U31"
	//   "U32"
	//   "U33"
	//   "U34"
	//   "U35"
	//   "U36"
	//   "U37"
	//   "U38"
	//   "U39"
	//   "U40"
	//   "U41"
	//   "U42"
	//   "U43"
	//   "U44"
	//   "U45"
	//   "U46"
	//   "U47"
	//   "U48"
	//   "U49"
	//   "U50"
	//   "U51"
	//   "U52"
	//   "U53"
	//   "U54"
	//   "U55"
	//   "U56"
	//   "U57"
	//   "U58"
	//   "U59"
	//   "U60"
	//   "U61"
	//   "U62"
	//   "U63"
	//   "U64"
	//   "U65"
	//   "U66"
	//   "U67"
	//   "U68"
	//   "U69"
	//   "U70"
	//   "U71"
	//   "U72"
	//   "U73"
	//   "U74"
	//   "U75"
	//   "U76"
	//   "U77"
	//   "U78"
	//   "U79"
	//   "U80"
	//   "U81"
	//   "U82"
	//   "U83"
	//   "U84"
	//   "U85"
	//   "U86"
	//   "U87"
	//   "U88"
	//   "U89"
	//   "U90"
	//   "U91"
	//   "U92"
	//   "U93"
	//   "U94"
	//   "U95"
	//   "U96"
	//   "U97"
	//   "U98"
	//   "U99"
	//   "U100"
	UserDefinedVariableTypes []string `json:"userDefinedVariableTypes,omitempty"`

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

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

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

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

// FloodlightActivityDynamicTag: Dynamic Tag
type FloodlightActivityDynamicTag struct {
	// Id: ID of this dynamic tag. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of this tag.
	Name string `json:"name,omitempty"`

	// Tag: Tag code.
	Tag string `json:"tag,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 *FloodlightActivityDynamicTag) MarshalJSON() ([]byte, error) {
	type NoMethod FloodlightActivityDynamicTag
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FloodlightActivityGroup: Contains properties of a Floodlight activity
// group.
type FloodlightActivityGroup struct {
	// AccountId: Account ID of this floodlight activity group. This is a
	// read-only field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this floodlight activity group. If
	// this field is left blank, the value will be copied over either from
	// the floodlight configuration's advertiser or from the existing
	// activity group's advertiser.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// FloodlightConfigurationId: Floodlight configuration ID of this
	// floodlight activity group. This is a required field.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

	// FloodlightConfigurationIdDimensionValue: Dimension value for the ID
	// of the floodlight configuration. This is a read-only, auto-generated
	// field.
	FloodlightConfigurationIdDimensionValue *DimensionValue `json:"floodlightConfigurationIdDimensionValue,omitempty"`

	// Id: ID of this floodlight activity group. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this floodlight
	// activity group. This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivityGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this floodlight activity group. This is a required
	// field. Must be less than 65 characters long and cannot contain
	// quotes.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this floodlight activity group. This
	// is a read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TagString: Value of the type= parameter in the floodlight tag, which
	// the ad servers use to identify the activity group that the activity
	// belongs to. This is optional: if empty, a new tag string will be
	// generated for you. This string must be 1 to 8 characters long, with
	// valid characters being a-z0-9[ _ ]. This tag string must also be
	// unique among activity groups of the same floodlight configuration.
	// This field is read-only after insertion.
	TagString string `json:"tagString,omitempty"`

	// Type: Type of the floodlight activity group. This is a required field
	// that is read-only after insertion.
	//
	// Possible values:
	//   "COUNTER"
	//   "SALE"
	Type string `json:"type,omitempty"`

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

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

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

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

// FloodlightActivityGroupsListResponse: Floodlight Activity Group List
// Response
type FloodlightActivityGroupsListResponse struct {
	// FloodlightActivityGroups: Floodlight activity group collection.
	FloodlightActivityGroups []*FloodlightActivityGroup `json:"floodlightActivityGroups,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivityGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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.
	// "FloodlightActivityGroups") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// FloodlightActivityPublisherDynamicTag: Publisher Dynamic Tag
type FloodlightActivityPublisherDynamicTag struct {
	// ClickThrough: Whether this tag is applicable only for click-throughs.
	ClickThrough bool `json:"clickThrough,omitempty"`

	// DirectorySiteId: Directory site ID of this dynamic tag. This is a
	// write-only field that can be used as an alternative to the siteId
	// field. When this resource is retrieved, only the siteId field will be
	// populated.
	DirectorySiteId int64 `json:"directorySiteId,omitempty,string"`

	// DynamicTag: Dynamic floodlight tag.
	DynamicTag *FloodlightActivityDynamicTag `json:"dynamicTag,omitempty"`

	// SiteId: Site ID of this dynamic tag.
	SiteId int64 `json:"siteId,omitempty,string"`

	// SiteIdDimensionValue: Dimension value for the ID of the site. This is
	// a read-only, auto-generated field.
	SiteIdDimensionValue *DimensionValue `json:"siteIdDimensionValue,omitempty"`

	// ViewThrough: Whether this tag is applicable only for view-throughs.
	ViewThrough bool `json:"viewThrough,omitempty"`

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

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

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

// FloodlightConfiguration: Contains properties of a Floodlight
// configuration.
type FloodlightConfiguration struct {
	// AccountId: Account ID of this floodlight configuration. This is a
	// read-only field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of the parent advertiser of this
	// floodlight configuration.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// AnalyticsDataSharingEnabled: Whether advertiser data is shared with
	// Google Analytics.
	AnalyticsDataSharingEnabled bool `json:"analyticsDataSharingEnabled,omitempty"`

	// CustomViewabilityMetric: Custom Viewability metric for the floodlight
	// configuration.
	CustomViewabilityMetric *CustomViewabilityMetric `json:"customViewabilityMetric,omitempty"`

	// ExposureToConversionEnabled: Whether the exposure-to-conversion
	// report is enabled. This report shows detailed pathway information on
	// up to 10 of the most recent ad exposures seen by a user before
	// converting.
	ExposureToConversionEnabled bool `json:"exposureToConversionEnabled,omitempty"`

	// FirstDayOfWeek: Day that will be counted as the first day of the week
	// in reports. This is a required field.
	//
	// Possible values:
	//   "MONDAY"
	//   "SUNDAY"
	FirstDayOfWeek string `json:"firstDayOfWeek,omitempty"`

	// Id: ID of this floodlight configuration. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this floodlight
	// configuration. This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// InAppAttributionTrackingEnabled: Whether in-app attribution tracking
	// is enabled.
	InAppAttributionTrackingEnabled bool `json:"inAppAttributionTrackingEnabled,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightConfiguration".
	Kind string `json:"kind,omitempty"`

	// LookbackConfiguration: Lookback window settings for this floodlight
	// configuration.
	LookbackConfiguration *LookbackConfiguration `json:"lookbackConfiguration,omitempty"`

	// NaturalSearchConversionAttributionOption: Types of attribution
	// options for natural search conversions.
	//
	// Possible values:
	//   "EXCLUDE_NATURAL_SEARCH_CONVERSION_ATTRIBUTION"
	//   "INCLUDE_NATURAL_SEARCH_CONVERSION_ATTRIBUTION"
	//   "INCLUDE_NATURAL_SEARCH_TIERED_CONVERSION_ATTRIBUTION"
	NaturalSearchConversionAttributionOption string `json:"naturalSearchConversionAttributionOption,omitempty"`

	// OmnitureSettings: Settings for Campaign Manager Omniture integration.
	OmnitureSettings *OmnitureSettings `json:"omnitureSettings,omitempty"`

	// SubaccountId: Subaccount ID of this floodlight configuration. This is
	// a read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TagSettings: Configuration settings for dynamic and image floodlight
	// tags.
	TagSettings *TagSettings `json:"tagSettings,omitempty"`

	// ThirdPartyAuthenticationTokens: List of third-party authentication
	// tokens enabled for this configuration.
	ThirdPartyAuthenticationTokens []*ThirdPartyAuthenticationToken `json:"thirdPartyAuthenticationTokens,omitempty"`

	// UserDefinedVariableConfigurations: List of user defined variables
	// enabled for this configuration.
	UserDefinedVariableConfigurations []*UserDefinedVariableConfiguration `json:"userDefinedVariableConfigurations,omitempty"`

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

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

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

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

// FloodlightConfigurationsListResponse: Floodlight Configuration List
// Response
type FloodlightConfigurationsListResponse struct {
	// FloodlightConfigurations: Floodlight configuration collection.
	FloodlightConfigurations []*FloodlightConfiguration `json:"floodlightConfigurations,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightConfigurationsListResponse".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// FloodlightReportCompatibleFields: Represents fields that are
// compatible to be selected for a report of type "FlOODLIGHT".
type FloodlightReportCompatibleFields struct {
	// DimensionFilters: Dimensions which are compatible to be selected in
	// the "dimensionFilters" section of the report.
	DimensionFilters []*Dimension `json:"dimensionFilters,omitempty"`

	// Dimensions: Dimensions which are compatible to be selected in the
	// "dimensions" section of the report.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#floodlightReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

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

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

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

// FrequencyCap: Frequency Cap.
type FrequencyCap struct {
	// Duration: Duration of time, in seconds, for this frequency cap. The
	// maximum duration is 90 days. Acceptable values are 1 to 7776000,
	// inclusive.
	Duration int64 `json:"duration,omitempty,string"`

	// Impressions: Number of times an individual user can be served the ad
	// within the specified duration. Acceptable values are 1 to 15,
	// inclusive.
	Impressions int64 `json:"impressions,omitempty,string"`

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

// FsCommand: FsCommand.
type FsCommand struct {
	// Left: Distance from the left of the browser.Applicable when
	// positionOption is DISTANCE_FROM_TOP_LEFT_CORNER.
	Left int64 `json:"left,omitempty"`

	// PositionOption: Position in the browser where the window will open.
	//
	// Possible values:
	//   "CENTERED"
	//   "DISTANCE_FROM_TOP_LEFT_CORNER"
	PositionOption string `json:"positionOption,omitempty"`

	// Top: Distance from the top of the browser. Applicable when
	// positionOption is DISTANCE_FROM_TOP_LEFT_CORNER.
	Top int64 `json:"top,omitempty"`

	// WindowHeight: Height of the window.
	WindowHeight int64 `json:"windowHeight,omitempty"`

	// WindowWidth: Width of the window.
	WindowWidth int64 `json:"windowWidth,omitempty"`

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

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

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

// GeoTargeting: Geographical Targeting.
type GeoTargeting struct {
	// Cities: Cities to be targeted. For each city only dartId is required.
	// The other fields are populated automatically when the ad is inserted
	// or updated. If targeting a city, do not target or exclude the country
	// of the city, and do not target the metro or region of the city.
	Cities []*City `json:"cities,omitempty"`

	// Countries: Countries to be targeted or excluded from targeting,
	// depending on the setting of the excludeCountries field. For each
	// country only dartId is required. The other fields are populated
	// automatically when the ad is inserted or updated. If targeting or
	// excluding a country, do not target regions, cities, metros, or postal
	// codes in the same country.
	Countries []*Country `json:"countries,omitempty"`

	// ExcludeCountries: Whether or not to exclude the countries in the
	// countries field from targeting. If false, the countries field refers
	// to countries which will be targeted by the ad.
	ExcludeCountries bool `json:"excludeCountries,omitempty"`

	// Metros: Metros to be targeted. For each metro only dmaId is required.
	// The other fields are populated automatically when the ad is inserted
	// or updated. If targeting a metro, do not target or exclude the
	// country of the metro.
	Metros []*Metro `json:"metros,omitempty"`

	// PostalCodes: Postal codes to be targeted. For each postal code only
	// id is required. The other fields are populated automatically when the
	// ad is inserted or updated. If targeting a postal code, do not target
	// or exclude the country of the postal code.
	PostalCodes []*PostalCode `json:"postalCodes,omitempty"`

	// Regions: Regions to be targeted. For each region only dartId is
	// required. The other fields are populated automatically when the ad is
	// inserted or updated. If targeting a region, do not target or exclude
	// the country of the region.
	Regions []*Region `json:"regions,omitempty"`

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

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

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

// InventoryItem: Represents a buy from the Planning inventory store.
type InventoryItem struct {
	// AccountId: Account ID of this inventory item.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdSlots: Ad slots of this inventory item. If this inventory item
	// represents a standalone placement, there will be exactly one ad slot.
	// If this inventory item represents a placement group, there will be
	// more than one ad slot, each representing one child placement in that
	// placement group.
	AdSlots []*AdSlot `json:"adSlots,omitempty"`

	// AdvertiserId: Advertiser ID of this inventory item.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// ContentCategoryId: Content category ID of this inventory item.
	ContentCategoryId int64 `json:"contentCategoryId,omitempty,string"`

	// EstimatedClickThroughRate: Estimated click-through rate of this
	// inventory item.
	EstimatedClickThroughRate int64 `json:"estimatedClickThroughRate,omitempty,string"`

	// EstimatedConversionRate: Estimated conversion rate of this inventory
	// item.
	EstimatedConversionRate int64 `json:"estimatedConversionRate,omitempty,string"`

	// Id: ID of this inventory item.
	Id int64 `json:"id,omitempty,string"`

	// InPlan: Whether this inventory item is in plan.
	InPlan bool `json:"inPlan,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#inventoryItem".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this inventory item.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this inventory item. For standalone inventory items,
	// this is the same name as that of its only ad slot. For group
	// inventory items, this can differ from the name of any of its ad
	// slots.
	Name string `json:"name,omitempty"`

	// NegotiationChannelId: Negotiation channel ID of this inventory item.
	NegotiationChannelId int64 `json:"negotiationChannelId,omitempty,string"`

	// OrderId: Order ID of this inventory item.
	OrderId int64 `json:"orderId,omitempty,string"`

	// PlacementStrategyId: Placement strategy ID of this inventory item.
	PlacementStrategyId int64 `json:"placementStrategyId,omitempty,string"`

	// Pricing: Pricing of this inventory item.
	Pricing *Pricing `json:"pricing,omitempty"`

	// ProjectId: Project ID of this inventory item.
	ProjectId int64 `json:"projectId,omitempty,string"`

	// RfpId: RFP ID of this inventory item.
	RfpId int64 `json:"rfpId,omitempty,string"`

	// SiteId: ID of the site this inventory item is associated with.
	SiteId int64 `json:"siteId,omitempty,string"`

	// SubaccountId: Subaccount ID of this inventory item.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// Type: Type of inventory item.
	//
	// Possible values:
	//   "PLANNING_PLACEMENT_TYPE_REGULAR"
	//   "PLANNING_PLACEMENT_TYPE_CREDIT"
	Type string `json:"type,omitempty"`

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

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

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

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

// InventoryItemsListResponse: Inventory item List Response
type InventoryItemsListResponse struct {
	// InventoryItems: Inventory item collection
	InventoryItems []*InventoryItem `json:"inventoryItems,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#inventoryItemsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "InventoryItems") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// KeyValueTargetingExpression: Key Value Targeting Expression.
type KeyValueTargetingExpression struct {
	// Expression: Keyword expression being targeted by the ad.
	Expression string `json:"expression,omitempty"`

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

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

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

// LandingPage: Contains information about where a user's browser is
// taken after the user clicks an ad.
type LandingPage struct {
	// AdvertiserId: Advertiser ID of this landing page. This is a required
	// field.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// Archived: Whether this landing page has been archived.
	Archived bool `json:"archived,omitempty"`

	// DeepLinks: Links that will direct the user to a mobile app, if
	// installed.
	DeepLinks []*DeepLink `json:"deepLinks,omitempty"`

	// Id: ID of this landing page. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#landingPage".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this landing page. This is a required field. It must be
	// less than 256 characters long.
	Name string `json:"name,omitempty"`

	// Url: URL of this landing page. This is a required field.
	Url string `json:"url,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 *LandingPage) MarshalJSON() ([]byte, error) {
	type NoMethod LandingPage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Language: Contains information about a language that can be targeted
// by ads.
type Language struct {
	// Id: Language ID of this language. This is the ID used for targeting
	// and generating reports.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#language".
	Kind string `json:"kind,omitempty"`

	// LanguageCode: Format of language code is an ISO 639 two-letter
	// language code optionally followed by an underscore followed by an ISO
	// 3166 code. Examples are "en" for English or "zh_CN" for Simplified
	// Chinese.
	LanguageCode string `json:"languageCode,omitempty"`

	// Name: Name of this language.
	Name string `json:"name,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 *Language) MarshalJSON() ([]byte, error) {
	type NoMethod Language
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LanguageTargeting: Language Targeting.
type LanguageTargeting struct {
	// Languages: Languages that this ad targets. For each language only
	// languageId is required. The other fields are populated automatically
	// when the ad is inserted or updated.
	Languages []*Language `json:"languages,omitempty"`

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

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

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

// LanguagesListResponse: Language List Response
type LanguagesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#languagesListResponse".
	Kind string `json:"kind,omitempty"`

	// Languages: Language collection.
	Languages []*Language `json:"languages,omitempty"`

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

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

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

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

// LastModifiedInfo: Modification timestamp.
type LastModifiedInfo struct {
	// Time: Timestamp of the last change in milliseconds since epoch.
	Time int64 `json:"time,omitempty,string"`

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

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

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

// ListPopulationClause: A group clause made up of list population terms
// representing constraints joined by ORs.
type ListPopulationClause struct {
	// Terms: Terms of this list population clause. Each clause is made up
	// of list population terms representing constraints and are joined by
	// ORs.
	Terms []*ListPopulationTerm `json:"terms,omitempty"`

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

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

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

// ListPopulationRule: Remarketing List Population Rule.
type ListPopulationRule struct {
	// FloodlightActivityId: Floodlight activity ID associated with this
	// rule. This field can be left blank.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// FloodlightActivityName: Name of floodlight activity associated with
	// this rule. This is a read-only, auto-generated field.
	FloodlightActivityName string `json:"floodlightActivityName,omitempty"`

	// ListPopulationClauses: Clauses that make up this list population
	// rule. Clauses are joined by ANDs, and the clauses themselves are made
	// up of list population terms which are joined by ORs.
	ListPopulationClauses []*ListPopulationClause `json:"listPopulationClauses,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 *ListPopulationRule) MarshalJSON() ([]byte, error) {
	type NoMethod ListPopulationRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListPopulationTerm: Remarketing List Population Rule Term.
type ListPopulationTerm struct {
	// Contains: Will be true if the term should check if the user is in the
	// list and false if the term should check if the user is not in the
	// list. This field is only relevant when type is set to
	// LIST_MEMBERSHIP_TERM. False by default.
	Contains bool `json:"contains,omitempty"`

	// Negation: Whether to negate the comparison result of this term during
	// rule evaluation. This field is only relevant when type is left unset
	// or set to CUSTOM_VARIABLE_TERM or REFERRER_TERM.
	Negation bool `json:"negation,omitempty"`

	// Operator: Comparison operator of this term. This field is only
	// relevant when type is left unset or set to CUSTOM_VARIABLE_TERM or
	// REFERRER_TERM.
	//
	// Possible values:
	//   "NUM_EQUALS"
	//   "NUM_LESS_THAN"
	//   "NUM_LESS_THAN_EQUAL"
	//   "NUM_GREATER_THAN"
	//   "NUM_GREATER_THAN_EQUAL"
	//   "STRING_EQUALS"
	//   "STRING_CONTAINS"
	Operator string `json:"operator,omitempty"`

	// RemarketingListId: ID of the list in question. This field is only
	// relevant when type is set to LIST_MEMBERSHIP_TERM.
	RemarketingListId int64 `json:"remarketingListId,omitempty,string"`

	// Type: List population term type determines the applicable fields in
	// this object. If left unset or set to CUSTOM_VARIABLE_TERM, then
	// variableName, variableFriendlyName, operator, value, and negation are
	// applicable. If set to LIST_MEMBERSHIP_TERM then remarketingListId and
	// contains are applicable. If set to REFERRER_TERM then operator,
	// value, and negation are applicable.
	//
	// Possible values:
	//   "CUSTOM_VARIABLE_TERM"
	//   "LIST_MEMBERSHIP_TERM"
	//   "REFERRER_TERM"
	Type string `json:"type,omitempty"`

	// Value: Literal to compare the variable to. This field is only
	// relevant when type is left unset or set to CUSTOM_VARIABLE_TERM or
	// REFERRER_TERM.
	Value string `json:"value,omitempty"`

	// VariableFriendlyName: Friendly name of this term's variable. This is
	// a read-only, auto-generated field. This field is only relevant when
	// type is left unset or set to CUSTOM_VARIABLE_TERM.
	VariableFriendlyName string `json:"variableFriendlyName,omitempty"`

	// VariableName: Name of the variable (U1, U2, etc.) being compared in
	// this term. This field is only relevant when type is set to null,
	// CUSTOM_VARIABLE_TERM or REFERRER_TERM.
	VariableName string `json:"variableName,omitempty"`

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

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

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

// ListTargetingExpression: Remarketing List Targeting Expression.
type ListTargetingExpression struct {
	// Expression: Expression describing which lists are being targeted by
	// the ad.
	Expression string `json:"expression,omitempty"`

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

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

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

// LookbackConfiguration: Lookback configuration settings.
type LookbackConfiguration struct {
	// ClickDuration: Lookback window, in days, from the last time a given
	// user clicked on one of your ads. If you enter 0, clicks will not be
	// considered as triggering events for floodlight tracking. If you leave
	// this field blank, the default value for your account will be used.
	// Acceptable values are 0 to 90, inclusive.
	ClickDuration int64 `json:"clickDuration,omitempty"`

	// PostImpressionActivitiesDuration: Lookback window, in days, from the
	// last time a given user viewed one of your ads. If you enter 0,
	// impressions will not be considered as triggering events for
	// floodlight tracking. If you leave this field blank, the default value
	// for your account will be used. Acceptable values are 0 to 90,
	// inclusive.
	PostImpressionActivitiesDuration int64 `json:"postImpressionActivitiesDuration,omitempty"`

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

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

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

// MediaRequestInfo: Extra information added to operations that support
// Scotty media requests.
type MediaRequestInfo struct {
	// CurrentBytes: The number of current bytes uploaded or downloaded.
	CurrentBytes int64 `json:"currentBytes,omitempty,string"`

	// CustomData: Data to be copied to backend requests. Custom data is
	// returned to Scotty in the agent_state field, which Scotty will then
	// provide in subsequent upload notifications.
	CustomData string `json:"customData,omitempty"`

	// DiffObjectVersion: Set if the http request info is diff encoded. The
	// value of this field is the version number of the base revision. This
	// is corresponding to Apiary's mediaDiffObjectVersion
	// (//depot/google3/java/com/google/api/server/media/variable/DiffObjectV
	// ersionVariable.java). See go/esf-scotty-diff-upload for more
	// information.
	DiffObjectVersion string `json:"diffObjectVersion,omitempty"`

	// NotificationType: The type of notification received from Scotty.
	//
	// Possible values:
	//   "START" - Such requests signals the start of a request containing
	// media upload. Only the media field(s) in the inserted/updated
	// resource are set. The response should either return an error or
	// succeed. On success, responses don't need to contain anything.
	//   "PROGRESS" - Such requests signals that the upload has progressed
	// and that the backend might want to access the media file specified in
	// relevant fields in the resource. Only the media field(s) in the
	// inserted/updated resource are set. The response should either return
	// an error or succeed. On success, responses don't need to contain
	// anything.
	//   "END" - Such requests signals the end of a request containing media
	// upload. END should be handled just like normal Insert/Upload
	// requests, that is, they should process the request and return a
	// complete resource in the response. Pointers to media data (a GFS path
	// usually) appear in the relevant fields in the inserted/updated
	// resource. See gdata.Media in data.proto.
	//   "RESPONSE_SENT" - Such requests occur after an END and signal that
	// the response has been sent back to the client. RESPONSE_SENT is only
	// sent to the backend if it is configured to receive them. The response
	// does not need to contain anything.
	//   "ERROR" - Such requests indicate that an error occurred while
	// processing the request. ERROR is only sent to the backend if it is
	// configured to receive them. It is not guaranteed that all errors will
	// result in this notification to the backend, even if the backend
	// requests them. Since these requests are just for informational
	// purposes, the response does not need to contain anything.
	NotificationType string `json:"notificationType,omitempty"`

	// RequestId: The Scotty request ID.
	RequestId string `json:"requestId,omitempty"`

	// TotalBytes: The total size of the file.
	TotalBytes int64 `json:"totalBytes,omitempty,string"`

	// TotalBytesIsEstimated: Whether the total bytes field contains an
	// estimated data.
	TotalBytesIsEstimated bool `json:"totalBytesIsEstimated,omitempty"`

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

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

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

// MediaResponseInfo: This message is for backends to pass their scotty
// media specific fields to ESF. Backend will include this in their
// response message to ESF. Example: ExportFile is an rpc defined for
// upload using scotty from ESF. rpc ExportFile(ExportFileRequest)
// returns (ExportFileResponse) Message ExportFileResponse will include
// apiserving.MediaResponseInfo to tell ESF about data like
// dynamic_dropzone it needs to pass to Scotty. message
// ExportFileResponse { optional gdata.Media blob = 1; optional
// apiserving.MediaResponseInfo media_response_info = 2 }
type MediaResponseInfo struct {
	// CustomData: Data to copy from backend response to the next backend
	// requests. Custom data is returned to Scotty in the agent_state field,
	// which Scotty will then provide in subsequent upload notifications.
	CustomData string `json:"customData,omitempty"`

	// DataStorageTransform: Specifies any transformation to be applied to
	// data before persisting it or retrieving from storage. E.g.,
	// encryption options for blobstore2. This should be of the form
	// uploader_service.DataStorageTransform.
	DataStorageTransform string `json:"dataStorageTransform,omitempty"`

	// DynamicDropTarget: Specifies the Scotty Drop Target to use for
	// uploads. If present in a media response, Scotty does not upload to a
	// standard drop zone. Instead, Scotty saves the upload directly to the
	// location specified in this drop target. Unlike drop zones, the drop
	// target is the final storage location for an upload. So, the agent
	// does not need to clone the blob at the end of the upload. The agent
	// is responsible for garbage collecting any orphaned blobs that may
	// occur due to aborted uploads. For more information, see the drop
	// target design doc here: http://goto/ScottyDropTarget This field will
	// be preferred to dynamicDropzone. If provided, the identified field in
	// the response must be of the type uploader.agent.DropTarget.
	DynamicDropTarget string `json:"dynamicDropTarget,omitempty"`

	// DynamicDropzone: Specifies the Scotty dropzone to use for uploads.
	DynamicDropzone string `json:"dynamicDropzone,omitempty"`

	// RequestClass: Request class to use for all Blobstore operations for
	// this request.
	//
	// Possible values:
	//   "UNKNOWN_REQUEST_CLASS" - Unpopulated request_class in log files
	// will be taken as 0 in dremel query. GoogleSQL will try to cast it to
	// enum by default. An unused 0 value is added to avoid GoogleSQL
	// casting error. Please refer to b/69677280.
	//   "LATENCY_SENSITIVE" - A latency-sensitive request.
	//   "PRODUCTION_BATCH" - A request generated by a batch process.
	//   "BEST_EFFORT" - A best-effort request.
	RequestClass string `json:"requestClass,omitempty"`

	// TrafficClassField: Specifies the TrafficClass that Scotty should use
	// for any RPCs to fetch the response bytes. Will override the traffic
	// class GTOS of the incoming http request. This is a temporary field to
	// facilitate whitelisting and experimentation by the bigstore agent
	// only. For instance, this does not apply to RTMP reads. WARNING: DO
	// NOT USE WITHOUT PERMISSION FROM THE SCOTTY TEAM.
	//
	// Possible values:
	//   "BE1" - Application-selectable traffic classes Best effort
	//   "AF1" - Assured forwarding priority 1
	//   "AF2" - Assured forwarding priority 2
	//   "AF3" - Assured forwarding priority 3
	//   "AF4" - Assured forwarding priority 4
	//   "NC1" - Network control
	//   "NC0" - Network control
	//   "BE0" - Best effort at high packet loss
	//   "LLQ" - Low-latency queue (LLQ) best effort (go/llq)
	//   "LLQ1" - LLQ best effort (go/llq2)
	//   "LLQ2" - LLQ assured forwarding priority 2 (go/llq2)
	TrafficClassField string `json:"trafficClassField,omitempty"`

	// VerifyHashFromHeader: Tells Scotty to verify hashes on the agent's
	// behalf by parsing out the X-Goog-Hash header.
	VerifyHashFromHeader bool `json:"verifyHashFromHeader,omitempty"`

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

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

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

// Metric: Represents a metric.
type Metric struct {
	// Kind: The kind of resource this is, in this case dfareporting#metric.
	Kind string `json:"kind,omitempty"`

	// Name: The metric name, e.g. dfa:impressions
	Name string `json:"name,omitempty"`

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

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

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

// Metro: Contains information about a metro region that can be targeted
// by ads.
type Metro struct {
	// CountryCode: Country code of the country to which this metro region
	// belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this metro region
	// belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// DartId: DART ID of this metro region.
	DartId int64 `json:"dartId,omitempty,string"`

	// DmaId: DMA ID of this metro region. This is the ID used for targeting
	// and generating reports, and is equivalent to metro_code.
	DmaId int64 `json:"dmaId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#metro".
	Kind string `json:"kind,omitempty"`

	// MetroCode: Metro code of this metro region. This is equivalent to
	// dma_id.
	MetroCode string `json:"metroCode,omitempty"`

	// Name: Name of this metro region.
	Name string `json:"name,omitempty"`

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

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

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

// MetrosListResponse: Metro List Response
type MetrosListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#metrosListResponse".
	Kind string `json:"kind,omitempty"`

	// Metros: Metro collection.
	Metros []*Metro `json:"metros,omitempty"`

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

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

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

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

// MobileApp: Contains information about a mobile app. Used as a landing
// page deep link.
type MobileApp struct {
	// Directory: Mobile app directory.
	//
	// Possible values:
	//   "UNKNOWN"
	//   "APPLE_APP_STORE"
	//   "GOOGLE_PLAY_STORE"
	Directory string `json:"directory,omitempty"`

	// Id: ID of this mobile app.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#mobileApp".
	Kind string `json:"kind,omitempty"`

	// PublisherName: Publisher name.
	PublisherName string `json:"publisherName,omitempty"`

	// Title: Title of this mobile app.
	Title string `json:"title,omitempty"`

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

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

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

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

// MobileAppsListResponse: Mobile app List Response
type MobileAppsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#mobileAppsListResponse".
	Kind string `json:"kind,omitempty"`

	// MobileApps: Mobile apps collection.
	MobileApps []*MobileApp `json:"mobileApps,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	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. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// MobileCarrier: Contains information about a mobile carrier that can
// be targeted by ads.
type MobileCarrier struct {
	// CountryCode: Country code of the country to which this mobile carrier
	// belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this mobile carrier
	// belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// Id: ID of this mobile carrier.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#mobileCarrier".
	Kind string `json:"kind,omitempty"`

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

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

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

// MobileCarriersListResponse: Mobile Carrier List Response
type MobileCarriersListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#mobileCarriersListResponse".
	Kind string `json:"kind,omitempty"`

	// MobileCarriers: Mobile carrier collection.
	MobileCarriers []*MobileCarrier `json:"mobileCarriers,omitempty"`

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

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

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

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

// ObaIcon: Online Behavioral Advertiser icon.
type ObaIcon struct {
	// IconClickThroughUrl: URL to redirect to when an OBA icon is clicked.
	IconClickThroughUrl string `json:"iconClickThroughUrl,omitempty"`

	// IconClickTrackingUrl: URL to track click when an OBA icon is clicked.
	IconClickTrackingUrl string `json:"iconClickTrackingUrl,omitempty"`

	// IconViewTrackingUrl: URL to track view when an OBA icon is clicked.
	IconViewTrackingUrl string `json:"iconViewTrackingUrl,omitempty"`

	// Program: Identifies the industry initiative that the icon supports.
	// For example, AdChoices.
	Program string `json:"program,omitempty"`

	// ResourceUrl: OBA icon resource URL. Campaign Manager only supports
	// image and JavaScript icons. Learn more
	ResourceUrl string `json:"resourceUrl,omitempty"`

	// Size: OBA icon size.
	Size *Size `json:"size,omitempty"`

	// XPosition: OBA icon x coordinate position. Accepted values are left
	// or right.
	XPosition string `json:"xPosition,omitempty"`

	// YPosition: OBA icon y coordinate position. Accepted values are top or
	// bottom.
	YPosition string `json:"yPosition,omitempty"`

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

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

// ObjectFilter: Object Filter.
type ObjectFilter struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#objectFilter".
	Kind string `json:"kind,omitempty"`

	// ObjectIds: Applicable when status is ASSIGNED. The user has access to
	// objects with these object IDs.
	ObjectIds googleapi.Int64s `json:"objectIds,omitempty"`

	// Status: Status of the filter. NONE means the user has access to none
	// of the objects. ALL means the user has access to all objects.
	// ASSIGNED means the user has access to the objects with IDs in the
	// objectIds list.
	//
	// Possible values:
	//   "NONE"
	//   "ASSIGNED"
	//   "ALL"
	Status string `json:"status,omitempty"`

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

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

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

// OffsetPosition: Offset Position.
type OffsetPosition struct {
	// Left: Offset distance from left side of an asset or a window.
	Left int64 `json:"left,omitempty"`

	// Top: Offset distance from top side of an asset or a window.
	Top int64 `json:"top,omitempty"`

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

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

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

// OmnitureSettings: Omniture Integration Settings.
type OmnitureSettings struct {
	// OmnitureCostDataEnabled: Whether placement cost data will be sent to
	// Omniture. This property can be enabled only if
	// omnitureIntegrationEnabled is true.
	OmnitureCostDataEnabled bool `json:"omnitureCostDataEnabled,omitempty"`

	// OmnitureIntegrationEnabled: Whether Omniture integration is enabled.
	// This property can be enabled only when the "Advanced Ad Serving"
	// account setting is enabled.
	OmnitureIntegrationEnabled bool `json:"omnitureIntegrationEnabled,omitempty"`

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

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

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

// OperatingSystem: Contains information about an operating system that
// can be targeted by ads.
type OperatingSystem struct {
	// DartId: DART ID of this operating system. This is the ID used for
	// targeting.
	DartId int64 `json:"dartId,omitempty,string"`

	// Desktop: Whether this operating system is for desktop.
	Desktop bool `json:"desktop,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#operatingSystem".
	Kind string `json:"kind,omitempty"`

	// Mobile: Whether this operating system is for mobile.
	Mobile bool `json:"mobile,omitempty"`

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

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

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

// OperatingSystemVersion: Contains information about a particular
// version of an operating system that can be targeted by ads.
type OperatingSystemVersion struct {
	// Id: ID of this operating system version.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#operatingSystemVersion".
	Kind string `json:"kind,omitempty"`

	// MajorVersion: Major version (leftmost number) of this operating
	// system version.
	MajorVersion string `json:"majorVersion,omitempty"`

	// MinorVersion: Minor version (number after the first dot) of this
	// operating system version.
	MinorVersion string `json:"minorVersion,omitempty"`

	// Name: Name of this operating system version.
	Name string `json:"name,omitempty"`

	// OperatingSystem: Operating system of this operating system version.
	OperatingSystem *OperatingSystem `json:"operatingSystem,omitempty"`

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

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

// OperatingSystemVersionsListResponse: Operating System Version List
// Response
type OperatingSystemVersionsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#operatingSystemVersionsListResponse".
	Kind string `json:"kind,omitempty"`

	// OperatingSystemVersions: Operating system version collection.
	OperatingSystemVersions []*OperatingSystemVersion `json:"operatingSystemVersions,omitempty"`

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

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

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

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

// OperatingSystemsListResponse: Operating System List Response
type OperatingSystemsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#operatingSystemsListResponse".
	Kind string `json:"kind,omitempty"`

	// OperatingSystems: Operating system collection.
	OperatingSystems []*OperatingSystem `json:"operatingSystems,omitempty"`

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

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

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

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

// OptimizationActivity: Creative optimization activity.
type OptimizationActivity struct {
	// FloodlightActivityId: Floodlight activity ID of this optimization
	// activity. This is a required field.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// FloodlightActivityIdDimensionValue: Dimension value for the ID of the
	// floodlight activity. This is a read-only, auto-generated field.
	FloodlightActivityIdDimensionValue *DimensionValue `json:"floodlightActivityIdDimensionValue,omitempty"`

	// Weight: Weight associated with this optimization. The weight assigned
	// will be understood in proportion to the weights assigned to the other
	// optimization activities. Value must be greater than or equal to 1.
	Weight int64 `json:"weight,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 *OptimizationActivity) MarshalJSON() ([]byte, error) {
	type NoMethod OptimizationActivity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Order: Describes properties of a Planning order.
type Order struct {
	// AccountId: Account ID of this order.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this order.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// ApproverUserProfileIds: IDs for users that have to approve documents
	// created for this order.
	ApproverUserProfileIds googleapi.Int64s `json:"approverUserProfileIds,omitempty"`

	// BuyerInvoiceId: Buyer invoice ID associated with this order.
	BuyerInvoiceId string `json:"buyerInvoiceId,omitempty"`

	// BuyerOrganizationName: Name of the buyer organization.
	BuyerOrganizationName string `json:"buyerOrganizationName,omitempty"`

	// Comments: Comments in this order.
	Comments string `json:"comments,omitempty"`

	// Contacts: Contacts for this order.
	Contacts []*OrderContact `json:"contacts,omitempty"`

	// Id: ID of this order. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#order".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this order.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this order.
	Name string `json:"name,omitempty"`

	// Notes: Notes of this order.
	Notes string `json:"notes,omitempty"`

	// PlanningTermId: ID of the terms and conditions template used in this
	// order.
	PlanningTermId int64 `json:"planningTermId,omitempty,string"`

	// ProjectId: Project ID of this order.
	ProjectId int64 `json:"projectId,omitempty,string"`

	// SellerOrderId: Seller order ID associated with this order.
	SellerOrderId string `json:"sellerOrderId,omitempty"`

	// SellerOrganizationName: Name of the seller organization.
	SellerOrganizationName string `json:"sellerOrganizationName,omitempty"`

	// SiteId: Site IDs this order is associated with.
	SiteId googleapi.Int64s `json:"siteId,omitempty"`

	// SiteNames: Free-form site names this order is associated with.
	SiteNames []string `json:"siteNames,omitempty"`

	// SubaccountId: Subaccount ID of this order.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TermsAndConditions: Terms and conditions of this order.
	TermsAndConditions string `json:"termsAndConditions,omitempty"`

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

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

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

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

// OrderContact: Contact of an order.
type OrderContact struct {
	// ContactInfo: Free-form information about this contact. It could be
	// any information related to this contact in addition to type, title,
	// name, and signature user profile ID.
	ContactInfo string `json:"contactInfo,omitempty"`

	// ContactName: Name of this contact.
	ContactName string `json:"contactName,omitempty"`

	// ContactTitle: Title of this contact.
	ContactTitle string `json:"contactTitle,omitempty"`

	// ContactType: Type of this contact.
	//
	// Possible values:
	//   "PLANNING_ORDER_CONTACT_BUYER_CONTACT"
	//   "PLANNING_ORDER_CONTACT_BUYER_BILLING_CONTACT"
	//   "PLANNING_ORDER_CONTACT_SELLER_CONTACT"
	ContactType string `json:"contactType,omitempty"`

	// SignatureUserProfileId: ID of the user profile containing the
	// signature that will be embedded into order documents.
	SignatureUserProfileId int64 `json:"signatureUserProfileId,omitempty,string"`

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

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

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

// OrderDocument: Contains properties of a Planning order document.
type OrderDocument struct {
	// AccountId: Account ID of this order document.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this order document.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AmendedOrderDocumentId: The amended order document ID of this order
	// document. An order document can be created by optionally amending
	// another order document so that the change history can be preserved.
	AmendedOrderDocumentId int64 `json:"amendedOrderDocumentId,omitempty,string"`

	// ApprovedByUserProfileIds: IDs of users who have approved this order
	// document.
	ApprovedByUserProfileIds googleapi.Int64s `json:"approvedByUserProfileIds,omitempty"`

	// Cancelled: Whether this order document is cancelled.
	Cancelled bool `json:"cancelled,omitempty"`

	// CreatedInfo: Information about the creation of this order document.
	CreatedInfo *LastModifiedInfo `json:"createdInfo,omitempty"`

	EffectiveDate string `json:"effectiveDate,omitempty"`

	// Id: ID of this order document.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#orderDocument".
	Kind string `json:"kind,omitempty"`

	// LastSentRecipients: List of email addresses that received the last
	// sent document.
	LastSentRecipients []string `json:"lastSentRecipients,omitempty"`

	LastSentTime string `json:"lastSentTime,omitempty"`

	// OrderId: ID of the order from which this order document is created.
	OrderId int64 `json:"orderId,omitempty,string"`

	// ProjectId: Project ID of this order document.
	ProjectId int64 `json:"projectId,omitempty,string"`

	// Signed: Whether this order document has been signed.
	Signed bool `json:"signed,omitempty"`

	// SubaccountId: Subaccount ID of this order document.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// Title: Title of this order document.
	Title string `json:"title,omitempty"`

	// Type: Type of this order document
	//
	// Possible values:
	//   "PLANNING_ORDER_TYPE_INSERTION_ORDER"
	//   "PLANNING_ORDER_TYPE_CHANGE_ORDER"
	Type string `json:"type,omitempty"`

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

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

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

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

// OrderDocumentsListResponse: Order document List Response
type OrderDocumentsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#orderDocumentsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// OrderDocuments: Order document collection
	OrderDocuments []*OrderDocument `json:"orderDocuments,omitempty"`

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

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

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

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

// OrdersListResponse: Order List Response
type OrdersListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#ordersListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Orders: Order collection.
	Orders []*Order `json:"orders,omitempty"`

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

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

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

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

// PathFilter: Represents a DfaReporting path filter.
type PathFilter struct {
	// EventFilters: Event filters in path report.
	EventFilters []*EventFilter `json:"eventFilters,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#pathFilter.
	Kind string `json:"kind,omitempty"`

	// PathMatchPosition: Determines how the 'value' field is matched when
	// filtering. If not specified, defaults to EXACT. If set to
	// WILDCARD_EXPRESSION, '*' is allowed as a placeholder for variable
	// length character sequences, and it can be escaped with a backslash.
	// Note, only paid search dimensions ('dfa:paidSearch*') allow a
	// matchType other than EXACT.
	//
	// Possible values:
	//   "PATH_MATCH_POSITION_UNSPECIFIED"
	//   "ANY"
	//   "FIRST"
	//   "LAST"
	PathMatchPosition string `json:"pathMatchPosition,omitempty"`

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

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

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

// PathReportCompatibleFields: Represents fields that are compatible to
// be selected for a report of type "PATH".
type PathReportCompatibleFields struct {
	// ChannelGroupings: Dimensions which are compatible to be selected in
	// the "channelGroupings" section of the report.
	ChannelGroupings []*Dimension `json:"channelGroupings,omitempty"`

	// Dimensions: Dimensions which are compatible to be selected in the
	// "dimensions" section of the report.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#pathReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// PathFilters: Dimensions which are compatible to be selected in the
	// "pathFilters" section of the report.
	PathFilters []*Dimension `json:"pathFilters,omitempty"`

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

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

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

// PathReportDimensionValue: Represents a PathReportDimensionValue
// resource.
type PathReportDimensionValue struct {
	// DimensionName: The name of the dimension.
	DimensionName string `json:"dimensionName,omitempty"`

	// Ids: The possible ID's associated with the value if available.
	Ids []string `json:"ids,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#pathReportDimensionValue.
	Kind string `json:"kind,omitempty"`

	// MatchType: Determines how the 'value' field is matched when
	// filtering. If not specified, defaults to EXACT. If set to
	// WILDCARD_EXPRESSION, '*' is allowed as a placeholder for variable
	// length character sequences, and it can be escaped with a backslash.
	// Note, only paid search dimensions ('dfa:paidSearch*') allow a
	// matchType other than EXACT.
	//
	// Possible values:
	//   "EXACT"
	//   "BEGINS_WITH"
	//   "CONTAINS"
	//   "WILDCARD_EXPRESSION"
	MatchType string `json:"matchType,omitempty"`

	// Values: The possible values of the dimension.
	Values []string `json:"values,omitempty"`

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

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

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

// PathToConversionReportCompatibleFields: Represents fields that are
// compatible to be selected for a report of type "PATH_TO_CONVERSION".
type PathToConversionReportCompatibleFields struct {
	// ConversionDimensions: Conversion dimensions which are compatible to
	// be selected in the "conversionDimensions" section of the report.
	ConversionDimensions []*Dimension `json:"conversionDimensions,omitempty"`

	// CustomFloodlightVariables: Custom floodlight variables which are
	// compatible to be selected in the "customFloodlightVariables" section
	// of the report.
	CustomFloodlightVariables []*Dimension `json:"customFloodlightVariables,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#pathToConversionReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// PerInteractionDimensions: Per-interaction dimensions which are
	// compatible to be selected in the "perInteractionDimensions" section
	// of the report.
	PerInteractionDimensions []*Dimension `json:"perInteractionDimensions,omitempty"`

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

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

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

// Placement: Contains properties of a placement.
type Placement struct {
	// AccountId: Account ID of this placement. This field can be left
	// blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdBlockingOptOut: Whether this placement opts out of ad blocking.
	// When true, ad blocking is disabled for this placement. When false,
	// the campaign and site settings take effect.
	AdBlockingOptOut bool `json:"adBlockingOptOut,omitempty"`

	// AdditionalSizes: Additional sizes associated with this placement.
	// When inserting or updating a placement, only the size ID field is
	// used.
	AdditionalSizes []*Size `json:"additionalSizes,omitempty"`

	// AdvertiserId: Advertiser ID of this placement. This field can be left
	// blank.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Archived: Whether this placement is archived.
	Archived bool `json:"archived,omitempty"`

	// CampaignId: Campaign ID of this placement. This field is a required
	// field on insertion.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CampaignIdDimensionValue: Dimension value for the ID of the campaign.
	// This is a read-only, auto-generated field.
	CampaignIdDimensionValue *DimensionValue `json:"campaignIdDimensionValue,omitempty"`

	// Comment: Comments for this placement.
	Comment string `json:"comment,omitempty"`

	// Compatibility: Placement compatibility. DISPLAY and
	// DISPLAY_INTERSTITIAL refer to rendering on desktop, on mobile devices
	// or in mobile apps for regular or interstitial ads respectively. APP
	// and APP_INTERSTITIAL are no longer allowed for new placement
	// insertions. Instead, use DISPLAY or DISPLAY_INTERSTITIAL.
	// IN_STREAM_VIDEO refers to rendering in in-stream video ads developed
	// with the VAST standard. This field is required on insertion.
	//
	// Possible values:
	//   "DISPLAY"
	//   "DISPLAY_INTERSTITIAL"
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	//   "IN_STREAM_AUDIO"
	Compatibility string `json:"compatibility,omitempty"`

	// ContentCategoryId: ID of the content category assigned to this
	// placement.
	ContentCategoryId int64 `json:"contentCategoryId,omitempty,string"`

	// CreateInfo: Information about the creation of this placement. This is
	// a read-only field.
	CreateInfo *LastModifiedInfo `json:"createInfo,omitempty"`

	// DirectorySiteId: Directory site ID of this placement. On insert, you
	// must set either this field or the siteId field to specify the site
	// associated with this placement. This is a required field that is
	// read-only after insertion.
	DirectorySiteId int64 `json:"directorySiteId,omitempty,string"`

	// DirectorySiteIdDimensionValue: Dimension value for the ID of the
	// directory site. This is a read-only, auto-generated field.
	DirectorySiteIdDimensionValue *DimensionValue `json:"directorySiteIdDimensionValue,omitempty"`

	// ExternalId: External ID for this placement.
	ExternalId string `json:"externalId,omitempty"`

	// Id: ID of this placement. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this placement. This
	// is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// KeyName: Key name of this placement. This is a read-only,
	// auto-generated field.
	KeyName string `json:"keyName,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placement".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this placement. This is a read-only field.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// LookbackConfiguration: Lookback window settings for this placement.
	LookbackConfiguration *LookbackConfiguration `json:"lookbackConfiguration,omitempty"`

	// Name: Name of this placement.This is a required field and must be
	// less than 256 characters long.
	Name string `json:"name,omitempty"`

	// PaymentApproved: Whether payment was approved for this placement.
	// This is a read-only field relevant only to publisher-paid placements.
	PaymentApproved bool `json:"paymentApproved,omitempty"`

	// PaymentSource: Payment source for this placement. This is a required
	// field that is read-only after insertion.
	//
	// Possible values:
	//   "PLACEMENT_AGENCY_PAID"
	//   "PLACEMENT_PUBLISHER_PAID"
	PaymentSource string `json:"paymentSource,omitempty"`

	// PlacementGroupId: ID of this placement's group, if applicable.
	PlacementGroupId int64 `json:"placementGroupId,omitempty,string"`

	// PlacementGroupIdDimensionValue: Dimension value for the ID of the
	// placement group. This is a read-only, auto-generated field.
	PlacementGroupIdDimensionValue *DimensionValue `json:"placementGroupIdDimensionValue,omitempty"`

	// PlacementStrategyId: ID of the placement strategy assigned to this
	// placement.
	PlacementStrategyId int64 `json:"placementStrategyId,omitempty,string"`

	// PricingSchedule: Pricing schedule of this placement. This field is
	// required on insertion, specifically subfields startDate, endDate and
	// pricingType.
	PricingSchedule *PricingSchedule `json:"pricingSchedule,omitempty"`

	// Primary: Whether this placement is the primary placement of a
	// roadblock (placement group). You cannot change this field from true
	// to false. Setting this field to true will automatically set the
	// primary field on the original primary placement of the roadblock to
	// false, and it will automatically set the roadblock's
	// primaryPlacementId field to the ID of this placement.
	Primary bool `json:"primary,omitempty"`

	// PublisherUpdateInfo: Information about the last publisher update.
	// This is a read-only field.
	PublisherUpdateInfo *LastModifiedInfo `json:"publisherUpdateInfo,omitempty"`

	// SiteId: Site ID associated with this placement. On insert, you must
	// set either this field or the directorySiteId field to specify the
	// site associated with this placement. This is a required field that is
	// read-only after insertion.
	SiteId int64 `json:"siteId,omitempty,string"`

	// SiteIdDimensionValue: Dimension value for the ID of the site. This is
	// a read-only, auto-generated field.
	SiteIdDimensionValue *DimensionValue `json:"siteIdDimensionValue,omitempty"`

	// Size: Size associated with this placement. When inserting or updating
	// a placement, only the size ID field is used. This field is required
	// on insertion.
	Size *Size `json:"size,omitempty"`

	// SslRequired: Whether creatives assigned to this placement must be
	// SSL-compliant.
	SslRequired bool `json:"sslRequired,omitempty"`

	// Status: Third-party placement status.
	//
	// Possible values:
	//   "PENDING_REVIEW"
	//   "PAYMENT_ACCEPTED"
	//   "PAYMENT_REJECTED"
	//   "ACKNOWLEDGE_REJECTION"
	//   "ACKNOWLEDGE_ACCEPTANCE"
	//   "DRAFT"
	Status string `json:"status,omitempty"`

	// SubaccountId: Subaccount ID of this placement. This field can be left
	// blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TagFormats: Tag formats to generate for this placement. This field is
	// required on insertion. Acceptable values are: -
	// "PLACEMENT_TAG_STANDARD" - "PLACEMENT_TAG_IFRAME_JAVASCRIPT" -
	// "PLACEMENT_TAG_IFRAME_ILAYER" - "PLACEMENT_TAG_INTERNAL_REDIRECT" -
	// "PLACEMENT_TAG_JAVASCRIPT" -
	// "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT" -
	// "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT" -
	// "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT" -
	// "PLACEMENT_TAG_CLICK_COMMANDS" -
	// "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH" -
	// "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3" -
	// "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_4" -
	// "PLACEMENT_TAG_TRACKING" - "PLACEMENT_TAG_TRACKING_IFRAME" -
	// "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
	//
	// Possible values:
	//   "PLACEMENT_TAG_STANDARD"
	//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT"
	//   "PLACEMENT_TAG_IFRAME_ILAYER"
	//   "PLACEMENT_TAG_INTERNAL_REDIRECT"
	//   "PLACEMENT_TAG_JAVASCRIPT"
	//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT"
	//   "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT"
	//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT"
	//   "PLACEMENT_TAG_CLICK_COMMANDS"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH"
	//   "PLACEMENT_TAG_TRACKING"
	//   "PLACEMENT_TAG_TRACKING_IFRAME"
	//   "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3"
	//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_4"
	TagFormats []string `json:"tagFormats,omitempty"`

	// TagSetting: Tag settings for this placement.
	TagSetting *TagSetting `json:"tagSetting,omitempty"`

	// VideoActiveViewOptOut: Whether Verification and ActiveView are
	// disabled for in-stream video creatives for this placement. The same
	// setting videoActiveViewOptOut exists on the site level -- the opt out
	// occurs if either of these settings are true. These settings are
	// distinct from DirectorySites.settings.activeViewOptOut or
	// Sites.siteSettings.activeViewOptOut which only apply to display ads.
	// However, Accounts.activeViewOptOut opts out both video traffic, as
	// well as display ads, from Verification and ActiveView.
	VideoActiveViewOptOut bool `json:"videoActiveViewOptOut,omitempty"`

	// VideoSettings: A collection of settings which affect video creatives
	// served through this placement. Applicable to placements with
	// IN_STREAM_VIDEO compatibility.
	VideoSettings *VideoSettings `json:"videoSettings,omitempty"`

	// VpaidAdapterChoice: VPAID adapter setting for this placement.
	// Controls which VPAID format the measurement adapter will use for
	// in-stream video creatives assigned to this placement. *Note:* Flash
	// is no longer supported. This field now defaults to HTML5 when the
	// following values are provided: FLASH, BOTH.
	//
	// Possible values:
	//   "DEFAULT"
	//   "FLASH"
	//   "HTML5"
	//   "BOTH"
	VpaidAdapterChoice string `json:"vpaidAdapterChoice,omitempty"`

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

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

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

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

// PlacementAssignment: Placement Assignment.
type PlacementAssignment struct {
	// Active: Whether this placement assignment is active. When true, the
	// placement will be included in the ad's rotation.
	Active bool `json:"active,omitempty"`

	// PlacementId: ID of the placement to be assigned. This is a required
	// field.
	PlacementId int64 `json:"placementId,omitempty,string"`

	// PlacementIdDimensionValue: Dimension value for the ID of the
	// placement. This is a read-only, auto-generated field.
	PlacementIdDimensionValue *DimensionValue `json:"placementIdDimensionValue,omitempty"`

	// SslRequired: Whether the placement to be assigned requires SSL. This
	// is a read-only field that is auto-generated when the ad is inserted
	// or updated.
	SslRequired bool `json:"sslRequired,omitempty"`

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

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

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

// PlacementGroup: Contains properties of a package or roadblock.
type PlacementGroup struct {
	// AccountId: Account ID of this placement group. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this placement group. This is a
	// required field on insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Archived: Whether this placement group is archived.
	Archived bool `json:"archived,omitempty"`

	// CampaignId: Campaign ID of this placement group. This field is
	// required on insertion.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CampaignIdDimensionValue: Dimension value for the ID of the campaign.
	// This is a read-only, auto-generated field.
	CampaignIdDimensionValue *DimensionValue `json:"campaignIdDimensionValue,omitempty"`

	// ChildPlacementIds: IDs of placements which are assigned to this
	// placement group. This is a read-only, auto-generated field.
	ChildPlacementIds googleapi.Int64s `json:"childPlacementIds,omitempty"`

	// Comment: Comments for this placement group.
	Comment string `json:"comment,omitempty"`

	// ContentCategoryId: ID of the content category assigned to this
	// placement group.
	ContentCategoryId int64 `json:"contentCategoryId,omitempty,string"`

	// CreateInfo: Information about the creation of this placement group.
	// This is a read-only field.
	CreateInfo *LastModifiedInfo `json:"createInfo,omitempty"`

	// DirectorySiteId: Directory site ID associated with this placement
	// group. On insert, you must set either this field or the site_id field
	// to specify the site associated with this placement group. This is a
	// required field that is read-only after insertion.
	DirectorySiteId int64 `json:"directorySiteId,omitempty,string"`

	// DirectorySiteIdDimensionValue: Dimension value for the ID of the
	// directory site. This is a read-only, auto-generated field.
	DirectorySiteIdDimensionValue *DimensionValue `json:"directorySiteIdDimensionValue,omitempty"`

	// ExternalId: External ID for this placement.
	ExternalId string `json:"externalId,omitempty"`

	// Id: ID of this placement group. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this placement group.
	// This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementGroup".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this placement group. This is a read-only field.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this placement group. This is a required field and must
	// be less than 256 characters long.
	Name string `json:"name,omitempty"`

	// PlacementGroupType: Type of this placement group. A package is a
	// simple group of placements that acts as a single pricing point for a
	// group of tags. A roadblock is a group of placements that not only
	// acts as a single pricing point, but also assumes that all the tags in
	// it will be served at the same time. A roadblock requires one of its
	// assigned placements to be marked as primary for reporting. This field
	// is required on insertion.
	//
	// Possible values:
	//   "PLACEMENT_PACKAGE"
	//   "PLACEMENT_ROADBLOCK"
	PlacementGroupType string `json:"placementGroupType,omitempty"`

	// PlacementStrategyId: ID of the placement strategy assigned to this
	// placement group.
	PlacementStrategyId int64 `json:"placementStrategyId,omitempty,string"`

	// PricingSchedule: Pricing schedule of this placement group. This field
	// is required on insertion.
	PricingSchedule *PricingSchedule `json:"pricingSchedule,omitempty"`

	// PrimaryPlacementId: ID of the primary placement, used to calculate
	// the media cost of a roadblock (placement group). Modifying this field
	// will automatically modify the primary field on all affected roadblock
	// child placements.
	PrimaryPlacementId int64 `json:"primaryPlacementId,omitempty,string"`

	// PrimaryPlacementIdDimensionValue: Dimension value for the ID of the
	// primary placement. This is a read-only, auto-generated field.
	PrimaryPlacementIdDimensionValue *DimensionValue `json:"primaryPlacementIdDimensionValue,omitempty"`

	// SiteId: Site ID associated with this placement group. On insert, you
	// must set either this field or the directorySiteId field to specify
	// the site associated with this placement group. This is a required
	// field that is read-only after insertion.
	SiteId int64 `json:"siteId,omitempty,string"`

	// SiteIdDimensionValue: Dimension value for the ID of the site. This is
	// a read-only, auto-generated field.
	SiteIdDimensionValue *DimensionValue `json:"siteIdDimensionValue,omitempty"`

	// SubaccountId: Subaccount ID of this placement group. This is a
	// read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// PlacementGroupsListResponse: Placement Group List Response
type PlacementGroupsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PlacementGroups: Placement group collection.
	PlacementGroups []*PlacementGroup `json:"placementGroups,omitempty"`

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

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

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

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

// PlacementStrategiesListResponse: Placement Strategy List Response
type PlacementStrategiesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementStrategiesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PlacementStrategies: Placement strategy collection.
	PlacementStrategies []*PlacementStrategy `json:"placementStrategies,omitempty"`

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

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

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

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

// PlacementStrategy: Contains properties of a placement strategy.
type PlacementStrategy struct {
	// AccountId: Account ID of this placement strategy.This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Id: ID of this placement strategy. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementStrategy".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this placement strategy. This is a required field. It
	// must be less than 256 characters long and unique among placement
	// strategies of the same account.
	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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// PlacementTag: Placement Tag
type PlacementTag struct {
	// PlacementId: Placement ID
	PlacementId int64 `json:"placementId,omitempty,string"`

	// TagDatas: Tags generated for this placement.
	TagDatas []*TagData `json:"tagDatas,omitempty"`

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

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

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

// PlacementsGenerateTagsResponse: Placement GenerateTags Response
type PlacementsGenerateTagsResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementsGenerateTagsResponse".
	Kind string `json:"kind,omitempty"`

	// PlacementTags: Set of generated tags for the specified placements.
	PlacementTags []*PlacementTag `json:"placementTags,omitempty"`

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

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

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

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

// PlacementsListResponse: Placement List Response
type PlacementsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Placements: Placement collection.
	Placements []*Placement `json:"placements,omitempty"`

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

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

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

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

// PlatformType: Contains information about a platform type that can be
// targeted by ads.
type PlatformType struct {
	// Id: ID of this platform type.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#platformType".
	Kind string `json:"kind,omitempty"`

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

// PlatformTypesListResponse: Platform Type List Response
type PlatformTypesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#platformTypesListResponse".
	Kind string `json:"kind,omitempty"`

	// PlatformTypes: Platform type collection.
	PlatformTypes []*PlatformType `json:"platformTypes,omitempty"`

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

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

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

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

// PopupWindowProperties: Popup Window Properties.
type PopupWindowProperties struct {
	// Dimension: Popup dimension for a creative. This is a read-only field.
	// Applicable to the following creative types: all RICH_MEDIA and all
	// VPAID
	Dimension *Size `json:"dimension,omitempty"`

	// Offset: Upper-left corner coordinates of the popup window. Applicable
	// if positionType is COORDINATES.
	Offset *OffsetPosition `json:"offset,omitempty"`

	// PositionType: Popup window position either centered or at specific
	// coordinate.
	//
	// Possible values:
	//   "CENTER"
	//   "COORDINATES"
	PositionType string `json:"positionType,omitempty"`

	// ShowAddressBar: Whether to display the browser address bar.
	ShowAddressBar bool `json:"showAddressBar,omitempty"`

	// ShowMenuBar: Whether to display the browser menu bar.
	ShowMenuBar bool `json:"showMenuBar,omitempty"`

	// ShowScrollBar: Whether to display the browser scroll bar.
	ShowScrollBar bool `json:"showScrollBar,omitempty"`

	// ShowStatusBar: Whether to display the browser status bar.
	ShowStatusBar bool `json:"showStatusBar,omitempty"`

	// ShowToolBar: Whether to display the browser tool bar.
	ShowToolBar bool `json:"showToolBar,omitempty"`

	// Title: Title of popup window.
	Title string `json:"title,omitempty"`

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

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

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

// PostalCode: Contains information about a postal code that can be
// targeted by ads.
type PostalCode struct {
	// Code: Postal code. This is equivalent to the id field.
	Code string `json:"code,omitempty"`

	// CountryCode: Country code of the country to which this postal code
	// belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this postal code
	// belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// Id: ID of this postal code.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#postalCode".
	Kind string `json:"kind,omitempty"`

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

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

// PostalCodesListResponse: Postal Code List Response
type PostalCodesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#postalCodesListResponse".
	Kind string `json:"kind,omitempty"`

	// PostalCodes: Postal code collection.
	PostalCodes []*PostalCode `json:"postalCodes,omitempty"`

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

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

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

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

// Pricing: Pricing Information
type Pricing struct {
	// CapCostType: Cap cost type of this inventory item.
	//
	// Possible values:
	//   "PLANNING_PLACEMENT_CAP_COST_TYPE_NONE"
	//   "PLANNING_PLACEMENT_CAP_COST_TYPE_MONTHLY"
	//   "PLANNING_PLACEMENT_CAP_COST_TYPE_CUMULATIVE"
	CapCostType string `json:"capCostType,omitempty"`

	EndDate string `json:"endDate,omitempty"`

	// Flights: Flights of this inventory item. A flight (a.k.a. pricing
	// period) represents the inventory item pricing information for a
	// specific period of time.
	Flights []*Flight `json:"flights,omitempty"`

	// GroupType: Group type of this inventory item if it represents a
	// placement group. Is null otherwise. There are two type of placement
	// groups: PLANNING_PLACEMENT_GROUP_TYPE_PACKAGE is a simple group of
	// inventory items that acts as a single pricing point for a group of
	// tags. PLANNING_PLACEMENT_GROUP_TYPE_ROADBLOCK is a group of inventory
	// items that not only acts as a single pricing point, but also assumes
	// that all the tags in it will be served at the same time. A roadblock
	// requires one of its assigned inventory items to be marked as primary.
	//
	// Possible values:
	//   "PLANNING_PLACEMENT_GROUP_TYPE_PACKAGE"
	//   "PLANNING_PLACEMENT_GROUP_TYPE_ROADBLOCK"
	GroupType string `json:"groupType,omitempty"`

	// PricingType: Pricing type of this inventory item.
	//
	// Possible values:
	//   "PLANNING_PLACEMENT_PRICING_TYPE_IMPRESSIONS"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CPM"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CLICKS"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CPC"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CPA"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_FLAT_RATE_CLICKS"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CPM_ACTIVEVIEW"
	PricingType string `json:"pricingType,omitempty"`

	StartDate string `json:"startDate,omitempty"`

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

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

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

// PricingSchedule: Pricing Schedule
type PricingSchedule struct {
	// CapCostOption: Placement cap cost option.
	//
	// Possible values:
	//   "CAP_COST_NONE"
	//   "CAP_COST_MONTHLY"
	//   "CAP_COST_CUMULATIVE"
	CapCostOption string `json:"capCostOption,omitempty"`

	EndDate string `json:"endDate,omitempty"`

	// Flighted: Whether this placement is flighted. If true, pricing
	// periods will be computed automatically.
	Flighted bool `json:"flighted,omitempty"`

	// FloodlightActivityId: Floodlight activity ID associated with this
	// placement. This field should be set when placement pricing type is
	// set to PRICING_TYPE_CPA.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// PricingPeriods: Pricing periods for this placement.
	PricingPeriods []*PricingSchedulePricingPeriod `json:"pricingPeriods,omitempty"`

	// PricingType: Placement pricing type. This field is required on
	// insertion.
	//
	// Possible values:
	//   "PRICING_TYPE_CPM"
	//   "PRICING_TYPE_CPC"
	//   "PRICING_TYPE_CPA"
	//   "PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
	//   "PRICING_TYPE_FLAT_RATE_CLICKS"
	//   "PRICING_TYPE_CPM_ACTIVEVIEW"
	PricingType string `json:"pricingType,omitempty"`

	StartDate string `json:"startDate,omitempty"`

	TestingStartDate string `json:"testingStartDate,omitempty"`

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

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

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

// PricingSchedulePricingPeriod: Pricing Period
type PricingSchedulePricingPeriod struct {
	EndDate string `json:"endDate,omitempty"`

	// PricingComment: Comments for this pricing period.
	PricingComment string `json:"pricingComment,omitempty"`

	// RateOrCostNanos: Rate or cost of this pricing period in nanos (i.e.,
	// multipled by 1000000000). Acceptable values are 0 to
	// 1000000000000000000, inclusive.
	RateOrCostNanos int64 `json:"rateOrCostNanos,omitempty,string"`

	StartDate string `json:"startDate,omitempty"`

	// Units: Units of this pricing period. Acceptable values are 0 to
	// 10000000000, inclusive.
	Units int64 `json:"units,omitempty,string"`

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

// Project: Contains properties of a Planning project.
type Project struct {
	// AccountId: Account ID of this project.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this project.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AudienceAgeGroup: Audience age group of this project.
	//
	// Possible values:
	//   "PLANNING_AUDIENCE_AGE_18_24"
	//   "PLANNING_AUDIENCE_AGE_25_34"
	//   "PLANNING_AUDIENCE_AGE_35_44"
	//   "PLANNING_AUDIENCE_AGE_45_54"
	//   "PLANNING_AUDIENCE_AGE_55_64"
	//   "PLANNING_AUDIENCE_AGE_65_OR_MORE"
	//   "PLANNING_AUDIENCE_AGE_UNKNOWN"
	AudienceAgeGroup string `json:"audienceAgeGroup,omitempty"`

	// AudienceGender: Audience gender of this project.
	//
	// Possible values:
	//   "PLANNING_AUDIENCE_GENDER_MALE"
	//   "PLANNING_AUDIENCE_GENDER_FEMALE"
	AudienceGender string `json:"audienceGender,omitempty"`

	// Budget: Budget of this project in the currency specified by the
	// current account. The value stored in this field represents only the
	// non-fractional amount. For example, for USD, the smallest value that
	// can be represented by this field is 1 US dollar.
	Budget int64 `json:"budget,omitempty,string"`

	// ClientBillingCode: Client billing code of this project.
	ClientBillingCode string `json:"clientBillingCode,omitempty"`

	// ClientName: Name of the project client.
	ClientName string `json:"clientName,omitempty"`

	EndDate string `json:"endDate,omitempty"`

	// Id: ID of this project. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#project".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this project.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this project.
	Name string `json:"name,omitempty"`

	// Overview: Overview of this project.
	Overview string `json:"overview,omitempty"`

	StartDate string `json:"startDate,omitempty"`

	// SubaccountId: Subaccount ID of this project.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TargetClicks: Number of clicks that the advertiser is targeting.
	TargetClicks int64 `json:"targetClicks,omitempty,string"`

	// TargetConversions: Number of conversions that the advertiser is
	// targeting.
	TargetConversions int64 `json:"targetConversions,omitempty,string"`

	// TargetCpaNanos: CPA that the advertiser is targeting.
	TargetCpaNanos int64 `json:"targetCpaNanos,omitempty,string"`

	// TargetCpcNanos: CPC that the advertiser is targeting.
	TargetCpcNanos int64 `json:"targetCpcNanos,omitempty,string"`

	// TargetCpmActiveViewNanos: vCPM from Active View that the advertiser
	// is targeting.
	TargetCpmActiveViewNanos int64 `json:"targetCpmActiveViewNanos,omitempty,string"`

	// TargetCpmNanos: CPM that the advertiser is targeting.
	TargetCpmNanos int64 `json:"targetCpmNanos,omitempty,string"`

	// TargetImpressions: Number of impressions that the advertiser is
	// targeting.
	TargetImpressions int64 `json:"targetImpressions,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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// ProjectsListResponse: Project List Response
type ProjectsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#projectsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Projects: Project collection.
	Projects []*Project `json:"projects,omitempty"`

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

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

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

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

// ReachReportCompatibleFields: Represents fields that are compatible to
// be selected for a report of type "REACH".
type ReachReportCompatibleFields struct {
	// DimensionFilters: Dimensions which are compatible to be selected in
	// the "dimensionFilters" section of the report.
	DimensionFilters []*Dimension `json:"dimensionFilters,omitempty"`

	// Dimensions: Dimensions which are compatible to be selected in the
	// "dimensions" section of the report.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#reachReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// PivotedActivityMetrics: Metrics which are compatible to be selected
	// as activity metrics to pivot on in the "activities" section of the
	// report.
	PivotedActivityMetrics []*Metric `json:"pivotedActivityMetrics,omitempty"`

	// ReachByFrequencyMetrics: Metrics which are compatible to be selected
	// in the "reachByFrequencyMetricNames" section of the report.
	ReachByFrequencyMetrics []*Metric `json:"reachByFrequencyMetrics,omitempty"`

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

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

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

// Recipient: Represents a recipient.
type Recipient struct {
	// DeliveryType: The delivery type for the recipient.
	//
	// Possible values:
	//   "LINK"
	//   "ATTACHMENT"
	DeliveryType string `json:"deliveryType,omitempty"`

	// Email: The email address of the recipient.
	Email string `json:"email,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#recipient.
	Kind string `json:"kind,omitempty"`

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

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

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

// Region: Contains information about a region that can be targeted by
// ads.
type Region struct {
	// CountryCode: Country code of the country to which this region
	// belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this region belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// DartId: DART ID of this region.
	DartId int64 `json:"dartId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#region".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this region.
	Name string `json:"name,omitempty"`

	// RegionCode: Region code.
	RegionCode string `json:"regionCode,omitempty"`

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

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

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

// RegionsListResponse: Region List Response
type RegionsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#regionsListResponse".
	Kind string `json:"kind,omitempty"`

	// Regions: Region collection.
	Regions []*Region `json:"regions,omitempty"`

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

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

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

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

// RemarketingList: Contains properties of a remarketing list.
// Remarketing enables you to create lists of users who have performed
// specific actions on a site, then target ads to members of those
// lists. This resource can be used to manage remarketing lists that are
// owned by your advertisers. To see all remarketing lists that are
// visible to your advertisers, including those that are shared to your
// advertiser or account, use the TargetableRemarketingLists resource.
type RemarketingList struct {
	// AccountId: Account ID of this remarketing list. This is a read-only,
	// auto-generated field that is only returned in GET requests.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether this remarketing list is active.
	Active bool `json:"active,omitempty"`

	// AdvertiserId: Dimension value for the advertiser ID that owns this
	// remarketing list. This is a required field.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Description: Remarketing list description.
	Description string `json:"description,omitempty"`

	// Id: Remarketing list ID. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#remarketingList".
	Kind string `json:"kind,omitempty"`

	// LifeSpan: Number of days that a user should remain in the remarketing
	// list without an impression. Acceptable values are 1 to 540,
	// inclusive.
	LifeSpan int64 `json:"lifeSpan,omitempty,string"`

	// ListPopulationRule: Rule used to populate the remarketing list with
	// users.
	ListPopulationRule *ListPopulationRule `json:"listPopulationRule,omitempty"`

	// ListSize: Number of users currently in the list. This is a read-only
	// field.
	ListSize int64 `json:"listSize,omitempty,string"`

	// ListSource: Product from which this remarketing list was originated.
	//
	// Possible values:
	//   "REMARKETING_LIST_SOURCE_OTHER"
	//   "REMARKETING_LIST_SOURCE_ADX"
	//   "REMARKETING_LIST_SOURCE_DFP"
	//   "REMARKETING_LIST_SOURCE_XFP"
	//   "REMARKETING_LIST_SOURCE_DFA"
	//   "REMARKETING_LIST_SOURCE_GA"
	//   "REMARKETING_LIST_SOURCE_YOUTUBE"
	//   "REMARKETING_LIST_SOURCE_DBM"
	//   "REMARKETING_LIST_SOURCE_GPLUS"
	//   "REMARKETING_LIST_SOURCE_DMP"
	//   "REMARKETING_LIST_SOURCE_PLAY_STORE"
	ListSource string `json:"listSource,omitempty"`

	// Name: Name of the remarketing list. This is a required field. Must be
	// no greater than 128 characters long.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this remarketing list. This is a
	// read-only, auto-generated field that is only returned in GET
	// requests.
	SubaccountId int64 `json:"subaccountId,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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// RemarketingListShare: Contains properties of a remarketing list's
// sharing information. Sharing allows other accounts or advertisers to
// target to your remarketing lists. This resource can be used to manage
// remarketing list sharing to other accounts and advertisers.
type RemarketingListShare struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#remarketingListShare".
	Kind string `json:"kind,omitempty"`

	// RemarketingListId: Remarketing list ID. This is a read-only,
	// auto-generated field.
	RemarketingListId int64 `json:"remarketingListId,omitempty,string"`

	// SharedAccountIds: Accounts that the remarketing list is shared with.
	SharedAccountIds googleapi.Int64s `json:"sharedAccountIds,omitempty"`

	// SharedAdvertiserIds: Advertisers that the remarketing list is shared
	// with.
	SharedAdvertiserIds googleapi.Int64s `json:"sharedAdvertiserIds,omitempty"`

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

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

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

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

// RemarketingListsListResponse: Remarketing list response
type RemarketingListsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#remarketingListsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// RemarketingLists: Remarketing list collection.
	RemarketingLists []*RemarketingList `json:"remarketingLists,omitempty"`

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

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

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

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

// Report: Represents a Report resource.
type Report struct {
	// AccountId: The account ID to which this report belongs.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Criteria: The report criteria for a report of type "STANDARD".
	Criteria *ReportCriteria `json:"criteria,omitempty"`

	// CrossDimensionReachCriteria: The report criteria for a report of type
	// "CROSS_DIMENSION_REACH".
	CrossDimensionReachCriteria *ReportCrossDimensionReachCriteria `json:"crossDimensionReachCriteria,omitempty"`

	// Delivery: The report's email delivery settings.
	Delivery *ReportDelivery `json:"delivery,omitempty"`

	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// FileName: The filename used when generating report files for this
	// report.
	FileName string `json:"fileName,omitempty"`

	// FloodlightCriteria: The report criteria for a report of type
	// "FLOODLIGHT".
	FloodlightCriteria *ReportFloodlightCriteria `json:"floodlightCriteria,omitempty"`

	// Format: The output format of the report. If not specified, default
	// format is "CSV". Note that the actual format in the completed report
	// file might differ if for instance the report's size exceeds the
	// format's capabilities. "CSV" will then be the fallback format.
	//
	// Possible values:
	//   "CSV"
	//   "EXCEL"
	Format string `json:"format,omitempty"`

	// Id: The unique ID identifying this report resource.
	Id int64 `json:"id,omitempty,string"`

	// Kind: The kind of resource this is, in this case dfareporting#report.
	Kind string `json:"kind,omitempty"`

	// LastModifiedTime: The timestamp (in milliseconds since epoch) of when
	// this report was last modified.
	LastModifiedTime uint64 `json:"lastModifiedTime,omitempty,string"`

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

	// OwnerProfileId: The user profile id of the owner of this report.
	OwnerProfileId int64 `json:"ownerProfileId,omitempty,string"`

	// PathAttributionCriteria: The report criteria for a report of type
	// "PATH_ATTRIBUTION".
	PathAttributionCriteria *ReportPathAttributionCriteria `json:"pathAttributionCriteria,omitempty"`

	// PathCriteria: The report criteria for a report of type "PATH".
	PathCriteria *ReportPathCriteria `json:"pathCriteria,omitempty"`

	// PathToConversionCriteria: The report criteria for a report of type
	// "PATH_TO_CONVERSION".
	PathToConversionCriteria *ReportPathToConversionCriteria `json:"pathToConversionCriteria,omitempty"`

	// ReachCriteria: The report criteria for a report of type "REACH".
	ReachCriteria *ReportReachCriteria `json:"reachCriteria,omitempty"`

	// Schedule: The report's schedule. Can only be set if the report's
	// 'dateRange' is a relative date range and the relative date range is
	// not "TODAY".
	Schedule *ReportSchedule `json:"schedule,omitempty"`

	// SubAccountId: The subaccount ID to which this report belongs if
	// applicable.
	SubAccountId int64 `json:"subAccountId,omitempty,string"`

	// Type: The type of the report.
	//
	// Possible values:
	//   "STANDARD"
	//   "REACH"
	//   "PATH_TO_CONVERSION"
	//   "CROSS_DIMENSION_REACH"
	//   "FLOODLIGHT"
	//   "PATH"
	//   "PATH_ATTRIBUTION"
	Type string `json:"type,omitempty"`

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

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

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

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

// ReportCriteria: The report criteria for a report of type "STANDARD".
type ReportCriteria struct {
	// Activities: Activity group.
	Activities *Activities `json:"activities,omitempty"`

	// CustomRichMediaEvents: Custom Rich Media Events group.
	CustomRichMediaEvents *CustomRichMediaEvents `json:"customRichMediaEvents,omitempty"`

	// DateRange: The date range for which this report should be run.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// DimensionFilters: The list of filters on which dimensions are
	// filtered. Filters for different dimensions are ANDed, filters for the
	// same dimension are grouped together and ORed.
	DimensionFilters []*DimensionValue `json:"dimensionFilters,omitempty"`

	// Dimensions: The list of standard dimensions the report should
	// include.
	Dimensions []*SortedDimension `json:"dimensions,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

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

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

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

// ReportCrossDimensionReachCriteria: The report criteria for a report
// of type "CROSS_DIMENSION_REACH".
type ReportCrossDimensionReachCriteria struct {
	// Breakdown: The list of dimensions the report should include.
	Breakdown []*SortedDimension `json:"breakdown,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Dimension: The dimension option.
	//
	// Possible values:
	//   "ADVERTISER"
	//   "CAMPAIGN"
	//   "SITE_BY_ADVERTISER"
	//   "SITE_BY_CAMPAIGN"
	Dimension string `json:"dimension,omitempty"`

	// DimensionFilters: The list of filters on which dimensions are
	// filtered.
	DimensionFilters []*DimensionValue `json:"dimensionFilters,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// OverlapMetricNames: The list of names of overlap metrics the report
	// should include.
	OverlapMetricNames []string `json:"overlapMetricNames,omitempty"`

	// Pivoted: Whether the report is pivoted or not. Defaults to true.
	Pivoted bool `json:"pivoted,omitempty"`

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

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

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

// ReportDelivery: The report's email delivery settings.
type ReportDelivery struct {
	// EmailOwner: Whether the report should be emailed to the report owner.
	EmailOwner bool `json:"emailOwner,omitempty"`

	// EmailOwnerDeliveryType: The type of delivery for the owner to
	// receive, if enabled.
	//
	// Possible values:
	//   "LINK"
	//   "ATTACHMENT"
	EmailOwnerDeliveryType string `json:"emailOwnerDeliveryType,omitempty"`

	// Message: The message to be sent with each email.
	Message string `json:"message,omitempty"`

	// Recipients: The list of recipients to which to email the report.
	Recipients []*Recipient `json:"recipients,omitempty"`

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

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

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

// ReportFloodlightCriteria: The report criteria for a report of type
// "FLOODLIGHT".
type ReportFloodlightCriteria struct {
	// CustomRichMediaEvents: The list of custom rich media events to
	// include.
	CustomRichMediaEvents []*DimensionValue `json:"customRichMediaEvents,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// DimensionFilters: The list of filters on which dimensions are
	// filtered. Filters for different dimensions are ANDed, filters for the
	// same dimension are grouped together and ORed.
	DimensionFilters []*DimensionValue `json:"dimensionFilters,omitempty"`

	// Dimensions: The list of dimensions the report should include.
	Dimensions []*SortedDimension `json:"dimensions,omitempty"`

	// FloodlightConfigId: The floodlight ID for which to show data in this
	// report. All advertisers associated with that ID will automatically be
	// added. The dimension of the value needs to be
	// 'dfa:floodlightConfigId'.
	FloodlightConfigId *DimensionValue `json:"floodlightConfigId,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// ReportProperties: The properties of the report.
	ReportProperties *ReportFloodlightCriteriaReportProperties `json:"reportProperties,omitempty"`

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

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

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

// ReportFloodlightCriteriaReportProperties: The properties of the
// report.
type ReportFloodlightCriteriaReportProperties struct {
	// IncludeAttributedIPConversions: Include conversions that have no
	// cookie, but do have an exposure path.
	IncludeAttributedIPConversions bool `json:"includeAttributedIPConversions,omitempty"`

	// IncludeUnattributedCookieConversions: Include conversions of users
	// with a DoubleClick cookie but without an exposure. That means the
	// user did not click or see an ad from the advertiser within the
	// Floodlight group, or that the interaction happened outside the
	// lookback window.
	IncludeUnattributedCookieConversions bool `json:"includeUnattributedCookieConversions,omitempty"`

	// IncludeUnattributedIPConversions: Include conversions that have no
	// associated cookies and no exposures. It’s therefore impossible to
	// know how the user was exposed to your ads during the lookback window
	// prior to a conversion.
	IncludeUnattributedIPConversions bool `json:"includeUnattributedIPConversions,omitempty"`

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

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

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

// ReportPathAttributionCriteria: The report criteria for a report of
// type "PATH_ATTRIBUTION".
type ReportPathAttributionCriteria struct {
	// ActivityFilters: The list of 'dfa:activity' values to filter on.
	ActivityFilters []*DimensionValue `json:"activityFilters,omitempty"`

	// CustomChannelGrouping: Channel Grouping.
	CustomChannelGrouping *ChannelGrouping `json:"customChannelGrouping,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Dimensions: The list of dimensions the report should include.
	Dimensions []*SortedDimension `json:"dimensions,omitempty"`

	// FloodlightConfigId: The floodlight ID for which to show data in this
	// report. All advertisers associated with that ID will automatically be
	// added. The dimension of the value needs to be
	// 'dfa:floodlightConfigId'.
	FloodlightConfigId *DimensionValue `json:"floodlightConfigId,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// PathFilters: Path Filters.
	PathFilters []*PathFilter `json:"pathFilters,omitempty"`

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

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

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

// ReportPathCriteria: The report criteria for a report of type "PATH".
type ReportPathCriteria struct {
	// ActivityFilters: The list of 'dfa:activity' values to filter on.
	ActivityFilters []*DimensionValue `json:"activityFilters,omitempty"`

	// CustomChannelGrouping: Channel Grouping.
	CustomChannelGrouping *ChannelGrouping `json:"customChannelGrouping,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Dimensions: The list of dimensions the report should include.
	Dimensions []*SortedDimension `json:"dimensions,omitempty"`

	// FloodlightConfigId: The floodlight ID for which to show data in this
	// report. All advertisers associated with that ID will automatically be
	// added. The dimension of the value needs to be
	// 'dfa:floodlightConfigId'.
	FloodlightConfigId *DimensionValue `json:"floodlightConfigId,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// PathFilters: Path Filters.
	PathFilters []*PathFilter `json:"pathFilters,omitempty"`

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

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

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

// ReportPathToConversionCriteria: The report criteria for a report of
// type "PATH_TO_CONVERSION".
type ReportPathToConversionCriteria struct {
	// ActivityFilters: The list of 'dfa:activity' values to filter on.
	ActivityFilters []*DimensionValue `json:"activityFilters,omitempty"`

	// ConversionDimensions: The list of conversion dimensions the report
	// should include.
	ConversionDimensions []*SortedDimension `json:"conversionDimensions,omitempty"`

	// CustomFloodlightVariables: The list of custom floodlight variables
	// the report should include.
	CustomFloodlightVariables []*SortedDimension `json:"customFloodlightVariables,omitempty"`

	// CustomRichMediaEvents: The list of custom rich media events to
	// include.
	CustomRichMediaEvents []*DimensionValue `json:"customRichMediaEvents,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// FloodlightConfigId: The floodlight ID for which to show data in this
	// report. All advertisers associated with that ID will automatically be
	// added. The dimension of the value needs to be
	// 'dfa:floodlightConfigId'.
	FloodlightConfigId *DimensionValue `json:"floodlightConfigId,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// PerInteractionDimensions: The list of per interaction dimensions the
	// report should include.
	PerInteractionDimensions []*SortedDimension `json:"perInteractionDimensions,omitempty"`

	// ReportProperties: The properties of the report.
	ReportProperties *ReportPathToConversionCriteriaReportProperties `json:"reportProperties,omitempty"`

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

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

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

// ReportPathToConversionCriteriaReportProperties: The properties of the
// report.
type ReportPathToConversionCriteriaReportProperties struct {
	// ClicksLookbackWindow: DFA checks to see if a click interaction
	// occurred within the specified period of time before a conversion. By
	// default the value is pulled from Floodlight or you can manually enter
	// a custom value. Valid values: 1-90.
	ClicksLookbackWindow int64 `json:"clicksLookbackWindow,omitempty"`

	// ImpressionsLookbackWindow: DFA checks to see if an impression
	// interaction occurred within the specified period of time before a
	// conversion. By default the value is pulled from Floodlight or you can
	// manually enter a custom value. Valid values: 1-90.
	ImpressionsLookbackWindow int64 `json:"impressionsLookbackWindow,omitempty"`

	// IncludeAttributedIPConversions: Deprecated: has no effect.
	IncludeAttributedIPConversions bool `json:"includeAttributedIPConversions,omitempty"`

	// IncludeUnattributedCookieConversions: Include conversions of users
	// with a DoubleClick cookie but without an exposure. That means the
	// user did not click or see an ad from the advertiser within the
	// Floodlight group, or that the interaction happened outside the
	// lookback window.
	IncludeUnattributedCookieConversions bool `json:"includeUnattributedCookieConversions,omitempty"`

	// IncludeUnattributedIPConversions: Include conversions that have no
	// associated cookies and no exposures. It’s therefore impossible to
	// know how the user was exposed to your ads during the lookback window
	// prior to a conversion.
	IncludeUnattributedIPConversions bool `json:"includeUnattributedIPConversions,omitempty"`

	// MaximumClickInteractions: The maximum number of click interactions to
	// include in the report. Advertisers currently paying for E2C reports
	// get up to 200 (100 clicks, 100 impressions). If another advertiser in
	// your network is paying for E2C, you can have up to 5 total exposures
	// per report.
	MaximumClickInteractions int64 `json:"maximumClickInteractions,omitempty"`

	// MaximumImpressionInteractions: The maximum number of click
	// interactions to include in the report. Advertisers currently paying
	// for E2C reports get up to 200 (100 clicks, 100 impressions). If
	// another advertiser in your network is paying for E2C, you can have up
	// to 5 total exposures per report.
	MaximumImpressionInteractions int64 `json:"maximumImpressionInteractions,omitempty"`

	// MaximumInteractionGap: The maximum amount of time that can take place
	// between interactions (clicks or impressions) by the same user. Valid
	// values: 1-90.
	MaximumInteractionGap int64 `json:"maximumInteractionGap,omitempty"`

	// PivotOnInteractionPath: Enable pivoting on interaction path.
	PivotOnInteractionPath bool `json:"pivotOnInteractionPath,omitempty"`

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

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

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

// ReportReachCriteria: The report criteria for a report of type
// "REACH".
type ReportReachCriteria struct {
	// Activities: Activity group.
	Activities *Activities `json:"activities,omitempty"`

	// CustomRichMediaEvents: Custom Rich Media Events group.
	CustomRichMediaEvents *CustomRichMediaEvents `json:"customRichMediaEvents,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// DimensionFilters: The list of filters on which dimensions are
	// filtered. Filters for different dimensions are ANDed, filters for the
	// same dimension are grouped together and ORed.
	DimensionFilters []*DimensionValue `json:"dimensionFilters,omitempty"`

	// Dimensions: The list of dimensions the report should include.
	Dimensions []*SortedDimension `json:"dimensions,omitempty"`

	// EnableAllDimensionCombinations: Whether to enable all reach dimension
	// combinations in the report. Defaults to false. If enabled, the date
	// range of the report should be within the last 42 days.
	EnableAllDimensionCombinations bool `json:"enableAllDimensionCombinations,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// ReachByFrequencyMetricNames: The list of names of Reach By Frequency
	// metrics the report should include.
	ReachByFrequencyMetricNames []string `json:"reachByFrequencyMetricNames,omitempty"`

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

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

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

// ReportSchedule: The report's schedule. Can only be set if the
// report's 'dateRange' is a relative date range and the relative date
// range is not "TODAY".
type ReportSchedule struct {
	// Active: Whether the schedule is active or not. Must be set to either
	// true or false.
	Active bool `json:"active,omitempty"`

	// Every: Defines every how many days, weeks or months the report should
	// be run. Needs to be set when "repeats" is either "DAILY", "WEEKLY" or
	// "MONTHLY".
	Every int64 `json:"every,omitempty"`

	ExpirationDate string `json:"expirationDate,omitempty"`

	// Repeats: The interval for which the report is repeated. Note: -
	// "DAILY" also requires field "every" to be set. - "WEEKLY" also
	// requires fields "every" and "repeatsOnWeekDays" to be set. -
	// "MONTHLY" also requires fields "every" and "runsOnDayOfMonth" to be
	// set.
	Repeats string `json:"repeats,omitempty"`

	// RepeatsOnWeekDays: List of week days "WEEKLY" on which scheduled
	// reports should run.
	//
	// Possible values:
	//   "SUNDAY"
	//   "MONDAY"
	//   "TUESDAY"
	//   "WEDNESDAY"
	//   "THURSDAY"
	//   "FRIDAY"
	//   "SATURDAY"
	RepeatsOnWeekDays []string `json:"repeatsOnWeekDays,omitempty"`

	// RunsOnDayOfMonth: Enum to define for "MONTHLY" scheduled reports
	// whether reports should be repeated on the same day of the month as
	// "startDate" or the same day of the week of the month. Example: If
	// 'startDate' is Monday, April 2nd 2012 (2012-04-02), "DAY_OF_MONTH"
	// would run subsequent reports on the 2nd of every Month, and
	// "WEEK_OF_MONTH" would run subsequent reports on the first Monday of
	// the month.
	//
	// Possible values:
	//   "DAY_OF_MONTH"
	//   "WEEK_OF_MONTH"
	RunsOnDayOfMonth string `json:"runsOnDayOfMonth,omitempty"`

	StartDate string `json:"startDate,omitempty"`

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

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

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

// ReportCompatibleFields: Represents fields that are compatible to be
// selected for a report of type "STANDARD".
type ReportCompatibleFields struct {
	// DimensionFilters: Dimensions which are compatible to be selected in
	// the "dimensionFilters" section of the report.
	DimensionFilters []*Dimension `json:"dimensionFilters,omitempty"`

	// Dimensions: Dimensions which are compatible to be selected in the
	// "dimensions" section of the report.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#reportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// PivotedActivityMetrics: Metrics which are compatible to be selected
	// as activity metrics to pivot on in the "activities" section of the
	// report.
	PivotedActivityMetrics []*Metric `json:"pivotedActivityMetrics,omitempty"`

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

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

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

// ReportList: Represents the list of reports.
type ReportList struct {
	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Items: The reports returned in this response.
	Items []*Report `json:"items,omitempty"`

	// Kind: The kind of list this is, in this case dfareporting#reportList.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Continuation token used to page through reports. To
	// retrieve the next page of results, set the next request's "pageToken"
	// to the value of this field. The page token is only valid for a
	// limited amount of time and should not be persisted.
	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. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// ReportsConfiguration: Reporting Configuration
type ReportsConfiguration struct {
	// ExposureToConversionEnabled: Whether the exposure to conversion
	// report is enabled. This report shows detailed pathway information on
	// up to 10 of the most recent ad exposures seen by a user before
	// converting.
	ExposureToConversionEnabled bool `json:"exposureToConversionEnabled,omitempty"`

	// LookbackConfiguration: Default lookback windows for new advertisers
	// in this account.
	LookbackConfiguration *LookbackConfiguration `json:"lookbackConfiguration,omitempty"`

	// ReportGenerationTimeZoneId: Report generation time zone ID of this
	// account. This is a required field that can only be changed by a
	// superuser. Acceptable values are: - "1" for "America/New_York" - "2"
	// for "Europe/London" - "3" for "Europe/Paris" - "4" for
	// "Africa/Johannesburg" - "5" for "Asia/Jerusalem" - "6" for
	// "Asia/Shanghai" - "7" for "Asia/Hong_Kong" - "8" for "Asia/Tokyo" -
	// "9" for "Australia/Sydney" - "10" for "Asia/Dubai" - "11" for
	// "America/Los_Angeles" - "12" for "Pacific/Auckland" - "13" for
	// "America/Sao_Paulo" - "16" for "America/Asuncion" - "17" for
	// "America/Chicago" - "18" for "America/Denver" - "19" for
	// "America/St_Johns" - "20" for "Asia/Dhaka" - "21" for "Asia/Jakarta"
	// - "22" for "Asia/Kabul" - "23" for "Asia/Karachi" - "24" for
	// "Asia/Calcutta" - "25" for "Asia/Pyongyang" - "26" for "Asia/Rangoon"
	// - "27" for "Atlantic/Cape_Verde" - "28" for "Atlantic/South_Georgia"
	// - "29" for "Australia/Adelaide" - "30" for "Australia/Lord_Howe" -
	// "31" for "Europe/Moscow" - "32" for "Pacific/Kiritimati" - "35" for
	// "Pacific/Norfolk" - "36" for "Pacific/Tongatapu"
	ReportGenerationTimeZoneId int64 `json:"reportGenerationTimeZoneId,omitempty,string"`

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

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

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

// RichMediaExitOverride: Rich Media Exit Override.
type RichMediaExitOverride struct {
	// ClickThroughUrl: Click-through URL of this rich media exit override.
	// Applicable if the enabled field is set to true.
	ClickThroughUrl *ClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// Enabled: Whether to use the clickThroughUrl. If false, the
	// creative-level exit will be used.
	Enabled bool `json:"enabled,omitempty"`

	// ExitId: ID for the override to refer to a specific exit in the
	// creative.
	ExitId int64 `json:"exitId,omitempty,string"`

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

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

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

// Rule: A rule associates an asset with a targeting template for
// asset-level targeting. Applicable to INSTREAM_VIDEO creatives.
type Rule struct {
	// AssetId: A creativeAssets[].id. This should refer to one of the
	// parent assets in this creative. This is a required field.
	AssetId int64 `json:"assetId,omitempty,string"`

	// Name: A user-friendly name for this rule. This is a required field.
	Name string `json:"name,omitempty"`

	// TargetingTemplateId: A targeting template ID. The targeting from the
	// targeting template will be used to determine whether this asset
	// should be served. This is a required field.
	TargetingTemplateId int64 `json:"targetingTemplateId,omitempty,string"`

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

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

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

// Site: Contains properties of a site.
type Site struct {
	// AccountId: Account ID of this site. This is a read-only field that
	// can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Approved: Whether this site is approved.
	Approved bool `json:"approved,omitempty"`

	// DirectorySiteId: Directory site associated with this site. This is a
	// required field that is read-only after insertion.
	DirectorySiteId int64 `json:"directorySiteId,omitempty,string"`

	// DirectorySiteIdDimensionValue: Dimension value for the ID of the
	// directory site. This is a read-only, auto-generated field.
	DirectorySiteIdDimensionValue *DimensionValue `json:"directorySiteIdDimensionValue,omitempty"`

	// Id: ID of this site. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this site. This is a
	// read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// KeyName: Key name of this site. This is a read-only, auto-generated
	// field.
	KeyName string `json:"keyName,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#site".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this site.This is a required field. Must be less than
	// 128 characters long. If this site is under a subaccount, the name
	// must be unique among sites of the same subaccount. Otherwise, this
	// site is a top-level site, and the name must be unique among top-level
	// sites of the same account.
	Name string `json:"name,omitempty"`

	// SiteContacts: Site contacts.
	SiteContacts []*SiteContact `json:"siteContacts,omitempty"`

	// SiteSettings: Site-wide settings.
	SiteSettings *SiteSettings `json:"siteSettings,omitempty"`

	// SubaccountId: Subaccount ID of this site. This is a read-only field
	// that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// VideoSettings: Default video settings for new placements created
	// under this site. This value will be used to populate the
	// placements.videoSettings field, when no value is specified for the
	// new placement.
	VideoSettings *SiteVideoSettings `json:"videoSettings,omitempty"`

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

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

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

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

// SiteCompanionSetting: Companion Settings
type SiteCompanionSetting struct {
	// CompanionsDisabled: Whether companions are disabled for this site
	// template.
	CompanionsDisabled bool `json:"companionsDisabled,omitempty"`

	// EnabledSizes: Whitelist of companion sizes to be served via this site
	// template. Set this list to null or empty to serve all companion
	// sizes.
	EnabledSizes []*Size `json:"enabledSizes,omitempty"`

	// ImageOnly: Whether to serve only static images as companions.
	ImageOnly bool `json:"imageOnly,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#siteCompanionSetting".
	Kind string `json:"kind,omitempty"`

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

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

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

// SiteContact: Site Contact
type SiteContact struct {
	// Address: Address of this site contact.
	Address string `json:"address,omitempty"`

	// ContactType: Site contact type.
	//
	// Possible values:
	//   "SALES_PERSON"
	//   "TRAFFICKER"
	ContactType string `json:"contactType,omitempty"`

	// Email: Email address of this site contact. This is a required field.
	Email string `json:"email,omitempty"`

	// FirstName: First name of this site contact.
	FirstName string `json:"firstName,omitempty"`

	// Id: ID of this site contact. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// LastName: Last name of this site contact.
	LastName string `json:"lastName,omitempty"`

	// Phone: Primary phone number of this site contact.
	Phone string `json:"phone,omitempty"`

	// Title: Title or designation of this site contact.
	Title string `json:"title,omitempty"`

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

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

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

// SiteSettings: Site Settings
type SiteSettings struct {
	// ActiveViewOptOut: Whether active view creatives are disabled for this
	// site.
	ActiveViewOptOut bool `json:"activeViewOptOut,omitempty"`

	// AdBlockingOptOut: Whether this site opts out of ad blocking. When
	// true, ad blocking is disabled for all placements under the site,
	// regardless of the individual placement settings. When false, the
	// campaign and placement settings take effect.
	AdBlockingOptOut bool `json:"adBlockingOptOut,omitempty"`

	// DisableNewCookie: Whether new cookies are disabled for this site.
	DisableNewCookie bool `json:"disableNewCookie,omitempty"`

	// TagSetting: Configuration settings for dynamic and image floodlight
	// tags.
	TagSetting *TagSetting `json:"tagSetting,omitempty"`

	// VideoActiveViewOptOutTemplate: Whether Verification and ActiveView
	// for in-stream video creatives are disabled by default for new
	// placements created under this site. This value will be used to
	// populate the placement.videoActiveViewOptOut field, when no value is
	// specified for the new placement.
	VideoActiveViewOptOutTemplate bool `json:"videoActiveViewOptOutTemplate,omitempty"`

	// VpaidAdapterChoiceTemplate: Default VPAID adapter setting for new
	// placements created under this site. This value will be used to
	// populate the placements.vpaidAdapterChoice field, when no value is
	// specified for the new placement. Controls which VPAID format the
	// measurement adapter will use for in-stream video creatives assigned
	// to the placement. The publisher's specifications will typically
	// determine this setting. For VPAID creatives, the adapter format will
	// match the VPAID format (HTML5 VPAID creatives use the HTML5 adapter).
	// *Note:* Flash is no longer supported. This field now defaults to
	// HTML5 when the following values are provided: FLASH, BOTH.
	//
	// Possible values:
	//   "DEFAULT"
	//   "FLASH"
	//   "HTML5"
	//   "BOTH"
	VpaidAdapterChoiceTemplate string `json:"vpaidAdapterChoiceTemplate,omitempty"`

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

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

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

// SiteSkippableSetting: Skippable Settings
type SiteSkippableSetting struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#siteSkippableSetting".
	Kind string `json:"kind,omitempty"`

	// ProgressOffset: Amount of time to play videos served to this site
	// template before counting a view. Applicable when skippable is true.
	ProgressOffset *VideoOffset `json:"progressOffset,omitempty"`

	// SkipOffset: Amount of time to play videos served to this site before
	// the skip button should appear. Applicable when skippable is true.
	SkipOffset *VideoOffset `json:"skipOffset,omitempty"`

	// Skippable: Whether the user can skip creatives served to this site.
	// This will act as default for new placements created under this site.
	Skippable bool `json:"skippable,omitempty"`

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

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

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

// SiteTranscodeSetting: Transcode Settings
type SiteTranscodeSetting struct {
	// EnabledVideoFormats: Whitelist of video formats to be served to this
	// site template. Set this list to null or empty to serve all video
	// formats.
	EnabledVideoFormats []int64 `json:"enabledVideoFormats,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#siteTranscodeSetting".
	Kind string `json:"kind,omitempty"`

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

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

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

// SiteVideoSettings: Video Settings
type SiteVideoSettings struct {
	// CompanionSettings: Settings for the companion creatives of video
	// creatives served to this site.
	CompanionSettings *SiteCompanionSetting `json:"companionSettings,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#siteVideoSettings".
	Kind string `json:"kind,omitempty"`

	// ObaEnabled: Whether OBA icons are enabled for this placement.
	ObaEnabled bool `json:"obaEnabled,omitempty"`

	// ObaSettings: Settings for the OBA icon of video creatives served to
	// this site. This will act as default for new placements created under
	// this site.
	ObaSettings *ObaIcon `json:"obaSettings,omitempty"`

	// Orientation: Orientation of a site template used for video. This will
	// act as default for new placements created under this site.
	//
	// Possible values:
	//   "ANY"
	//   "LANDSCAPE"
	//   "PORTRAIT"
	Orientation string `json:"orientation,omitempty"`

	// SkippableSettings: Settings for the skippability of video creatives
	// served to this site. This will act as default for new placements
	// created under this site.
	SkippableSettings *SiteSkippableSetting `json:"skippableSettings,omitempty"`

	// TranscodeSettings: Settings for the transcodes of video creatives
	// served to this site. This will act as default for new placements
	// created under this site.
	TranscodeSettings *SiteTranscodeSetting `json:"transcodeSettings,omitempty"`

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

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

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

// SitesListResponse: Site List Response
type SitesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#sitesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

// Size: Represents the dimensions of ads, placements, creatives, or
// creative assets.
type Size struct {
	// Height: Height of this size. Acceptable values are 0 to 32767,
	// inclusive.
	Height int64 `json:"height,omitempty"`

	// Iab: IAB standard size. This is a read-only, auto-generated field.
	Iab bool `json:"iab,omitempty"`

	// Id: ID of this size. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#size".
	Kind string `json:"kind,omitempty"`

	// Width: Width of this size. Acceptable values are 0 to 32767,
	// inclusive.
	Width int64 `json:"width,omitempty"`

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

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

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

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

// SizesListResponse: Size List Response
type SizesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#sizesListResponse".
	Kind string `json:"kind,omitempty"`

	// Sizes: Size collection.
	Sizes []*Size `json:"sizes,omitempty"`

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

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

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

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

// SkippableSetting: Skippable Settings
type SkippableSetting struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#skippableSetting".
	Kind string `json:"kind,omitempty"`

	// ProgressOffset: Amount of time to play videos served to this
	// placement before counting a view. Applicable when skippable is true.
	ProgressOffset *VideoOffset `json:"progressOffset,omitempty"`

	// SkipOffset: Amount of time to play videos served to this placement
	// before the skip button should appear. Applicable when skippable is
	// true.
	SkipOffset *VideoOffset `json:"skipOffset,omitempty"`

	// Skippable: Whether the user can skip creatives served to this
	// placement.
	Skippable bool `json:"skippable,omitempty"`

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

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

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

// SortedDimension: Represents a sorted dimension.
type SortedDimension struct {
	// Kind: The kind of resource this is, in this case
	// dfareporting#sortedDimension.
	Kind string `json:"kind,omitempty"`

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

	// SortOrder: An optional sort order for the dimension column.
	//
	// Possible values:
	//   "ASCENDING"
	//   "DESCENDING"
	SortOrder string `json:"sortOrder,omitempty"`

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

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

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

// Subaccount: Contains properties of a Campaign Manager subaccount.
type Subaccount struct {
	// AccountId: ID of the account that contains this subaccount. This is a
	// read-only field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AvailablePermissionIds: IDs of the available user role permissions
	// for this subaccount.
	AvailablePermissionIds googleapi.Int64s `json:"availablePermissionIds,omitempty"`

	// Id: ID of this subaccount. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#subaccount".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this subaccount. This is a required field. Must be less
	// than 128 characters long and be unique among subaccounts of the same
	// account.
	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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// SubaccountsListResponse: Subaccount List Response
type SubaccountsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#subaccountsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Subaccounts: Subaccount collection.
	Subaccounts []*Subaccount `json:"subaccounts,omitempty"`

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

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

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

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

// TagData: Placement Tag Data
type TagData struct {
	// AdId: Ad associated with this placement tag. Applicable only when
	// format is PLACEMENT_TAG_TRACKING.
	AdId int64 `json:"adId,omitempty,string"`

	// ClickTag: Tag string to record a click.
	ClickTag string `json:"clickTag,omitempty"`

	// CreativeId: Creative associated with this placement tag. Applicable
	// only when format is PLACEMENT_TAG_TRACKING.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// Format: TagData tag format of this tag.
	//
	// Possible values:
	//   "PLACEMENT_TAG_STANDARD"
	//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT"
	//   "PLACEMENT_TAG_IFRAME_ILAYER"
	//   "PLACEMENT_TAG_INTERNAL_REDIRECT"
	//   "PLACEMENT_TAG_JAVASCRIPT"
	//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT"
	//   "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT"
	//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT"
	//   "PLACEMENT_TAG_CLICK_COMMANDS"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH"
	//   "PLACEMENT_TAG_TRACKING"
	//   "PLACEMENT_TAG_TRACKING_IFRAME"
	//   "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3"
	//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_4"
	Format string `json:"format,omitempty"`

	// ImpressionTag: Tag string for serving an ad.
	ImpressionTag string `json:"impressionTag,omitempty"`

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

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

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

// TagSetting: Tag Settings
type TagSetting struct {
	// AdditionalKeyValues: Additional key-values to be included in tags.
	// Each key-value pair must be of the form key=value, and pairs must be
	// separated by a semicolon (;). Keys and values must not contain
	// commas. For example, id=2;color=red is a valid value for this field.
	AdditionalKeyValues string `json:"additionalKeyValues,omitempty"`

	// IncludeClickThroughUrls: Whether static landing page URLs should be
	// included in the tags. This setting applies only to placements.
	IncludeClickThroughUrls bool `json:"includeClickThroughUrls,omitempty"`

	// IncludeClickTracking: Whether click-tracking string should be
	// included in the tags.
	IncludeClickTracking bool `json:"includeClickTracking,omitempty"`

	// KeywordOption: Option specifying how keywords are embedded in ad
	// tags. This setting can be used to specify whether keyword
	// placeholders are inserted in placement tags for this site. Publishers
	// can then add keywords to those placeholders.
	//
	// Possible values:
	//   "PLACEHOLDER_WITH_LIST_OF_KEYWORDS"
	//   "IGNORE"
	//   "GENERATE_SEPARATE_TAG_FOR_EACH_KEYWORD"
	KeywordOption string `json:"keywordOption,omitempty"`

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

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

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

// TagSettings: Dynamic and Image Tag Settings.
type TagSettings struct {
	// DynamicTagEnabled: Whether dynamic floodlight tags are enabled.
	DynamicTagEnabled bool `json:"dynamicTagEnabled,omitempty"`

	// ImageTagEnabled: Whether image tags are enabled.
	ImageTagEnabled bool `json:"imageTagEnabled,omitempty"`

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

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

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

// TargetWindow: Target Window.
type TargetWindow struct {
	// CustomHtml: User-entered value.
	CustomHtml string `json:"customHtml,omitempty"`

	// TargetWindowOption: Type of browser window for which the backup image
	// of the flash creative can be displayed.
	//
	// Possible values:
	//   "NEW_WINDOW"
	//   "CURRENT_WINDOW"
	//   "CUSTOM"
	TargetWindowOption string `json:"targetWindowOption,omitempty"`

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

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

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

// TargetableRemarketingList: Contains properties of a targetable
// remarketing list. Remarketing enables you to create lists of users
// who have performed specific actions on a site, then target ads to
// members of those lists. This resource is a read-only view of a
// remarketing list to be used to faciliate targeting ads to specific
// lists. Remarketing lists that are owned by your advertisers and those
// that are shared to your advertisers or account are accessible via
// this resource. To manage remarketing lists that are owned by your
// advertisers, use the RemarketingLists resource.
type TargetableRemarketingList struct {
	// AccountId: Account ID of this remarketing list. This is a read-only,
	// auto-generated field that is only returned in GET requests.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether this targetable remarketing list is active.
	Active bool `json:"active,omitempty"`

	// AdvertiserId: Dimension value for the advertiser ID that owns this
	// targetable remarketing list.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Description: Targetable remarketing list description.
	Description string `json:"description,omitempty"`

	// Id: Targetable remarketing list ID.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#targetableRemarketingList".
	Kind string `json:"kind,omitempty"`

	// LifeSpan: Number of days that a user should remain in the targetable
	// remarketing list without an impression.
	LifeSpan int64 `json:"lifeSpan,omitempty,string"`

	// ListSize: Number of users currently in the list. This is a read-only
	// field.
	ListSize int64 `json:"listSize,omitempty,string"`

	// ListSource: Product from which this targetable remarketing list was
	// originated.
	//
	// Possible values:
	//   "REMARKETING_LIST_SOURCE_OTHER"
	//   "REMARKETING_LIST_SOURCE_ADX"
	//   "REMARKETING_LIST_SOURCE_DFP"
	//   "REMARKETING_LIST_SOURCE_XFP"
	//   "REMARKETING_LIST_SOURCE_DFA"
	//   "REMARKETING_LIST_SOURCE_GA"
	//   "REMARKETING_LIST_SOURCE_YOUTUBE"
	//   "REMARKETING_LIST_SOURCE_DBM"
	//   "REMARKETING_LIST_SOURCE_GPLUS"
	//   "REMARKETING_LIST_SOURCE_DMP"
	//   "REMARKETING_LIST_SOURCE_PLAY_STORE"
	ListSource string `json:"listSource,omitempty"`

	// Name: Name of the targetable remarketing list. Is no greater than 128
	// characters long.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this remarketing list. This is a
	// read-only, auto-generated field that is only returned in GET
	// requests.
	SubaccountId int64 `json:"subaccountId,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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// TargetableRemarketingListsListResponse: Targetable remarketing list
// response
type TargetableRemarketingListsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#targetableRemarketingListsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TargetableRemarketingLists: Targetable remarketing list collection.
	TargetableRemarketingLists []*TargetableRemarketingList `json:"targetableRemarketingLists,omitempty"`

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

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

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

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

// TargetingTemplate: Contains properties of a targeting template. A
// targeting template encapsulates targeting information which can be
// reused across multiple ads.
type TargetingTemplate struct {
	// AccountId: Account ID of this targeting template. This field, if left
	// unset, will be auto-generated on insert and is read-only after
	// insert.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this targeting template. This is a
	// required field on insert and is read-only after insert.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// DayPartTargeting: Time and day targeting criteria.
	DayPartTargeting *DayPartTargeting `json:"dayPartTargeting,omitempty"`

	// GeoTargeting: Geographical targeting criteria.
	GeoTargeting *GeoTargeting `json:"geoTargeting,omitempty"`

	// Id: ID of this targeting template. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// KeyValueTargetingExpression: Key-value targeting criteria.
	KeyValueTargetingExpression *KeyValueTargetingExpression `json:"keyValueTargetingExpression,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#targetingTemplate".
	Kind string `json:"kind,omitempty"`

	// LanguageTargeting: Language targeting criteria.
	LanguageTargeting *LanguageTargeting `json:"languageTargeting,omitempty"`

	// ListTargetingExpression: Remarketing list targeting criteria.
	ListTargetingExpression *ListTargetingExpression `json:"listTargetingExpression,omitempty"`

	// Name: Name of this targeting template. This field is required. It
	// must be less than 256 characters long and unique within an
	// advertiser.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this targeting template. This field,
	// if left unset, will be auto-generated on insert and is read-only
	// after insert.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TechnologyTargeting: Technology platform targeting criteria.
	TechnologyTargeting *TechnologyTargeting `json:"technologyTargeting,omitempty"`

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

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

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

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

// TargetingTemplatesListResponse: Targeting Template List Response
type TargetingTemplatesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#targetingTemplatesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TargetingTemplates: Targeting template collection.
	TargetingTemplates []*TargetingTemplate `json:"targetingTemplates,omitempty"`

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

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

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

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

// TechnologyTargeting: Technology Targeting.
type TechnologyTargeting struct {
	// Browsers: Browsers that this ad targets. For each browser either set
	// browserVersionId or dartId along with the version numbers. If both
	// are specified, only browserVersionId will be used. The other fields
	// are populated automatically when the ad is inserted or updated.
	Browsers []*Browser `json:"browsers,omitempty"`

	// ConnectionTypes: Connection types that this ad targets. For each
	// connection type only id is required. The other fields are populated
	// automatically when the ad is inserted or updated.
	ConnectionTypes []*ConnectionType `json:"connectionTypes,omitempty"`

	// MobileCarriers: Mobile carriers that this ad targets. For each mobile
	// carrier only id is required, and the other fields are populated
	// automatically when the ad is inserted or updated. If targeting a
	// mobile carrier, do not set targeting for any zip codes.
	MobileCarriers []*MobileCarrier `json:"mobileCarriers,omitempty"`

	// OperatingSystemVersions: Operating system versions that this ad
	// targets. To target all versions, use operatingSystems. For each
	// operating system version, only id is required. The other fields are
	// populated automatically when the ad is inserted or updated. If
	// targeting an operating system version, do not set targeting for the
	// corresponding operating system in operatingSystems.
	OperatingSystemVersions []*OperatingSystemVersion `json:"operatingSystemVersions,omitempty"`

	// OperatingSystems: Operating systems that this ad targets. To target
	// specific versions, use operatingSystemVersions. For each operating
	// system only dartId is required. The other fields are populated
	// automatically when the ad is inserted or updated. If targeting an
	// operating system, do not set targeting for operating system versions
	// for the same operating system.
	OperatingSystems []*OperatingSystem `json:"operatingSystems,omitempty"`

	// PlatformTypes: Platform types that this ad targets. For example,
	// desktop, mobile, or tablet. For each platform type, only id is
	// required, and the other fields are populated automatically when the
	// ad is inserted or updated.
	PlatformTypes []*PlatformType `json:"platformTypes,omitempty"`

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

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

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

// ThirdPartyAuthenticationToken: Third Party Authentication Token
type ThirdPartyAuthenticationToken struct {
	// Name: Name of the third-party authentication token.
	Name string `json:"name,omitempty"`

	// Value: Value of the third-party authentication token. This is a
	// read-only, auto-generated field.
	Value string `json:"value,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 *ThirdPartyAuthenticationToken) MarshalJSON() ([]byte, error) {
	type NoMethod ThirdPartyAuthenticationToken
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ThirdPartyTrackingUrl: Third-party Tracking URL.
type ThirdPartyTrackingUrl struct {
	// ThirdPartyUrlType: Third-party URL type for in-stream video and
	// in-stream audio creatives.
	//
	// Possible values:
	//   "IMPRESSION"
	//   "CLICK_TRACKING"
	//   "VIDEO_START"
	//   "VIDEO_FIRST_QUARTILE"
	//   "VIDEO_MIDPOINT"
	//   "VIDEO_THIRD_QUARTILE"
	//   "VIDEO_COMPLETE"
	//   "VIDEO_MUTE"
	//   "VIDEO_PAUSE"
	//   "VIDEO_REWIND"
	//   "VIDEO_FULLSCREEN"
	//   "VIDEO_STOP"
	//   "VIDEO_CUSTOM"
	//   "SURVEY"
	//   "RICH_MEDIA_IMPRESSION"
	//   "RICH_MEDIA_RM_IMPRESSION"
	//   "RICH_MEDIA_BACKUP_IMPRESSION"
	//   "VIDEO_SKIP"
	//   "VIDEO_PROGRESS"
	ThirdPartyUrlType string `json:"thirdPartyUrlType,omitempty"`

	// Url: URL for the specified third-party URL type.
	Url string `json:"url,omitempty"`

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

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

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

// TranscodeSetting: Transcode Settings
type TranscodeSetting struct {
	// EnabledVideoFormats: Whitelist of video formats to be served to this
	// placement. Set this list to null or empty to serve all video formats.
	EnabledVideoFormats []int64 `json:"enabledVideoFormats,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#transcodeSetting".
	Kind string `json:"kind,omitempty"`

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

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

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

// UniversalAdId: A Universal Ad ID as per the VAST 4.0 spec. Applicable
// to the following creative types: INSTREAM_AUDIO, INSTREAM_VIDEO and
// VPAID.
type UniversalAdId struct {
	// Registry: Registry used for the Ad ID value.
	//
	// Possible values:
	//   "OTHER"
	//   "AD_ID_OFFICIAL"
	//   "CLEARCAST"
	//   "DCM"
	Registry string `json:"registry,omitempty"`

	// Value: ID value for this creative. Only alphanumeric characters and
	// the following symbols are valid: "_/\-". Maximum length is 64
	// characters. Read only when registry is DCM.
	Value string `json:"value,omitempty"`

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

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

// UserDefinedVariableConfiguration: User Defined Variable
// configuration.
type UserDefinedVariableConfiguration struct {
	// DataType: Data type for the variable. This is a required field.
	//
	// Possible values:
	//   "STRING"
	//   "NUMBER"
	DataType string `json:"dataType,omitempty"`

	// ReportName: User-friendly name for the variable which will appear in
	// reports. This is a required field, must be less than 64 characters
	// long, and cannot contain the following characters: ""<>".
	ReportName string `json:"reportName,omitempty"`

	// VariableType: Variable name in the tag. This is a required field.
	//
	// Possible values:
	//   "U1"
	//   "U2"
	//   "U3"
	//   "U4"
	//   "U5"
	//   "U6"
	//   "U7"
	//   "U8"
	//   "U9"
	//   "U10"
	//   "U11"
	//   "U12"
	//   "U13"
	//   "U14"
	//   "U15"
	//   "U16"
	//   "U17"
	//   "U18"
	//   "U19"
	//   "U20"
	//   "U21"
	//   "U22"
	//   "U23"
	//   "U24"
	//   "U25"
	//   "U26"
	//   "U27"
	//   "U28"
	//   "U29"
	//   "U30"
	//   "U31"
	//   "U32"
	//   "U33"
	//   "U34"
	//   "U35"
	//   "U36"
	//   "U37"
	//   "U38"
	//   "U39"
	//   "U40"
	//   "U41"
	//   "U42"
	//   "U43"
	//   "U44"
	//   "U45"
	//   "U46"
	//   "U47"
	//   "U48"
	//   "U49"
	//   "U50"
	//   "U51"
	//   "U52"
	//   "U53"
	//   "U54"
	//   "U55"
	//   "U56"
	//   "U57"
	//   "U58"
	//   "U59"
	//   "U60"
	//   "U61"
	//   "U62"
	//   "U63"
	//   "U64"
	//   "U65"
	//   "U66"
	//   "U67"
	//   "U68"
	//   "U69"
	//   "U70"
	//   "U71"
	//   "U72"
	//   "U73"
	//   "U74"
	//   "U75"
	//   "U76"
	//   "U77"
	//   "U78"
	//   "U79"
	//   "U80"
	//   "U81"
	//   "U82"
	//   "U83"
	//   "U84"
	//   "U85"
	//   "U86"
	//   "U87"
	//   "U88"
	//   "U89"
	//   "U90"
	//   "U91"
	//   "U92"
	//   "U93"
	//   "U94"
	//   "U95"
	//   "U96"
	//   "U97"
	//   "U98"
	//   "U99"
	//   "U100"
	VariableType string `json:"variableType,omitempty"`

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

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

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

// UserProfile: A UserProfile resource lets you list all DFA user
// profiles that are associated with a Google user account. The
// profile_id needs to be specified in other API requests.
type UserProfile struct {
	// AccountId: The account ID to which this profile belongs.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AccountName: The account name this profile belongs to.
	AccountName string `json:"accountName,omitempty"`

	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userProfile".
	Kind string `json:"kind,omitempty"`

	// ProfileId: The unique ID of the user profile.
	ProfileId int64 `json:"profileId,omitempty,string"`

	// SubAccountId: The sub account ID this profile belongs to if
	// applicable.
	SubAccountId int64 `json:"subAccountId,omitempty,string"`

	// SubAccountName: The sub account name this profile belongs to if
	// applicable.
	SubAccountName string `json:"subAccountName,omitempty"`

	// UserName: The user name.
	UserName string `json:"userName,omitempty"`

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

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

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

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

// UserProfileList: Represents the list of user profiles.
type UserProfileList struct {
	// Etag: Etag of this resource.
	Etag string `json:"etag,omitempty"`

	// Items: The user profiles returned in this response.
	Items []*UserProfile `json:"items,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userProfileList".
	Kind string `json:"kind,omitempty"`

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

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

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

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

// UserRole: Contains properties of auser role, which is used to manage
// user access.
type UserRole struct {
	// AccountId: Account ID of this user role. This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// DefaultUserRole: Whether this is a default user role. Default user
	// roles are created by the system for the account/subaccount and cannot
	// be modified or deleted. Each default user role comes with a basic set
	// of preassigned permissions.
	DefaultUserRole bool `json:"defaultUserRole,omitempty"`

	// Id: ID of this user role. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRole".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this user role. This is a required field. Must be less
	// than 256 characters long. If this user role is under a subaccount,
	// the name must be unique among sites of the same subaccount.
	// Otherwise, this user role is a top-level user role, and the name must
	// be unique among top-level user roles of the same account.
	Name string `json:"name,omitempty"`

	// ParentUserRoleId: ID of the user role that this user role is based on
	// or copied from. This is a required field.
	ParentUserRoleId int64 `json:"parentUserRoleId,omitempty,string"`

	// Permissions: List of permissions associated with this user role.
	Permissions []*UserRolePermission `json:"permissions,omitempty"`

	// SubaccountId: Subaccount ID of this user role. This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,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. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// UserRolePermission: Contains properties of a user role permission.
type UserRolePermission struct {
	// Availability: Levels of availability for a user role permission.
	//
	// Possible values:
	//   "NOT_AVAILABLE_BY_DEFAULT"
	//   "ACCOUNT_BY_DEFAULT"
	//   "SUBACCOUNT_AND_ACCOUNT_BY_DEFAULT"
	//   "ACCOUNT_ALWAYS"
	//   "SUBACCOUNT_AND_ACCOUNT_ALWAYS"
	Availability string `json:"availability,omitempty"`

	// Id: ID of this user role permission.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolePermission".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this user role permission.
	Name string `json:"name,omitempty"`

	// PermissionGroupId: ID of the permission group that this user role
	// permission belongs to.
	PermissionGroupId int64 `json:"permissionGroupId,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. "Availability") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// UserRolePermissionGroup: Represents a grouping of related user role
// permissions.
type UserRolePermissionGroup struct {
	// Id: ID of this user role permission.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolePermissionGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this user role permission 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. "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 *UserRolePermissionGroup) MarshalJSON() ([]byte, error) {
	type NoMethod UserRolePermissionGroup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UserRolePermissionGroupsListResponse: User Role Permission Group List
// Response
type UserRolePermissionGroupsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolePermissionGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// UserRolePermissionGroups: User role permission group collection.
	UserRolePermissionGroups []*UserRolePermissionGroup `json:"userRolePermissionGroups,omitempty"`

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

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

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

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

// UserRolePermissionsListResponse: User Role Permission List Response
type UserRolePermissionsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolePermissionsListResponse".
	Kind string `json:"kind,omitempty"`

	// UserRolePermissions: User role permission collection.
	UserRolePermissions []*UserRolePermission `json:"userRolePermissions,omitempty"`

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

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

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

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

// UserRolesListResponse: User Role List Response
type UserRolesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// UserRoles: User role collection.
	UserRoles []*UserRole `json:"userRoles,omitempty"`

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

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

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

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

// VideoFormat: Contains information about supported video formats.
type VideoFormat struct {
	// FileType: File type of the video format.
	//
	// Possible values:
	//   "FLV"
	//   "THREEGPP"
	//   "MP4"
	//   "WEBM"
	//   "M3U8"
	FileType string `json:"fileType,omitempty"`

	// Id: ID of the video format.
	Id int64 `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#videoFormat".
	Kind string `json:"kind,omitempty"`

	// Resolution: The resolution of this video format.
	Resolution *Size `json:"resolution,omitempty"`

	// TargetBitRate: The target bit rate of this video format.
	TargetBitRate int64 `json:"targetBitRate,omitempty"`

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

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

// VideoFormatsListResponse: Video Format List Response
type VideoFormatsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#videoFormatsListResponse".
	Kind string `json:"kind,omitempty"`

	// VideoFormats: Video format collection.
	VideoFormats []*VideoFormat `json:"videoFormats,omitempty"`

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

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

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

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

// VideoOffset: Video Offset
type VideoOffset struct {
	// OffsetPercentage: Duration, as a percentage of video duration. Do not
	// set when offsetSeconds is set. Acceptable values are 0 to 100,
	// inclusive.
	OffsetPercentage int64 `json:"offsetPercentage,omitempty"`

	// OffsetSeconds: Duration, in seconds. Do not set when offsetPercentage
	// is set. Acceptable values are 0 to 86399, inclusive.
	OffsetSeconds int64 `json:"offsetSeconds,omitempty"`

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

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

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

// VideoSettings: Video Settings
type VideoSettings struct {
	// CompanionSettings: Settings for the companion creatives of video
	// creatives served to this placement.
	CompanionSettings *CompanionSetting `json:"companionSettings,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#videoSettings".
	Kind string `json:"kind,omitempty"`

	// ObaEnabled: Whether OBA icons are enabled for this placement.
	ObaEnabled bool `json:"obaEnabled,omitempty"`

	// ObaSettings: Settings for the OBA icon of video creatives served to
	// this placement. If this object is provided, the creative-level OBA
	// settings will be overridden.
	ObaSettings *ObaIcon `json:"obaSettings,omitempty"`

	// Orientation: Orientation of a video placement. If this value is set,
	// placement will return assets matching the specified orientation.
	//
	// Possible values:
	//   "ANY"
	//   "LANDSCAPE"
	//   "PORTRAIT"
	Orientation string `json:"orientation,omitempty"`

	// SkippableSettings: Settings for the skippability of video creatives
	// served to this placement. If this object is provided, the
	// creative-level skippable settings will be overridden.
	SkippableSettings *SkippableSetting `json:"skippableSettings,omitempty"`

	// TranscodeSettings: Settings for the transcodes of video creatives
	// served to this placement. If this object is provided, the
	// creative-level transcode settings will be overridden.
	TranscodeSettings *TranscodeSetting `json:"transcodeSettings,omitempty"`

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

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

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

// method id "dfareporting.accountActiveAdSummaries.get":

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

// Get: Gets the account's active ad summary by account ID.
func (r *AccountActiveAdSummariesService) Get(profileId int64, summaryAccountId int64) *AccountActiveAdSummariesGetCall {
	c := &AccountActiveAdSummariesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.summaryAccountId = summaryAccountId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountActiveAdSummariesGetCall) Fields(s ...googleapi.Field) *AccountActiveAdSummariesGetCall {
	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 *AccountActiveAdSummariesGetCall) IfNoneMatch(entityTag string) *AccountActiveAdSummariesGetCall {
	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 *AccountActiveAdSummariesGetCall) Context(ctx context.Context) *AccountActiveAdSummariesGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountActiveAdSummaries.get" call.
// Exactly one of *AccountActiveAdSummary or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountActiveAdSummary.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountActiveAdSummariesGetCall) Do(opts ...googleapi.CallOption) (*AccountActiveAdSummary, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountActiveAdSummary{
		ServerResponse: googleapi.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 account's active ad summary by account ID.",
	//   "flatPath": "userprofiles/{profileId}/accountActiveAdSummaries/{summaryAccountId}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountActiveAdSummaries.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "summaryAccountId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "summaryAccountId": {
	//       "description": "Account ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountActiveAdSummaries/{summaryAccountId}",
	//   "response": {
	//     "$ref": "AccountActiveAdSummary"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountPermissionGroups.get":

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

// Get: Gets one account permission group by ID.
func (r *AccountPermissionGroupsService) Get(profileId int64, id int64) *AccountPermissionGroupsGetCall {
	c := &AccountPermissionGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountPermissionGroupsGetCall) Fields(s ...googleapi.Field) *AccountPermissionGroupsGetCall {
	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 *AccountPermissionGroupsGetCall) IfNoneMatch(entityTag string) *AccountPermissionGroupsGetCall {
	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 *AccountPermissionGroupsGetCall) Context(ctx context.Context) *AccountPermissionGroupsGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountPermissionGroups.get" call.
// Exactly one of *AccountPermissionGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountPermissionGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountPermissionGroupsGetCall) Do(opts ...googleapi.CallOption) (*AccountPermissionGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountPermissionGroup{
		ServerResponse: googleapi.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 one account permission group by ID.",
	//   "flatPath": "userprofiles/{profileId}/accountPermissionGroups/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountPermissionGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Account permission group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountPermissionGroups/{id}",
	//   "response": {
	//     "$ref": "AccountPermissionGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountPermissionGroups.list":

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

// List: Retrieves the list of account permission groups.
func (r *AccountPermissionGroupsService) List(profileId int64) *AccountPermissionGroupsListCall {
	c := &AccountPermissionGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountPermissionGroupsListCall) Fields(s ...googleapi.Field) *AccountPermissionGroupsListCall {
	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 *AccountPermissionGroupsListCall) IfNoneMatch(entityTag string) *AccountPermissionGroupsListCall {
	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 *AccountPermissionGroupsListCall) Context(ctx context.Context) *AccountPermissionGroupsListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountPermissionGroups.list" call.
// Exactly one of *AccountPermissionGroupsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AccountPermissionGroupsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AccountPermissionGroupsListCall) Do(opts ...googleapi.CallOption) (*AccountPermissionGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountPermissionGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of account permission groups.",
	//   "flatPath": "userprofiles/{profileId}/accountPermissionGroups",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountPermissionGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountPermissionGroups",
	//   "response": {
	//     "$ref": "AccountPermissionGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountPermissions.get":

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

// Get: Gets one account permission by ID.
func (r *AccountPermissionsService) Get(profileId int64, id int64) *AccountPermissionsGetCall {
	c := &AccountPermissionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountPermissionsGetCall) Fields(s ...googleapi.Field) *AccountPermissionsGetCall {
	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 *AccountPermissionsGetCall) IfNoneMatch(entityTag string) *AccountPermissionsGetCall {
	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 *AccountPermissionsGetCall) Context(ctx context.Context) *AccountPermissionsGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountPermissions.get" call.
// Exactly one of *AccountPermission or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountPermission.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountPermissionsGetCall) Do(opts ...googleapi.CallOption) (*AccountPermission, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountPermission{
		ServerResponse: googleapi.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 one account permission by ID.",
	//   "flatPath": "userprofiles/{profileId}/accountPermissions/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountPermissions.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Account permission ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountPermissions/{id}",
	//   "response": {
	//     "$ref": "AccountPermission"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountPermissions.list":

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

// List: Retrieves the list of account permissions.
func (r *AccountPermissionsService) List(profileId int64) *AccountPermissionsListCall {
	c := &AccountPermissionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountPermissionsListCall) Fields(s ...googleapi.Field) *AccountPermissionsListCall {
	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 *AccountPermissionsListCall) IfNoneMatch(entityTag string) *AccountPermissionsListCall {
	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 *AccountPermissionsListCall) Context(ctx context.Context) *AccountPermissionsListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountPermissions.list" call.
// Exactly one of *AccountPermissionsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AccountPermissionsListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountPermissionsListCall) Do(opts ...googleapi.CallOption) (*AccountPermissionsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountPermissionsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of account permissions.",
	//   "flatPath": "userprofiles/{profileId}/accountPermissions",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountPermissions.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountPermissions",
	//   "response": {
	//     "$ref": "AccountPermissionsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountUserProfiles.get":

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

// Get: Gets one account user profile by ID.
func (r *AccountUserProfilesService) Get(profileId int64, id int64) *AccountUserProfilesGetCall {
	c := &AccountUserProfilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesGetCall) Fields(s ...googleapi.Field) *AccountUserProfilesGetCall {
	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 *AccountUserProfilesGetCall) IfNoneMatch(entityTag string) *AccountUserProfilesGetCall {
	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 *AccountUserProfilesGetCall) Context(ctx context.Context) *AccountUserProfilesGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountUserProfiles.get" call.
// Exactly one of *AccountUserProfile or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountUserProfile.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesGetCall) Do(opts ...googleapi.CallOption) (*AccountUserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfile{
		ServerResponse: googleapi.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 one account user profile by ID.",
	//   "flatPath": "userprofiles/{profileId}/accountUserProfiles/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountUserProfiles.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles/{id}",
	//   "response": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountUserProfiles.insert":

type AccountUserProfilesInsertCall struct {
	s                  *Service
	profileId          int64
	accountuserprofile *AccountUserProfile
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Insert: Inserts a new account user profile.
func (r *AccountUserProfilesService) Insert(profileId int64, accountuserprofile *AccountUserProfile) *AccountUserProfilesInsertCall {
	c := &AccountUserProfilesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.accountuserprofile = accountuserprofile
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesInsertCall) Fields(s ...googleapi.Field) *AccountUserProfilesInsertCall {
	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 *AccountUserProfilesInsertCall) Context(ctx context.Context) *AccountUserProfilesInsertCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountUserProfiles.insert" call.
// Exactly one of *AccountUserProfile or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountUserProfile.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesInsertCall) Do(opts ...googleapi.CallOption) (*AccountUserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfile{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new account user profile.",
	//   "flatPath": "userprofiles/{profileId}/accountUserProfiles",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.accountUserProfiles.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles",
	//   "request": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "response": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountUserProfiles.list":

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

// List: Retrieves a list of account user profiles, possibly filtered.
// This method supports paging.
func (r *AccountUserProfilesService) List(profileId int64) *AccountUserProfilesListCall {
	c := &AccountUserProfilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Active sets the optional parameter "active": Select only active user
// profiles.
func (c *AccountUserProfilesListCall) Active(active bool) *AccountUserProfilesListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// Ids sets the optional parameter "ids": Select only user profiles with
// these IDs.
func (c *AccountUserProfilesListCall) Ids(ids ...int64) *AccountUserProfilesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AccountUserProfilesListCall) MaxResults(maxResults int64) *AccountUserProfilesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AccountUserProfilesListCall) PageToken(pageToken string) *AccountUserProfilesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name, ID or email. Wildcards (*) are
// allowed. For example, "user profile*2015" will return objects with
// names like "user profile June 2015", "user profile April 2015", or
// simply "user profile 2015". Most of the searches also add wildcards
// implicitly at the start and the end of the search string. For
// example, a search string of "user profile" will match objects with
// name "my user profile", "user profile 2015", or simply "user
// profile".
func (c *AccountUserProfilesListCall) SearchString(searchString string) *AccountUserProfilesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *AccountUserProfilesListCall) SortField(sortField string) *AccountUserProfilesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *AccountUserProfilesListCall) SortOrder(sortOrder string) *AccountUserProfilesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// user profiles with the specified subaccount ID.
func (c *AccountUserProfilesListCall) SubaccountId(subaccountId int64) *AccountUserProfilesListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// UserRoleId sets the optional parameter "userRoleId": Select only user
// profiles with the specified user role ID.
func (c *AccountUserProfilesListCall) UserRoleId(userRoleId int64) *AccountUserProfilesListCall {
	c.urlParams_.Set("userRoleId", fmt.Sprint(userRoleId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesListCall) Fields(s ...googleapi.Field) *AccountUserProfilesListCall {
	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 *AccountUserProfilesListCall) IfNoneMatch(entityTag string) *AccountUserProfilesListCall {
	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 *AccountUserProfilesListCall) Context(ctx context.Context) *AccountUserProfilesListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountUserProfiles.list" call.
// Exactly one of *AccountUserProfilesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AccountUserProfilesListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesListCall) Do(opts ...googleapi.CallOption) (*AccountUserProfilesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfilesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of account user profiles, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/accountUserProfiles",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountUserProfiles.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active user profiles.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only user profiles with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name, ID or email. Wildcards (*) are allowed. For example, \"user profile*2015\" will return objects with names like \"user profile June 2015\", \"user profile April 2015\", or simply \"user profile 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"user profile\" will match objects with name \"my user profile\", \"user profile 2015\", or simply \"user profile\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only user profiles with the specified subaccount ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userRoleId": {
	//       "description": "Select only user profiles with the specified user role ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles",
	//   "response": {
	//     "$ref": "AccountUserProfilesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *AccountUserProfilesListCall) Pages(ctx context.Context, f func(*AccountUserProfilesListResponse) 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 "dfareporting.accountUserProfiles.patch":

type AccountUserProfilesPatchCall struct {
	s                  *Service
	profileId          int64
	accountuserprofile *AccountUserProfile
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Patch: Updates an existing account user profile. This method supports
// patch semantics.
func (r *AccountUserProfilesService) Patch(profileId int64, accountuserprofile *AccountUserProfile) *AccountUserProfilesPatchCall {
	c := &AccountUserProfilesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.accountuserprofile = accountuserprofile
	return c
}

// Id sets the optional parameter "id": AccountUserProfile ID.
func (c *AccountUserProfilesPatchCall) Id(id int64) *AccountUserProfilesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesPatchCall) Fields(s ...googleapi.Field) *AccountUserProfilesPatchCall {
	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 *AccountUserProfilesPatchCall) Context(ctx context.Context) *AccountUserProfilesPatchCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accountUserProfiles.patch" call.
// Exactly one of *AccountUserProfile or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountUserProfile.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesPatchCall) Do(opts ...googleapi.CallOption) (*AccountUserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfile{
		ServerResponse: googleapi.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 account user profile. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/accountUserProfiles",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.accountUserProfiles.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "AccountUserProfile ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles",
	//   "request": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "response": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountUserProfiles.update":

type AccountUserProfilesUpdateCall struct {
	s                  *Service
	profileId          int64
	accountuserprofile *AccountUserProfile
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Update: Updates an existing account user profile.
func (r *AccountUserProfilesService) Update(profileId int64, accountuserprofile *AccountUserProfile) *AccountUserProfilesUpdateCall {
	c := &AccountUserProfilesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.accountuserprofile = accountuserprofile
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesUpdateCall) Fields(s ...googleapi.Field) *AccountUserProfilesUpdateCall {
	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 *AccountUserProfilesUpdateCall) Context(ctx context.Context) *AccountUserProfilesUpdateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *AccountUserProfilesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.accountuserprofile)
	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, "userprofiles/{profileId}/accountUserProfiles")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountUserProfiles.update" call.
// Exactly one of *AccountUserProfile or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountUserProfile.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesUpdateCall) Do(opts ...googleapi.CallOption) (*AccountUserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfile{
		ServerResponse: googleapi.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 account user profile.",
	//   "flatPath": "userprofiles/{profileId}/accountUserProfiles",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.accountUserProfiles.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles",
	//   "request": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "response": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accounts.get":

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

// Get: Gets one account by ID.
func (r *AccountsService) Get(profileId int64, id int64) *AccountsGetCall {
	c := &AccountsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsGetCall) Fields(s ...googleapi.Field) *AccountsGetCall {
	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 *AccountsGetCall) IfNoneMatch(entityTag string) *AccountsGetCall {
	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 *AccountsGetCall) Context(ctx context.Context) *AccountsGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accounts.get" call.
// Exactly one of *Account or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Account.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsGetCall) Do(opts ...googleapi.CallOption) (*Account, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Account{
		ServerResponse: googleapi.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 one account by ID.",
	//   "flatPath": "userprofiles/{profileId}/accounts/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accounts.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Account ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accounts/{id}",
	//   "response": {
	//     "$ref": "Account"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accounts.list":

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

// List: Retrieves the list of accounts, possibly filtered. This method
// supports paging.
func (r *AccountsService) List(profileId int64) *AccountsListCall {
	c := &AccountsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Active sets the optional parameter "active": Select only active
// accounts. Don't set this field to select both active and non-active
// accounts.
func (c *AccountsListCall) Active(active bool) *AccountsListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// Ids sets the optional parameter "ids": Select only accounts with
// these IDs.
func (c *AccountsListCall) Ids(ids ...int64) *AccountsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AccountsListCall) MaxResults(maxResults int64) *AccountsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AccountsListCall) PageToken(pageToken string) *AccountsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "account*2015" will return objects with names like "account
// June 2015", "account April 2015", or simply "account 2015". Most of
// the searches also add wildcards implicitly at the start and the end
// of the search string. For example, a search string of "account" will
// match objects with name "my account", "account 2015", or simply
// "account".
func (c *AccountsListCall) SearchString(searchString string) *AccountsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *AccountsListCall) SortField(sortField string) *AccountsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *AccountsListCall) SortOrder(sortOrder string) *AccountsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsListCall) Fields(s ...googleapi.Field) *AccountsListCall {
	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 *AccountsListCall) IfNoneMatch(entityTag string) *AccountsListCall {
	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 *AccountsListCall) Context(ctx context.Context) *AccountsListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accounts.list" call.
// Exactly one of *AccountsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountsListCall) Do(opts ...googleapi.CallOption) (*AccountsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of accounts, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/accounts",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accounts.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active accounts. Don't set this field to select both active and non-active accounts.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only accounts with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"account*2015\" will return objects with names like \"account June 2015\", \"account April 2015\", or simply \"account 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"account\" will match objects with name \"my account\", \"account 2015\", or simply \"account\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accounts",
	//   "response": {
	//     "$ref": "AccountsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *AccountsListCall) Pages(ctx context.Context, f func(*AccountsListResponse) 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 "dfareporting.accounts.patch":

type AccountsPatchCall struct {
	s          *Service
	profileId  int64
	account    *Account
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing account. This method supports patch
// semantics.
func (r *AccountsService) Patch(profileId int64, account *Account) *AccountsPatchCall {
	c := &AccountsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.account = account
	return c
}

// Id sets the optional parameter "id": Account ID.
func (c *AccountsPatchCall) Id(id int64) *AccountsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsPatchCall) Fields(s ...googleapi.Field) *AccountsPatchCall {
	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 *AccountsPatchCall) Context(ctx context.Context) *AccountsPatchCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.accounts.patch" call.
// Exactly one of *Account or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Account.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsPatchCall) Do(opts ...googleapi.CallOption) (*Account, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Account{
		ServerResponse: googleapi.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 account. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/accounts",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.accounts.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Account ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accounts",
	//   "request": {
	//     "$ref": "Account"
	//   },
	//   "response": {
	//     "$ref": "Account"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accounts.update":

type AccountsUpdateCall struct {
	s          *Service
	profileId  int64
	account    *Account
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing account.
func (r *AccountsService) Update(profileId int64, account *Account) *AccountsUpdateCall {
	c := &AccountsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.account = account
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsUpdateCall) Fields(s ...googleapi.Field) *AccountsUpdateCall {
	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 *AccountsUpdateCall) Context(ctx context.Context) *AccountsUpdateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *AccountsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.account)
	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, "userprofiles/{profileId}/accounts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accounts.update" call.
// Exactly one of *Account or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Account.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsUpdateCall) Do(opts ...googleapi.CallOption) (*Account, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Account{
		ServerResponse: googleapi.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 account.",
	//   "flatPath": "userprofiles/{profileId}/accounts",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.accounts.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accounts",
	//   "request": {
	//     "$ref": "Account"
	//   },
	//   "response": {
	//     "$ref": "Account"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.ads.get":

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

// Get: Gets one ad by ID.
func (r *AdsService) Get(profileId int64, id int64) *AdsGetCall {
	c := &AdsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsGetCall) Fields(s ...googleapi.Field) *AdsGetCall {
	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 *AdsGetCall) IfNoneMatch(entityTag string) *AdsGetCall {
	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 *AdsGetCall) Context(ctx context.Context) *AdsGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.ads.get" call.
// Exactly one of *Ad or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either *Ad.ServerResponse.Header
// or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdsGetCall) Do(opts ...googleapi.CallOption) (*Ad, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Ad{
		ServerResponse: googleapi.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 one ad by ID.",
	//   "flatPath": "userprofiles/{profileId}/ads/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.ads.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Ad ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads/{id}",
	//   "response": {
	//     "$ref": "Ad"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.ads.insert":

type AdsInsertCall struct {
	s          *Service
	profileId  int64
	ad         *Ad
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new ad.
func (r *AdsService) Insert(profileId int64, ad *Ad) *AdsInsertCall {
	c := &AdsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.ad = ad
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsInsertCall) Fields(s ...googleapi.Field) *AdsInsertCall {
	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 *AdsInsertCall) Context(ctx context.Context) *AdsInsertCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.ads.insert" call.
// Exactly one of *Ad or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either *Ad.ServerResponse.Header
// or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdsInsertCall) Do(opts ...googleapi.CallOption) (*Ad, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Ad{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new ad.",
	//   "flatPath": "userprofiles/{profileId}/ads",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.ads.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads",
	//   "request": {
	//     "$ref": "Ad"
	//   },
	//   "response": {
	//     "$ref": "Ad"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.ads.list":

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

// List: Retrieves a list of ads, possibly filtered. This method
// supports paging.
func (r *AdsService) List(profileId int64) *AdsListCall {
	c := &AdsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Active sets the optional parameter "active": Select only active ads.
func (c *AdsListCall) Active(active bool) *AdsListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// ads with this advertiser ID.
func (c *AdsListCall) AdvertiserId(advertiserId int64) *AdsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// ads.
func (c *AdsListCall) Archived(archived bool) *AdsListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// AudienceSegmentIds sets the optional parameter "audienceSegmentIds":
// Select only ads with these audience segment IDs.
func (c *AdsListCall) AudienceSegmentIds(audienceSegmentIds ...int64) *AdsListCall {
	var audienceSegmentIds_ []string
	for _, v := range audienceSegmentIds {
		audienceSegmentIds_ = append(audienceSegmentIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("audienceSegmentIds", audienceSegmentIds_)
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// ads with these campaign IDs.
func (c *AdsListCall) CampaignIds(campaignIds ...int64) *AdsListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// Compatibility sets the optional parameter "compatibility": Select
// default ads with the specified compatibility. Applicable when type is
// AD_SERVING_DEFAULT_AD. DISPLAY and DISPLAY_INTERSTITIAL refer to
// rendering either on desktop or on mobile devices for regular or
// interstitial ads, respectively. APP and APP_INTERSTITIAL are for
// rendering in mobile apps. IN_STREAM_VIDEO refers to rendering an
// in-stream video ads developed with the VAST standard.
//
// Possible values:
//   "DISPLAY"
//   "DISPLAY_INTERSTITIAL"
//   "APP"
//   "APP_INTERSTITIAL"
//   "IN_STREAM_VIDEO"
//   "IN_STREAM_AUDIO"
func (c *AdsListCall) Compatibility(compatibility string) *AdsListCall {
	c.urlParams_.Set("compatibility", compatibility)
	return c
}

// CreativeIds sets the optional parameter "creativeIds": Select only
// ads with these creative IDs assigned.
func (c *AdsListCall) CreativeIds(creativeIds ...int64) *AdsListCall {
	var creativeIds_ []string
	for _, v := range creativeIds {
		creativeIds_ = append(creativeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("creativeIds", creativeIds_)
	return c
}

// CreativeOptimizationConfigurationIds sets the optional parameter
// "creativeOptimizationConfigurationIds": Select only ads with these
// creative optimization configuration IDs.
func (c *AdsListCall) CreativeOptimizationConfigurationIds(creativeOptimizationConfigurationIds ...int64) *AdsListCall {
	var creativeOptimizationConfigurationIds_ []string
	for _, v := range creativeOptimizationConfigurationIds {
		creativeOptimizationConfigurationIds_ = append(creativeOptimizationConfigurationIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("creativeOptimizationConfigurationIds", creativeOptimizationConfigurationIds_)
	return c
}

// DynamicClickTracker sets the optional parameter
// "dynamicClickTracker": Select only dynamic click trackers. Applicable
// when type is AD_SERVING_CLICK_TRACKER. If true, select dynamic click
// trackers. If false, select static click trackers. Leave unset to
// select both.
func (c *AdsListCall) DynamicClickTracker(dynamicClickTracker bool) *AdsListCall {
	c.urlParams_.Set("dynamicClickTracker", fmt.Sprint(dynamicClickTracker))
	return c
}

// Ids sets the optional parameter "ids": Select only ads with these
// IDs.
func (c *AdsListCall) Ids(ids ...int64) *AdsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// LandingPageIds sets the optional parameter "landingPageIds": Select
// only ads with these landing page IDs.
func (c *AdsListCall) LandingPageIds(landingPageIds ...int64) *AdsListCall {
	var landingPageIds_ []string
	for _, v := range landingPageIds {
		landingPageIds_ = append(landingPageIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("landingPageIds", landingPageIds_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AdsListCall) MaxResults(maxResults int64) *AdsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OverriddenEventTagId sets the optional parameter
// "overriddenEventTagId": Select only ads with this event tag override
// ID.
func (c *AdsListCall) OverriddenEventTagId(overriddenEventTagId int64) *AdsListCall {
	c.urlParams_.Set("overriddenEventTagId", fmt.Sprint(overriddenEventTagId))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AdsListCall) PageToken(pageToken string) *AdsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PlacementIds sets the optional parameter "placementIds": Select only
// ads with these placement IDs assigned.
func (c *AdsListCall) PlacementIds(placementIds ...int64) *AdsListCall {
	var placementIds_ []string
	for _, v := range placementIds {
		placementIds_ = append(placementIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("placementIds", placementIds_)
	return c
}

// RemarketingListIds sets the optional parameter "remarketingListIds":
// Select only ads whose list targeting expression use these remarketing
// list IDs.
func (c *AdsListCall) RemarketingListIds(remarketingListIds ...int64) *AdsListCall {
	var remarketingListIds_ []string
	for _, v := range remarketingListIds {
		remarketingListIds_ = append(remarketingListIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("remarketingListIds", remarketingListIds_)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "ad*2015" will return objects with names like "ad June
// 2015", "ad April 2015", or simply "ad 2015". Most of the searches
// also add wildcards implicitly at the start and the end of the search
// string. For example, a search string of "ad" will match objects with
// name "my ad", "ad 2015", or simply "ad".
func (c *AdsListCall) SearchString(searchString string) *AdsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SizeIds sets the optional parameter "sizeIds": Select only ads with
// these size IDs.
func (c *AdsListCall) SizeIds(sizeIds ...int64) *AdsListCall {
	var sizeIds_ []string
	for _, v := range sizeIds {
		sizeIds_ = append(sizeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("sizeIds", sizeIds_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *AdsListCall) SortField(sortField string) *AdsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *AdsListCall) SortOrder(sortOrder string) *AdsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SslCompliant sets the optional parameter "sslCompliant": Select only
// ads that are SSL-compliant.
func (c *AdsListCall) SslCompliant(sslCompliant bool) *AdsListCall {
	c.urlParams_.Set("sslCompliant", fmt.Sprint(sslCompliant))
	return c
}

// SslRequired sets the optional parameter "sslRequired": Select only
// ads that require SSL.
func (c *AdsListCall) SslRequired(sslRequired bool) *AdsListCall {
	c.urlParams_.Set("sslRequired", fmt.Sprint(sslRequired))
	return c
}

// Type sets the optional parameter "type": Select only ads with these
// types.
//
// Possible values:
//   "AD_SERVING_STANDARD_AD"
//   "AD_SERVING_DEFAULT_AD"
//   "AD_SERVING_CLICK_TRACKER"
//   "AD_SERVING_TRACKING"
func (c *AdsListCall) Type(type_ ...string) *AdsListCall {
	c.urlParams_.SetMulti("type", append([]string{}, type_...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsListCall) Fields(s ...googleapi.Field) *AdsListCall {
	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 *AdsListCall) IfNoneMatch(entityTag string) *AdsListCall {
	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 *AdsListCall) Context(ctx context.Context) *AdsListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.ads.list" call.
// Exactly one of *AdsListResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdsListResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdsListCall) Do(opts ...googleapi.CallOption) (*AdsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of ads, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/ads",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.ads.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active ads.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "advertiserId": {
	//       "description": "Select only ads with this advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived ads.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "audienceSegmentIds": {
	//       "description": "Select only ads with these audience segment IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "campaignIds": {
	//       "description": "Select only ads with these campaign IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "compatibility": {
	//       "description": "Select default ads with the specified compatibility. Applicable when type is AD_SERVING_DEFAULT_AD. DISPLAY and DISPLAY_INTERSTITIAL refer to rendering either on desktop or on mobile devices for regular or interstitial ads, respectively. APP and APP_INTERSTITIAL are for rendering in mobile apps. IN_STREAM_VIDEO refers to rendering an in-stream video ads developed with the VAST standard.",
	//       "enum": [
	//         "DISPLAY",
	//         "DISPLAY_INTERSTITIAL",
	//         "APP",
	//         "APP_INTERSTITIAL",
	//         "IN_STREAM_VIDEO",
	//         "IN_STREAM_AUDIO"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "creativeIds": {
	//       "description": "Select only ads with these creative IDs assigned.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "creativeOptimizationConfigurationIds": {
	//       "description": "Select only ads with these creative optimization configuration IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "dynamicClickTracker": {
	//       "description": "Select only dynamic click trackers. Applicable when type is AD_SERVING_CLICK_TRACKER. If true, select dynamic click trackers. If false, select static click trackers. Leave unset to select both.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only ads with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "landingPageIds": {
	//       "description": "Select only ads with these landing page IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "overriddenEventTagId": {
	//       "description": "Select only ads with this event tag override ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementIds": {
	//       "description": "Select only ads with these placement IDs assigned.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "remarketingListIds": {
	//       "description": "Select only ads whose list targeting expression use these remarketing list IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"ad*2015\" will return objects with names like \"ad June 2015\", \"ad April 2015\", or simply \"ad 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"ad\" will match objects with name \"my ad\", \"ad 2015\", or simply \"ad\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sizeIds": {
	//       "description": "Select only ads with these size IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sslCompliant": {
	//       "description": "Select only ads that are SSL-compliant.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "sslRequired": {
	//       "description": "Select only ads that require SSL.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "type": {
	//       "description": "Select only ads with these types.",
	//       "enum": [
	//         "AD_SERVING_STANDARD_AD",
	//         "AD_SERVING_DEFAULT_AD",
	//         "AD_SERVING_CLICK_TRACKER",
	//         "AD_SERVING_TRACKING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads",
	//   "response": {
	//     "$ref": "AdsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *AdsListCall) Pages(ctx context.Context, f func(*AdsListResponse) 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 "dfareporting.ads.patch":

type AdsPatchCall struct {
	s          *Service
	profileId  int64
	ad         *Ad
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing ad. This method supports patch semantics.
func (r *AdsService) Patch(profileId int64, ad *Ad) *AdsPatchCall {
	c := &AdsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.ad = ad
	return c
}

// Id sets the optional parameter "id": Ad ID.
func (c *AdsPatchCall) Id(id int64) *AdsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsPatchCall) Fields(s ...googleapi.Field) *AdsPatchCall {
	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 *AdsPatchCall) Context(ctx context.Context) *AdsPatchCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.ads.patch" call.
// Exactly one of *Ad or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either *Ad.ServerResponse.Header
// or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdsPatchCall) Do(opts ...googleapi.CallOption) (*Ad, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Ad{
		ServerResponse: googleapi.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 ad. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/ads",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.ads.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Ad ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads",
	//   "request": {
	//     "$ref": "Ad"
	//   },
	//   "response": {
	//     "$ref": "Ad"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.ads.update":

type AdsUpdateCall struct {
	s          *Service
	profileId  int64
	ad         *Ad
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing ad.
func (r *AdsService) Update(profileId int64, ad *Ad) *AdsUpdateCall {
	c := &AdsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.ad = ad
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsUpdateCall) Fields(s ...googleapi.Field) *AdsUpdateCall {
	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 *AdsUpdateCall) Context(ctx context.Context) *AdsUpdateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *AdsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.ad)
	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, "userprofiles/{profileId}/ads")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.ads.update" call.
// Exactly one of *Ad or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either *Ad.ServerResponse.Header
// or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdsUpdateCall) Do(opts ...googleapi.CallOption) (*Ad, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Ad{
		ServerResponse: googleapi.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 ad.",
	//   "flatPath": "userprofiles/{profileId}/ads",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.ads.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads",
	//   "request": {
	//     "$ref": "Ad"
	//   },
	//   "response": {
	//     "$ref": "Ad"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.delete":

type AdvertiserGroupsDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing advertiser group.
func (r *AdvertiserGroupsService) Delete(profileId int64, id int64) *AdvertiserGroupsDeleteCall {
	c := &AdvertiserGroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsDeleteCall) Fields(s ...googleapi.Field) *AdvertiserGroupsDeleteCall {
	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 *AdvertiserGroupsDeleteCall) Context(ctx context.Context) *AdvertiserGroupsDeleteCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserGroups.delete" call.
func (c *AdvertiserGroupsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing advertiser group.",
	//   "flatPath": "userprofiles/{profileId}/advertiserGroups/{id}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.advertiserGroups.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.get":

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

// Get: Gets one advertiser group by ID.
func (r *AdvertiserGroupsService) Get(profileId int64, id int64) *AdvertiserGroupsGetCall {
	c := &AdvertiserGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsGetCall) Fields(s ...googleapi.Field) *AdvertiserGroupsGetCall {
	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 *AdvertiserGroupsGetCall) IfNoneMatch(entityTag string) *AdvertiserGroupsGetCall {
	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 *AdvertiserGroupsGetCall) Context(ctx context.Context) *AdvertiserGroupsGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserGroups.get" call.
// Exactly one of *AdvertiserGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdvertiserGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsGetCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroup{
		ServerResponse: googleapi.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 one advertiser group by ID.",
	//   "flatPath": "userprofiles/{profileId}/advertiserGroups/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertiserGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups/{id}",
	//   "response": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.insert":

type AdvertiserGroupsInsertCall struct {
	s               *Service
	profileId       int64
	advertisergroup *AdvertiserGroup
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Insert: Inserts a new advertiser group.
func (r *AdvertiserGroupsService) Insert(profileId int64, advertisergroup *AdvertiserGroup) *AdvertiserGroupsInsertCall {
	c := &AdvertiserGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertisergroup = advertisergroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsInsertCall) Fields(s ...googleapi.Field) *AdvertiserGroupsInsertCall {
	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 *AdvertiserGroupsInsertCall) Context(ctx context.Context) *AdvertiserGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserGroups.insert" call.
// Exactly one of *AdvertiserGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdvertiserGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsInsertCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new advertiser group.",
	//   "flatPath": "userprofiles/{profileId}/advertiserGroups",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.advertiserGroups.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups",
	//   "request": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "response": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.list":

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

// List: Retrieves a list of advertiser groups, possibly filtered. This
// method supports paging.
func (r *AdvertiserGroupsService) List(profileId int64) *AdvertiserGroupsListCall {
	c := &AdvertiserGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only advertiser groups
// with these IDs.
func (c *AdvertiserGroupsListCall) Ids(ids ...int64) *AdvertiserGroupsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AdvertiserGroupsListCall) MaxResults(maxResults int64) *AdvertiserGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AdvertiserGroupsListCall) PageToken(pageToken string) *AdvertiserGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "advertiser*2015" will return objects with names like
// "advertiser group June 2015", "advertiser group April 2015", or
// simply "advertiser group 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "advertisergroup" will match objects
// with name "my advertisergroup", "advertisergroup 2015", or simply
// "advertisergroup".
func (c *AdvertiserGroupsListCall) SearchString(searchString string) *AdvertiserGroupsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *AdvertiserGroupsListCall) SortField(sortField string) *AdvertiserGroupsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *AdvertiserGroupsListCall) SortOrder(sortOrder string) *AdvertiserGroupsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsListCall) Fields(s ...googleapi.Field) *AdvertiserGroupsListCall {
	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 *AdvertiserGroupsListCall) IfNoneMatch(entityTag string) *AdvertiserGroupsListCall {
	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 *AdvertiserGroupsListCall) Context(ctx context.Context) *AdvertiserGroupsListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserGroups.list" call.
// Exactly one of *AdvertiserGroupsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AdvertiserGroupsListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsListCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of advertiser groups, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/advertiserGroups",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertiserGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only advertiser groups with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"advertiser*2015\" will return objects with names like \"advertiser group June 2015\", \"advertiser group April 2015\", or simply \"advertiser group 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"advertisergroup\" will match objects with name \"my advertisergroup\", \"advertisergroup 2015\", or simply \"advertisergroup\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups",
	//   "response": {
	//     "$ref": "AdvertiserGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *AdvertiserGroupsListCall) Pages(ctx context.Context, f func(*AdvertiserGroupsListResponse) 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 "dfareporting.advertiserGroups.patch":

type AdvertiserGroupsPatchCall struct {
	s               *Service
	profileId       int64
	advertisergroup *AdvertiserGroup
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Patch: Updates an existing advertiser group. This method supports
// patch semantics.
func (r *AdvertiserGroupsService) Patch(profileId int64, advertisergroup *AdvertiserGroup) *AdvertiserGroupsPatchCall {
	c := &AdvertiserGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertisergroup = advertisergroup
	return c
}

// Id sets the optional parameter "id": AdvertiserGroup ID.
func (c *AdvertiserGroupsPatchCall) Id(id int64) *AdvertiserGroupsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsPatchCall) Fields(s ...googleapi.Field) *AdvertiserGroupsPatchCall {
	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 *AdvertiserGroupsPatchCall) Context(ctx context.Context) *AdvertiserGroupsPatchCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserGroups.patch" call.
// Exactly one of *AdvertiserGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdvertiserGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsPatchCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroup{
		ServerResponse: googleapi.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 group. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/advertiserGroups",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.advertiserGroups.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "AdvertiserGroup ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups",
	//   "request": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "response": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.update":

type AdvertiserGroupsUpdateCall struct {
	s               *Service
	profileId       int64
	advertisergroup *AdvertiserGroup
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Update: Updates an existing advertiser group.
func (r *AdvertiserGroupsService) Update(profileId int64, advertisergroup *AdvertiserGroup) *AdvertiserGroupsUpdateCall {
	c := &AdvertiserGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertisergroup = advertisergroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsUpdateCall) Fields(s ...googleapi.Field) *AdvertiserGroupsUpdateCall {
	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 *AdvertiserGroupsUpdateCall) Context(ctx context.Context) *AdvertiserGroupsUpdateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *AdvertiserGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.advertisergroup)
	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, "userprofiles/{profileId}/advertiserGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertiserGroups.update" call.
// Exactly one of *AdvertiserGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdvertiserGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroup{
		ServerResponse: googleapi.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 group.",
	//   "flatPath": "userprofiles/{profileId}/advertiserGroups",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.advertiserGroups.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups",
	//   "request": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "response": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserLandingPages.get":

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

// Get: Gets one landing page by ID.
func (r *AdvertiserLandingPagesService) Get(profileId int64, id int64) *AdvertiserLandingPagesGetCall {
	c := &AdvertiserLandingPagesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserLandingPagesGetCall) Fields(s ...googleapi.Field) *AdvertiserLandingPagesGetCall {
	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 *AdvertiserLandingPagesGetCall) IfNoneMatch(entityTag string) *AdvertiserLandingPagesGetCall {
	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 *AdvertiserLandingPagesGetCall) Context(ctx context.Context) *AdvertiserLandingPagesGetCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserLandingPages.get" call.
// Exactly one of *LandingPage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LandingPage.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertiserLandingPagesGetCall) Do(opts ...googleapi.CallOption) (*LandingPage, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPage{
		ServerResponse: googleapi.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 one landing page by ID.",
	//   "flatPath": "userprofiles/{profileId}/advertiserLandingPages/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertiserLandingPages.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Landing page ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserLandingPages/{id}",
	//   "response": {
	//     "$ref": "LandingPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserLandingPages.insert":

type AdvertiserLandingPagesInsertCall struct {
	s           *Service
	profileId   int64
	landingpage *LandingPage
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Insert: Inserts a new landing page.
func (r *AdvertiserLandingPagesService) Insert(profileId int64, landingpage *LandingPage) *AdvertiserLandingPagesInsertCall {
	c := &AdvertiserLandingPagesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.landingpage = landingpage
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserLandingPagesInsertCall) Fields(s ...googleapi.Field) *AdvertiserLandingPagesInsertCall {
	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 *AdvertiserLandingPagesInsertCall) Context(ctx context.Context) *AdvertiserLandingPagesInsertCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserLandingPages.insert" call.
// Exactly one of *LandingPage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LandingPage.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertiserLandingPagesInsertCall) Do(opts ...googleapi.CallOption) (*LandingPage, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPage{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new landing page.",
	//   "flatPath": "userprofiles/{profileId}/advertiserLandingPages",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.advertiserLandingPages.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserLandingPages",
	//   "request": {
	//     "$ref": "LandingPage"
	//   },
	//   "response": {
	//     "$ref": "LandingPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserLandingPages.list":

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

// List: Retrieves a list of landing pages.
func (r *AdvertiserLandingPagesService) List(profileId int64) *AdvertiserLandingPagesListCall {
	c := &AdvertiserLandingPagesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only landing pages that belong to these advertisers.
func (c *AdvertiserLandingPagesListCall) AdvertiserIds(advertiserIds ...int64) *AdvertiserLandingPagesListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// landing pages. Don't set this field to select both archived and
// non-archived landing pages.
func (c *AdvertiserLandingPagesListCall) Archived(archived bool) *AdvertiserLandingPagesListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// landing pages that are associated with these campaigns.
func (c *AdvertiserLandingPagesListCall) CampaignIds(campaignIds ...int64) *AdvertiserLandingPagesListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only landing pages with
// these IDs.
func (c *AdvertiserLandingPagesListCall) Ids(ids ...int64) *AdvertiserLandingPagesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AdvertiserLandingPagesListCall) MaxResults(maxResults int64) *AdvertiserLandingPagesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AdvertiserLandingPagesListCall) PageToken(pageToken string) *AdvertiserLandingPagesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for landing pages by name or ID. Wildcards (*) are allowed.
// For example, "landingpage*2017" will return landing pages with names
// like "landingpage July 2017", "landingpage March 2017", or simply
// "landingpage 2017". Most of the searches also add wildcards
// implicitly at the start and the end of the search string. For
// example, a search string of "landingpage" will match campaigns with
// name "my landingpage", "landingpage 2015", or simply "landingpage".
func (c *AdvertiserLandingPagesListCall) SearchString(searchString string) *AdvertiserLandingPagesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *AdvertiserLandingPagesListCall) SortField(sortField string) *AdvertiserLandingPagesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *AdvertiserLandingPagesListCall) SortOrder(sortOrder string) *AdvertiserLandingPagesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// landing pages that belong to this subaccount.
func (c *AdvertiserLandingPagesListCall) SubaccountId(subaccountId int64) *AdvertiserLandingPagesListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserLandingPagesListCall) Fields(s ...googleapi.Field) *AdvertiserLandingPagesListCall {
	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 *AdvertiserLandingPagesListCall) IfNoneMatch(entityTag string) *AdvertiserLandingPagesListCall {
	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 *AdvertiserLandingPagesListCall) Context(ctx context.Context) *AdvertiserLandingPagesListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserLandingPages.list" call.
// Exactly one of *AdvertiserLandingPagesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AdvertiserLandingPagesListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdvertiserLandingPagesListCall) Do(opts ...googleapi.CallOption) (*AdvertiserLandingPagesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserLandingPagesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of landing pages.",
	//   "flatPath": "userprofiles/{profileId}/advertiserLandingPages",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertiserLandingPages.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only landing pages that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived landing pages. Don't set this field to select both archived and non-archived landing pages.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignIds": {
	//       "description": "Select only landing pages that are associated with these campaigns.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only landing pages with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for landing pages by name or ID. Wildcards (*) are allowed. For example, \"landingpage*2017\" will return landing pages with names like \"landingpage July 2017\", \"landingpage March 2017\", or simply \"landingpage 2017\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"landingpage\" will match campaigns with name \"my landingpage\", \"landingpage 2015\", or simply \"landingpage\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only landing pages that belong to this subaccount.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserLandingPages",
	//   "response": {
	//     "$ref": "AdvertiserLandingPagesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *AdvertiserLandingPagesListCall) Pages(ctx context.Context, f func(*AdvertiserLandingPagesListResponse) 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 "dfareporting.advertiserLandingPages.patch":

type AdvertiserLandingPagesPatchCall struct {
	s           *Service
	profileId   int64
	landingpage *LandingPage
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Patch: Updates an existing advertiser landing page. This method
// supports patch semantics.
func (r *AdvertiserLandingPagesService) Patch(profileId int64, landingpage *LandingPage) *AdvertiserLandingPagesPatchCall {
	c := &AdvertiserLandingPagesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.landingpage = landingpage
	return c
}

// Id sets the optional parameter "id": LandingPage ID.
func (c *AdvertiserLandingPagesPatchCall) Id(id int64) *AdvertiserLandingPagesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserLandingPagesPatchCall) Fields(s ...googleapi.Field) *AdvertiserLandingPagesPatchCall {
	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 *AdvertiserLandingPagesPatchCall) Context(ctx context.Context) *AdvertiserLandingPagesPatchCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertiserLandingPages.patch" call.
// Exactly one of *LandingPage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LandingPage.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertiserLandingPagesPatchCall) Do(opts ...googleapi.CallOption) (*LandingPage, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPage{
		ServerResponse: googleapi.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 landing page. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/advertiserLandingPages",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.advertiserLandingPages.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "LandingPage ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserLandingPages",
	//   "request": {
	//     "$ref": "LandingPage"
	//   },
	//   "response": {
	//     "$ref": "LandingPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserLandingPages.update":

type AdvertiserLandingPagesUpdateCall struct {
	s           *Service
	profileId   int64
	landingpage *LandingPage
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Update: Updates an existing landing page.
func (r *AdvertiserLandingPagesService) Update(profileId int64, landingpage *LandingPage) *AdvertiserLandingPagesUpdateCall {
	c := &AdvertiserLandingPagesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.landingpage = landingpage
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserLandingPagesUpdateCall) Fields(s ...googleapi.Field) *AdvertiserLandingPagesUpdateCall {
	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 *AdvertiserLandingPagesUpdateCall) Context(ctx context.Context) *AdvertiserLandingPagesUpdateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *AdvertiserLandingPagesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.landingpage)
	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, "userprofiles/{profileId}/advertiserLandingPages")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertiserLandingPages.update" call.
// Exactly one of *LandingPage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LandingPage.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertiserLandingPagesUpdateCall) Do(opts ...googleapi.CallOption) (*LandingPage, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPage{
		ServerResponse: googleapi.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 landing page.",
	//   "flatPath": "userprofiles/{profileId}/advertiserLandingPages",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.advertiserLandingPages.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserLandingPages",
	//   "request": {
	//     "$ref": "LandingPage"
	//   },
	//   "response": {
	//     "$ref": "LandingPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertisers.get":

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

// Get: Gets one advertiser by ID.
func (r *AdvertisersService) Get(profileId int64, id int64) *AdvertisersGetCall {
	c := &AdvertisersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return 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/20200825")
	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, "userprofiles/{profileId}/advertisers/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.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 one advertiser by ID.",
	//   "flatPath": "userprofiles/{profileId}/advertisers/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertisers.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers/{id}",
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertisers.insert":

type AdvertisersInsertCall struct {
	s          *Service
	profileId  int64
	advertiser *Advertiser
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new advertiser.
func (r *AdvertisersService) Insert(profileId int64, advertiser *Advertiser) *AdvertisersInsertCall {
	c := &AdvertisersInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	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 *AdvertisersInsertCall) Fields(s ...googleapi.Field) *AdvertisersInsertCall {
	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 *AdvertisersInsertCall) Context(ctx context.Context) *AdvertisersInsertCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.advertisers.insert" 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 *AdvertisersInsertCall) 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": "Inserts a new advertiser.",
	//   "flatPath": "userprofiles/{profileId}/advertisers",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.advertisers.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers",
	//   "request": {
	//     "$ref": "Advertiser"
	//   },
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertisers.list":

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

// List: Retrieves a list of advertisers, possibly filtered. This method
// supports paging.
func (r *AdvertisersService) List(profileId int64) *AdvertisersListCall {
	c := &AdvertisersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserGroupIds sets the optional parameter "advertiserGroupIds":
// Select only advertisers with these advertiser group IDs.
func (c *AdvertisersListCall) AdvertiserGroupIds(advertiserGroupIds ...int64) *AdvertisersListCall {
	var advertiserGroupIds_ []string
	for _, v := range advertiserGroupIds {
		advertiserGroupIds_ = append(advertiserGroupIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserGroupIds", advertiserGroupIds_)
	return c
}

// FloodlightConfigurationIds sets the optional parameter
// "floodlightConfigurationIds": Select only advertisers with these
// floodlight configuration IDs.
func (c *AdvertisersListCall) FloodlightConfigurationIds(floodlightConfigurationIds ...int64) *AdvertisersListCall {
	var floodlightConfigurationIds_ []string
	for _, v := range floodlightConfigurationIds {
		floodlightConfigurationIds_ = append(floodlightConfigurationIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("floodlightConfigurationIds", floodlightConfigurationIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only advertisers with
// these IDs.
func (c *AdvertisersListCall) Ids(ids ...int64) *AdvertisersListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// IncludeAdvertisersWithoutGroupsOnly sets the optional parameter
// "includeAdvertisersWithoutGroupsOnly": Select only advertisers which
// do not belong to any advertiser group.
func (c *AdvertisersListCall) IncludeAdvertisersWithoutGroupsOnly(includeAdvertisersWithoutGroupsOnly bool) *AdvertisersListCall {
	c.urlParams_.Set("includeAdvertisersWithoutGroupsOnly", fmt.Sprint(includeAdvertisersWithoutGroupsOnly))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AdvertisersListCall) MaxResults(maxResults int64) *AdvertisersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OnlyParent sets the optional parameter "onlyParent": Select only
// advertisers which use another advertiser's floodlight configuration.
func (c *AdvertisersListCall) OnlyParent(onlyParent bool) *AdvertisersListCall {
	c.urlParams_.Set("onlyParent", fmt.Sprint(onlyParent))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AdvertisersListCall) PageToken(pageToken string) *AdvertisersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "advertiser*2015" will return objects with names like
// "advertiser June 2015", "advertiser April 2015", or simply
// "advertiser 2015". Most of the searches also add wildcards implicitly
// at the start and the end of the search string. For example, a search
// string of "advertiser" will match objects with name "my advertiser",
// "advertiser 2015", or simply "advertiser" .
func (c *AdvertisersListCall) SearchString(searchString string) *AdvertisersListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *AdvertisersListCall) SortField(sortField string) *AdvertisersListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *AdvertisersListCall) SortOrder(sortOrder string) *AdvertisersListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Status sets the optional parameter "status": Select only advertisers
// with the specified status.
//
// Possible values:
//   "APPROVED"
//   "ON_HOLD"
func (c *AdvertisersListCall) Status(status string) *AdvertisersListCall {
	c.urlParams_.Set("status", status)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// advertisers with these subaccount IDs.
func (c *AdvertisersListCall) SubaccountId(subaccountId int64) *AdvertisersListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return 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/20200825")
	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, "userprofiles/{profileId}/advertisers")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertisers.list" call.
// Exactly one of *AdvertisersListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AdvertisersListResponse.ServerResponse.Header or (if a response was
// returned 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) (*AdvertisersListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertisersListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of advertisers, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/advertisers",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertisers.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserGroupIds": {
	//       "description": "Select only advertisers with these advertiser group IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "floodlightConfigurationIds": {
	//       "description": "Select only advertisers with these floodlight configuration IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only advertisers with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "includeAdvertisersWithoutGroupsOnly": {
	//       "description": "Select only advertisers which do not belong to any advertiser group.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "onlyParent": {
	//       "description": "Select only advertisers which use another advertiser's floodlight configuration.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"advertiser*2015\" will return objects with names like \"advertiser June 2015\", \"advertiser April 2015\", or simply \"advertiser 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"advertiser\" will match objects with name \"my advertiser\", \"advertiser 2015\", or simply \"advertiser\" .",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "status": {
	//       "description": "Select only advertisers with the specified status.",
	//       "enum": [
	//         "APPROVED",
	//         "ON_HOLD"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only advertisers with these subaccount IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers",
	//   "response": {
	//     "$ref": "AdvertisersListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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(*AdvertisersListResponse) 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 "dfareporting.advertisers.patch":

type AdvertisersPatchCall struct {
	s          *Service
	profileId  int64
	advertiser *Advertiser
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing advertiser. This method supports patch
// semantics.
func (r *AdvertisersService) Patch(profileId int64, advertiser *Advertiser) *AdvertisersPatchCall {
	c := &AdvertisersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertiser = advertiser
	return c
}

// Id sets the optional parameter "id": Advertiser ID.
func (c *AdvertisersPatchCall) Id(id int64) *AdvertisersPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return 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/20200825")
	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, "userprofiles/{profileId}/advertisers")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.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. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/advertisers",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.advertisers.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers",
	//   "request": {
	//     "$ref": "Advertiser"
	//   },
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertisers.update":

type AdvertisersUpdateCall struct {
	s          *Service
	profileId  int64
	advertiser *Advertiser
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing advertiser.
func (r *AdvertisersService) Update(profileId int64, advertiser *Advertiser) *AdvertisersUpdateCall {
	c := &AdvertisersUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	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 *AdvertisersUpdateCall) Fields(s ...googleapi.Field) *AdvertisersUpdateCall {
	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 *AdvertisersUpdateCall) Context(ctx context.Context) *AdvertisersUpdateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *AdvertisersUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/advertisers")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertisers.update" 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 *AdvertisersUpdateCall) 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.",
	//   "flatPath": "userprofiles/{profileId}/advertisers",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.advertisers.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers",
	//   "request": {
	//     "$ref": "Advertiser"
	//   },
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.browsers.list":

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

// List: Retrieves a list of browsers.
func (r *BrowsersService) List(profileId int64) *BrowsersListCall {
	c := &BrowsersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BrowsersListCall) Fields(s ...googleapi.Field) *BrowsersListCall {
	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 *BrowsersListCall) IfNoneMatch(entityTag string) *BrowsersListCall {
	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 *BrowsersListCall) Context(ctx context.Context) *BrowsersListCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.browsers.list" call.
// Exactly one of *BrowsersListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BrowsersListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BrowsersListCall) Do(opts ...googleapi.CallOption) (*BrowsersListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BrowsersListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of browsers.",
	//   "flatPath": "userprofiles/{profileId}/browsers",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.browsers.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/browsers",
	//   "response": {
	//     "$ref": "BrowsersListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaignCreativeAssociations.insert":

type CampaignCreativeAssociationsInsertCall struct {
	s                           *Service
	profileId                   int64
	campaignId                  int64
	campaigncreativeassociation *CampaignCreativeAssociation
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
	header_                     http.Header
}

// Insert: Associates a creative with the specified campaign. This
// method creates a default ad with dimensions matching the creative in
// the campaign if such a default ad does not exist already.
func (r *CampaignCreativeAssociationsService) Insert(profileId int64, campaignId int64, campaigncreativeassociation *CampaignCreativeAssociation) *CampaignCreativeAssociationsInsertCall {
	c := &CampaignCreativeAssociationsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	c.campaigncreativeassociation = campaigncreativeassociation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignCreativeAssociationsInsertCall) Fields(s ...googleapi.Field) *CampaignCreativeAssociationsInsertCall {
	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 *CampaignCreativeAssociationsInsertCall) Context(ctx context.Context) *CampaignCreativeAssociationsInsertCall {
	c.ctx_ = ctx
	return c
}

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

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

// Do executes the "dfareporting.campaignCreativeAssociations.insert" call.
// Exactly one of *CampaignCreativeAssociation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CampaignCreativeAssociation.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CampaignCreativeAssociationsInsertCall) Do(opts ...googleapi.CallOption) (*CampaignCreativeAssociation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CampaignCreativeAssociation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Associates a creative with the specified campaign. This method creates a default ad with dimensions matching the creative in the campaign if such a default ad does not exist already.",
	//   "flatPath": "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.campaignCreativeAssociations.insert",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Campaign ID in this association.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations",
	//   "request": {
	//     "$ref": "CampaignCreativeAssociation"
	//   },
	//   "response": {
	//     "$ref": "CampaignCreativeAssociation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaignCreativeAssociations.list":

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

// List: Retrieves the list of creative IDs associated with the
// specified campaign. This method supports paging.
func (r *CampaignCreativeAssociationsService) List(profileId int64, campaignId int64) *CampaignCreativeAssociationsListCall {
	c := &CampaignCreativeAssociationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CampaignCreativeAssociationsListCall) MaxResults(maxResults int64) *CampaignCreativeAssociationsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CampaignCreativeAssociationsListCall) PageToken(pageToken string) *CampaignCreativeAssociationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *CampaignCreativeAssociationsListCall) SortOrder(sortOrder string) *CampaignCreativeAssociationsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignCreativeAssociationsListCall) Fields(s ...googleapi.Field) *CampaignCreativeAssociationsListCall {
	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 *CampaignCreativeAssociationsListCall) IfNoneMatch(entityTag string) *CampaignCreativeAssociationsListCall {
	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 *CampaignCreativeAssociationsListCall) Context(ctx context.Context) *CampaignCreativeAssociationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignCreativeAssociationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignCreativeAssociationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations")
	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{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaignCreativeAssociations.list" call.
// Exactly one of *CampaignCreativeAssociationsListResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *CampaignCreativeAssociationsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CampaignCreativeAssociationsListCall) Do(opts ...googleapi.CallOption) (*CampaignCreativeAssociationsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CampaignCreativeAssociationsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of creative IDs associated with the specified campaign. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.campaignCreativeAssociations.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Campaign ID in this association.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations",
	//   "response": {
	//     "$ref": "CampaignCreativeAssociationsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *CampaignCreativeAssociationsListCall) Pages(ctx context.Context, f func(*CampaignCreativeAssociationsListResponse) 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 "dfareporting.campaigns.get":

type CampaignsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one campaign by ID.
func (r *CampaignsService) Get(profileId int64, id int64) *CampaignsGetCall {
	c := &CampaignsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignsGetCall) Fields(s ...googleapi.Field) *CampaignsGetCall {
	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 *CampaignsGetCall) IfNoneMatch(entityTag string) *CampaignsGetCall {
	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 *CampaignsGetCall) Context(ctx context.Context) *CampaignsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/campaigns/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.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 *CampaignsGetCall) 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 one campaign by ID.",
	//   "flatPath": "userprofiles/{profileId}/campaigns/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.campaigns.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Campaign ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{id}",
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaigns.insert":

type CampaignsInsertCall struct {
	s          *Service
	profileId  int64
	campaign   *Campaign
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new campaign.
func (r *CampaignsService) Insert(profileId int64, campaign *Campaign) *CampaignsInsertCall {
	c := &CampaignsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	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 *CampaignsInsertCall) Fields(s ...googleapi.Field) *CampaignsInsertCall {
	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 *CampaignsInsertCall) Context(ctx context.Context) *CampaignsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaigns.insert" 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 *CampaignsInsertCall) 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": "Inserts a new campaign.",
	//   "flatPath": "userprofiles/{profileId}/campaigns",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.campaigns.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns",
	//   "request": {
	//     "$ref": "Campaign"
	//   },
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaigns.list":

type CampaignsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of campaigns, possibly filtered. This method
// supports paging.
func (r *CampaignsService) List(profileId int64) *CampaignsListCall {
	c := &CampaignsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserGroupIds sets the optional parameter "advertiserGroupIds":
// Select only campaigns whose advertisers belong to these advertiser
// groups.
func (c *CampaignsListCall) AdvertiserGroupIds(advertiserGroupIds ...int64) *CampaignsListCall {
	var advertiserGroupIds_ []string
	for _, v := range advertiserGroupIds {
		advertiserGroupIds_ = append(advertiserGroupIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserGroupIds", advertiserGroupIds_)
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only campaigns that belong to these advertisers.
func (c *CampaignsListCall) AdvertiserIds(advertiserIds ...int64) *CampaignsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// campaigns. Don't set this field to select both archived and
// non-archived campaigns.
func (c *CampaignsListCall) Archived(archived bool) *CampaignsListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// AtLeastOneOptimizationActivity sets the optional parameter
// "atLeastOneOptimizationActivity": Select only campaigns that have at
// least one optimization activity.
func (c *CampaignsListCall) AtLeastOneOptimizationActivity(atLeastOneOptimizationActivity bool) *CampaignsListCall {
	c.urlParams_.Set("atLeastOneOptimizationActivity", fmt.Sprint(atLeastOneOptimizationActivity))
	return c
}

// ExcludedIds sets the optional parameter "excludedIds": Exclude
// campaigns with these IDs.
func (c *CampaignsListCall) ExcludedIds(excludedIds ...int64) *CampaignsListCall {
	var excludedIds_ []string
	for _, v := range excludedIds {
		excludedIds_ = append(excludedIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("excludedIds", excludedIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only campaigns with
// these IDs.
func (c *CampaignsListCall) Ids(ids ...int64) *CampaignsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CampaignsListCall) MaxResults(maxResults int64) *CampaignsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OverriddenEventTagId sets the optional parameter
// "overriddenEventTagId": Select only campaigns that have overridden
// this event tag ID.
func (c *CampaignsListCall) OverriddenEventTagId(overriddenEventTagId int64) *CampaignsListCall {
	c.urlParams_.Set("overriddenEventTagId", fmt.Sprint(overriddenEventTagId))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CampaignsListCall) PageToken(pageToken string) *CampaignsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for campaigns by name or ID. Wildcards (*) are allowed. For
// example, "campaign*2015" will return campaigns with names like
// "campaign June 2015", "campaign April 2015", or simply "campaign
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "campaign" will match campaigns with name "my campaign", "campaign
// 2015", or simply "campaign".
func (c *CampaignsListCall) SearchString(searchString string) *CampaignsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *CampaignsListCall) SortField(sortField string) *CampaignsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *CampaignsListCall) SortOrder(sortOrder string) *CampaignsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// campaigns that belong to this subaccount.
func (c *CampaignsListCall) SubaccountId(subaccountId int64) *CampaignsListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignsListCall) Fields(s ...googleapi.Field) *CampaignsListCall {
	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 *CampaignsListCall) IfNoneMatch(entityTag string) *CampaignsListCall {
	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 *CampaignsListCall) Context(ctx context.Context) *CampaignsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaigns.list" call.
// Exactly one of *CampaignsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CampaignsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CampaignsListCall) Do(opts ...googleapi.CallOption) (*CampaignsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CampaignsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of campaigns, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/campaigns",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.campaigns.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserGroupIds": {
	//       "description": "Select only campaigns whose advertisers belong to these advertiser groups.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "advertiserIds": {
	//       "description": "Select only campaigns that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived campaigns. Don't set this field to select both archived and non-archived campaigns.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "atLeastOneOptimizationActivity": {
	//       "description": "Select only campaigns that have at least one optimization activity.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "excludedIds": {
	//       "description": "Exclude campaigns with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only campaigns with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "overriddenEventTagId": {
	//       "description": "Select only campaigns that have overridden this event tag ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for campaigns by name or ID. Wildcards (*) are allowed. For example, \"campaign*2015\" will return campaigns with names like \"campaign June 2015\", \"campaign April 2015\", or simply \"campaign 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"campaign\" will match campaigns with name \"my campaign\", \"campaign 2015\", or simply \"campaign\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only campaigns that belong to this subaccount.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns",
	//   "response": {
	//     "$ref": "CampaignsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *CampaignsListCall) Pages(ctx context.Context, f func(*CampaignsListResponse) 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 "dfareporting.campaigns.patch":

type CampaignsPatchCall struct {
	s          *Service
	profileId  int64
	campaign   *Campaign
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing campaign. This method supports patch
// semantics.
func (r *CampaignsService) Patch(profileId int64, campaign *Campaign) *CampaignsPatchCall {
	c := &CampaignsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaign = campaign
	return c
}

// Id sets the optional parameter "id": Campaign ID.
func (c *CampaignsPatchCall) Id(id int64) *CampaignsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignsPatchCall) Fields(s ...googleapi.Field) *CampaignsPatchCall {
	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 *CampaignsPatchCall) Context(ctx context.Context) *CampaignsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/campaigns")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.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 *CampaignsPatchCall) 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. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/campaigns",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.campaigns.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Campaign ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns",
	//   "request": {
	//     "$ref": "Campaign"
	//   },
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaigns.update":

type CampaignsUpdateCall struct {
	s          *Service
	profileId  int64
	campaign   *Campaign
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing campaign.
func (r *CampaignsService) Update(profileId int64, campaign *Campaign) *CampaignsUpdateCall {
	c := &CampaignsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	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 *CampaignsUpdateCall) Fields(s ...googleapi.Field) *CampaignsUpdateCall {
	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 *CampaignsUpdateCall) Context(ctx context.Context) *CampaignsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/campaigns")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaigns.update" 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 *CampaignsUpdateCall) 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.",
	//   "flatPath": "userprofiles/{profileId}/campaigns",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.campaigns.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns",
	//   "request": {
	//     "$ref": "Campaign"
	//   },
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.changeLogs.get":

type ChangeLogsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one change log by ID.
func (r *ChangeLogsService) Get(profileId int64, id int64) *ChangeLogsGetCall {
	c := &ChangeLogsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ChangeLogsGetCall) Fields(s ...googleapi.Field) *ChangeLogsGetCall {
	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 *ChangeLogsGetCall) IfNoneMatch(entityTag string) *ChangeLogsGetCall {
	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 *ChangeLogsGetCall) Context(ctx context.Context) *ChangeLogsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ChangeLogsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ChangeLogsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/changeLogs/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.changeLogs.get" call.
// Exactly one of *ChangeLog or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ChangeLog.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ChangeLogsGetCall) Do(opts ...googleapi.CallOption) (*ChangeLog, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ChangeLog{
		ServerResponse: googleapi.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 one change log by ID.",
	//   "flatPath": "userprofiles/{profileId}/changeLogs/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.changeLogs.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Change log ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/changeLogs/{id}",
	//   "response": {
	//     "$ref": "ChangeLog"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.changeLogs.list":

type ChangeLogsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of change logs. This method supports paging.
func (r *ChangeLogsService) List(profileId int64) *ChangeLogsListCall {
	c := &ChangeLogsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Action sets the optional parameter "action": Select only change logs
// with the specified action.
//
// Possible values:
//   "ACTION_CREATE"
//   "ACTION_UPDATE"
//   "ACTION_DELETE"
//   "ACTION_ENABLE"
//   "ACTION_DISABLE"
//   "ACTION_ADD"
//   "ACTION_REMOVE"
//   "ACTION_MARK_AS_DEFAULT"
//   "ACTION_ASSOCIATE"
//   "ACTION_ASSIGN"
//   "ACTION_UNASSIGN"
//   "ACTION_SEND"
//   "ACTION_LINK"
//   "ACTION_UNLINK"
//   "ACTION_PUSH"
//   "ACTION_EMAIL_TAGS"
//   "ACTION_SHARE"
func (c *ChangeLogsListCall) Action(action string) *ChangeLogsListCall {
	c.urlParams_.Set("action", action)
	return c
}

// Ids sets the optional parameter "ids": Select only change logs with
// these IDs.
func (c *ChangeLogsListCall) Ids(ids ...int64) *ChangeLogsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxChangeTime sets the optional parameter "maxChangeTime": Select
// only change logs whose change time is before the specified
// maxChangeTime.The time should be formatted as an RFC3339 date/time
// string. For example, for 10:54 PM on July 18th, 2015, in the
// America/New York time zone, the format is
// "2015-07-18T22:54:00-04:00". In other words, the year, month, day,
// the letter T, the hour (24-hour clock system), minute, second, and
// then the time zone offset.
func (c *ChangeLogsListCall) MaxChangeTime(maxChangeTime string) *ChangeLogsListCall {
	c.urlParams_.Set("maxChangeTime", maxChangeTime)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ChangeLogsListCall) MaxResults(maxResults int64) *ChangeLogsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// MinChangeTime sets the optional parameter "minChangeTime": Select
// only change logs whose change time is after the specified
// minChangeTime.The time should be formatted as an RFC3339 date/time
// string. For example, for 10:54 PM on July 18th, 2015, in the
// America/New York time zone, the format is
// "2015-07-18T22:54:00-04:00". In other words, the year, month, day,
// the letter T, the hour (24-hour clock system), minute, second, and
// then the time zone offset.
func (c *ChangeLogsListCall) MinChangeTime(minChangeTime string) *ChangeLogsListCall {
	c.urlParams_.Set("minChangeTime", minChangeTime)
	return c
}

// ObjectIds sets the optional parameter "objectIds": Select only change
// logs with these object IDs.
func (c *ChangeLogsListCall) ObjectIds(objectIds ...int64) *ChangeLogsListCall {
	var objectIds_ []string
	for _, v := range objectIds {
		objectIds_ = append(objectIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("objectIds", objectIds_)
	return c
}

// ObjectType sets the optional parameter "objectType": Select only
// change logs with the specified object type.
//
// Possible values:
//   "OBJECT_ADVERTISER"
//   "OBJECT_FLOODLIGHT_CONFIGURATION"
//   "OBJECT_AD"
//   "OBJECT_FLOODLIGHT_ACTVITY"
//   "OBJECT_CAMPAIGN"
//   "OBJECT_FLOODLIGHT_ACTIVITY_GROUP"
//   "OBJECT_CREATIVE"
//   "OBJECT_PLACEMENT"
//   "OBJECT_DFA_SITE"
//   "OBJECT_USER_ROLE"
//   "OBJECT_USER_PROFILE"
//   "OBJECT_ADVERTISER_GROUP"
//   "OBJECT_ACCOUNT"
//   "OBJECT_SUBACCOUNT"
//   "OBJECT_RICHMEDIA_CREATIVE"
//   "OBJECT_INSTREAM_CREATIVE"
//   "OBJECT_MEDIA_ORDER"
//   "OBJECT_CONTENT_CATEGORY"
//   "OBJECT_PLACEMENT_STRATEGY"
//   "OBJECT_SD_SITE"
//   "OBJECT_SIZE"
//   "OBJECT_CREATIVE_GROUP"
//   "OBJECT_CREATIVE_ASSET"
//   "OBJECT_USER_PROFILE_FILTER"
//   "OBJECT_LANDING_PAGE"
//   "OBJECT_CREATIVE_FIELD"
//   "OBJECT_REMARKETING_LIST"
//   "OBJECT_PROVIDED_LIST_CLIENT"
//   "OBJECT_EVENT_TAG"
//   "OBJECT_CREATIVE_BUNDLE"
//   "OBJECT_BILLING_ACCOUNT_GROUP"
//   "OBJECT_BILLING_FEATURE"
//   "OBJECT_RATE_CARD"
//   "OBJECT_ACCOUNT_BILLING_FEATURE"
//   "OBJECT_BILLING_MINIMUM_FEE"
//   "OBJECT_BILLING_PROFILE"
//   "OBJECT_PLAYSTORE_LINK"
//   "OBJECT_TARGETING_TEMPLATE"
//   "OBJECT_SEARCH_LIFT_STUDY"
//   "OBJECT_FLOODLIGHT_DV360_LINK"
func (c *ChangeLogsListCall) ObjectType(objectType string) *ChangeLogsListCall {
	c.urlParams_.Set("objectType", objectType)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *ChangeLogsListCall) PageToken(pageToken string) *ChangeLogsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Select only
// change logs whose object ID, user name, old or new values match the
// search string.
func (c *ChangeLogsListCall) SearchString(searchString string) *ChangeLogsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// UserProfileIds sets the optional parameter "userProfileIds": Select
// only change logs with these user profile IDs.
func (c *ChangeLogsListCall) UserProfileIds(userProfileIds ...int64) *ChangeLogsListCall {
	var userProfileIds_ []string
	for _, v := range userProfileIds {
		userProfileIds_ = append(userProfileIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("userProfileIds", userProfileIds_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ChangeLogsListCall) Fields(s ...googleapi.Field) *ChangeLogsListCall {
	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 *ChangeLogsListCall) IfNoneMatch(entityTag string) *ChangeLogsListCall {
	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 *ChangeLogsListCall) Context(ctx context.Context) *ChangeLogsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ChangeLogsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ChangeLogsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/changeLogs")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.changeLogs.list" call.
// Exactly one of *ChangeLogsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ChangeLogsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ChangeLogsListCall) Do(opts ...googleapi.CallOption) (*ChangeLogsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ChangeLogsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of change logs. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/changeLogs",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.changeLogs.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Select only change logs with the specified action.",
	//       "enum": [
	//         "ACTION_CREATE",
	//         "ACTION_UPDATE",
	//         "ACTION_DELETE",
	//         "ACTION_ENABLE",
	//         "ACTION_DISABLE",
	//         "ACTION_ADD",
	//         "ACTION_REMOVE",
	//         "ACTION_MARK_AS_DEFAULT",
	//         "ACTION_ASSOCIATE",
	//         "ACTION_ASSIGN",
	//         "ACTION_UNASSIGN",
	//         "ACTION_SEND",
	//         "ACTION_LINK",
	//         "ACTION_UNLINK",
	//         "ACTION_PUSH",
	//         "ACTION_EMAIL_TAGS",
	//         "ACTION_SHARE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only change logs with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxChangeTime": {
	//       "description": "Select only change logs whose change time is before the specified maxChangeTime.The time should be formatted as an RFC3339 date/time string. For example, for 10:54 PM on July 18th, 2015, in the America/New York time zone, the format is \"2015-07-18T22:54:00-04:00\". In other words, the year, month, day, the letter T, the hour (24-hour clock system), minute, second, and then the time zone offset.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "minChangeTime": {
	//       "description": "Select only change logs whose change time is after the specified minChangeTime.The time should be formatted as an RFC3339 date/time string. For example, for 10:54 PM on July 18th, 2015, in the America/New York time zone, the format is \"2015-07-18T22:54:00-04:00\". In other words, the year, month, day, the letter T, the hour (24-hour clock system), minute, second, and then the time zone offset.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "objectIds": {
	//       "description": "Select only change logs with these object IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "objectType": {
	//       "description": "Select only change logs with the specified object type.",
	//       "enum": [
	//         "OBJECT_ADVERTISER",
	//         "OBJECT_FLOODLIGHT_CONFIGURATION",
	//         "OBJECT_AD",
	//         "OBJECT_FLOODLIGHT_ACTVITY",
	//         "OBJECT_CAMPAIGN",
	//         "OBJECT_FLOODLIGHT_ACTIVITY_GROUP",
	//         "OBJECT_CREATIVE",
	//         "OBJECT_PLACEMENT",
	//         "OBJECT_DFA_SITE",
	//         "OBJECT_USER_ROLE",
	//         "OBJECT_USER_PROFILE",
	//         "OBJECT_ADVERTISER_GROUP",
	//         "OBJECT_ACCOUNT",
	//         "OBJECT_SUBACCOUNT",
	//         "OBJECT_RICHMEDIA_CREATIVE",
	//         "OBJECT_INSTREAM_CREATIVE",
	//         "OBJECT_MEDIA_ORDER",
	//         "OBJECT_CONTENT_CATEGORY",
	//         "OBJECT_PLACEMENT_STRATEGY",
	//         "OBJECT_SD_SITE",
	//         "OBJECT_SIZE",
	//         "OBJECT_CREATIVE_GROUP",
	//         "OBJECT_CREATIVE_ASSET",
	//         "OBJECT_USER_PROFILE_FILTER",
	//         "OBJECT_LANDING_PAGE",
	//         "OBJECT_CREATIVE_FIELD",
	//         "OBJECT_REMARKETING_LIST",
	//         "OBJECT_PROVIDED_LIST_CLIENT",
	//         "OBJECT_EVENT_TAG",
	//         "OBJECT_CREATIVE_BUNDLE",
	//         "OBJECT_BILLING_ACCOUNT_GROUP",
	//         "OBJECT_BILLING_FEATURE",
	//         "OBJECT_RATE_CARD",
	//         "OBJECT_ACCOUNT_BILLING_FEATURE",
	//         "OBJECT_BILLING_MINIMUM_FEE",
	//         "OBJECT_BILLING_PROFILE",
	//         "OBJECT_PLAYSTORE_LINK",
	//         "OBJECT_TARGETING_TEMPLATE",
	//         "OBJECT_SEARCH_LIFT_STUDY",
	//         "OBJECT_FLOODLIGHT_DV360_LINK"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Select only change logs whose object ID, user name, old or new values match the search string.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProfileIds": {
	//       "description": "Select only change logs with these user profile IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/changeLogs",
	//   "response": {
	//     "$ref": "ChangeLogsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *ChangeLogsListCall) Pages(ctx context.Context, f func(*ChangeLogsListResponse) 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 "dfareporting.cities.list":

type CitiesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of cities, possibly filtered.
func (r *CitiesService) List(profileId int64) *CitiesListCall {
	c := &CitiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// CountryDartIds sets the optional parameter "countryDartIds": Select
// only cities from these countries.
func (c *CitiesListCall) CountryDartIds(countryDartIds ...int64) *CitiesListCall {
	var countryDartIds_ []string
	for _, v := range countryDartIds {
		countryDartIds_ = append(countryDartIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("countryDartIds", countryDartIds_)
	return c
}

// DartIds sets the optional parameter "dartIds": Select only cities
// with these DART IDs.
func (c *CitiesListCall) DartIds(dartIds ...int64) *CitiesListCall {
	var dartIds_ []string
	for _, v := range dartIds {
		dartIds_ = append(dartIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("dartIds", dartIds_)
	return c
}

// NamePrefix sets the optional parameter "namePrefix": Select only
// cities with names starting with this prefix.
func (c *CitiesListCall) NamePrefix(namePrefix string) *CitiesListCall {
	c.urlParams_.Set("namePrefix", namePrefix)
	return c
}

// RegionDartIds sets the optional parameter "regionDartIds": Select
// only cities from these regions.
func (c *CitiesListCall) RegionDartIds(regionDartIds ...int64) *CitiesListCall {
	var regionDartIds_ []string
	for _, v := range regionDartIds {
		regionDartIds_ = append(regionDartIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("regionDartIds", regionDartIds_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CitiesListCall) Fields(s ...googleapi.Field) *CitiesListCall {
	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 *CitiesListCall) IfNoneMatch(entityTag string) *CitiesListCall {
	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 *CitiesListCall) Context(ctx context.Context) *CitiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CitiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CitiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/cities")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.cities.list" call.
// Exactly one of *CitiesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CitiesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CitiesListCall) Do(opts ...googleapi.CallOption) (*CitiesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CitiesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of cities, possibly filtered.",
	//   "flatPath": "userprofiles/{profileId}/cities",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.cities.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "countryDartIds": {
	//       "description": "Select only cities from these countries.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "dartIds": {
	//       "description": "Select only cities with these DART IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "namePrefix": {
	//       "description": "Select only cities with names starting with this prefix.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "regionDartIds": {
	//       "description": "Select only cities from these regions.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/cities",
	//   "response": {
	//     "$ref": "CitiesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.connectionTypes.get":

type ConnectionTypesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one connection type by ID.
func (r *ConnectionTypesService) Get(profileId int64, id int64) *ConnectionTypesGetCall {
	c := &ConnectionTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ConnectionTypesGetCall) Fields(s ...googleapi.Field) *ConnectionTypesGetCall {
	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 *ConnectionTypesGetCall) IfNoneMatch(entityTag string) *ConnectionTypesGetCall {
	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 *ConnectionTypesGetCall) Context(ctx context.Context) *ConnectionTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ConnectionTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ConnectionTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/connectionTypes/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.connectionTypes.get" call.
// Exactly one of *ConnectionType or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ConnectionType.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ConnectionTypesGetCall) Do(opts ...googleapi.CallOption) (*ConnectionType, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ConnectionType{
		ServerResponse: googleapi.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 one connection type by ID.",
	//   "flatPath": "userprofiles/{profileId}/connectionTypes/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.connectionTypes.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Connection type ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/connectionTypes/{id}",
	//   "response": {
	//     "$ref": "ConnectionType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.connectionTypes.list":

type ConnectionTypesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of connection types.
func (r *ConnectionTypesService) List(profileId int64) *ConnectionTypesListCall {
	c := &ConnectionTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ConnectionTypesListCall) Fields(s ...googleapi.Field) *ConnectionTypesListCall {
	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 *ConnectionTypesListCall) IfNoneMatch(entityTag string) *ConnectionTypesListCall {
	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 *ConnectionTypesListCall) Context(ctx context.Context) *ConnectionTypesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ConnectionTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ConnectionTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/connectionTypes")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.connectionTypes.list" call.
// Exactly one of *ConnectionTypesListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ConnectionTypesListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ConnectionTypesListCall) Do(opts ...googleapi.CallOption) (*ConnectionTypesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ConnectionTypesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of connection types.",
	//   "flatPath": "userprofiles/{profileId}/connectionTypes",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.connectionTypes.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/connectionTypes",
	//   "response": {
	//     "$ref": "ConnectionTypesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.delete":

type ContentCategoriesDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing content category.
func (r *ContentCategoriesService) Delete(profileId int64, id int64) *ContentCategoriesDeleteCall {
	c := &ContentCategoriesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesDeleteCall) Fields(s ...googleapi.Field) *ContentCategoriesDeleteCall {
	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 *ContentCategoriesDeleteCall) Context(ctx context.Context) *ContentCategoriesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/contentCategories/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.delete" call.
func (c *ContentCategoriesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing content category.",
	//   "flatPath": "userprofiles/{profileId}/contentCategories/{id}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.contentCategories.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Content category ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.get":

type ContentCategoriesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one content category by ID.
func (r *ContentCategoriesService) Get(profileId int64, id int64) *ContentCategoriesGetCall {
	c := &ContentCategoriesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesGetCall) Fields(s ...googleapi.Field) *ContentCategoriesGetCall {
	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 *ContentCategoriesGetCall) IfNoneMatch(entityTag string) *ContentCategoriesGetCall {
	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 *ContentCategoriesGetCall) Context(ctx context.Context) *ContentCategoriesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/contentCategories/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.get" call.
// Exactly one of *ContentCategory or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContentCategory.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesGetCall) Do(opts ...googleapi.CallOption) (*ContentCategory, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategory{
		ServerResponse: googleapi.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 one content category by ID.",
	//   "flatPath": "userprofiles/{profileId}/contentCategories/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.contentCategories.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Content category ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories/{id}",
	//   "response": {
	//     "$ref": "ContentCategory"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.insert":

type ContentCategoriesInsertCall struct {
	s               *Service
	profileId       int64
	contentcategory *ContentCategory
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Insert: Inserts a new content category.
func (r *ContentCategoriesService) Insert(profileId int64, contentcategory *ContentCategory) *ContentCategoriesInsertCall {
	c := &ContentCategoriesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.contentcategory = contentcategory
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesInsertCall) Fields(s ...googleapi.Field) *ContentCategoriesInsertCall {
	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 *ContentCategoriesInsertCall) Context(ctx context.Context) *ContentCategoriesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.contentcategory)
	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, "userprofiles/{profileId}/contentCategories")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.insert" call.
// Exactly one of *ContentCategory or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContentCategory.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesInsertCall) Do(opts ...googleapi.CallOption) (*ContentCategory, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategory{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new content category.",
	//   "flatPath": "userprofiles/{profileId}/contentCategories",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.contentCategories.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories",
	//   "request": {
	//     "$ref": "ContentCategory"
	//   },
	//   "response": {
	//     "$ref": "ContentCategory"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.list":

type ContentCategoriesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of content categories, possibly filtered. This
// method supports paging.
func (r *ContentCategoriesService) List(profileId int64) *ContentCategoriesListCall {
	c := &ContentCategoriesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only content categories
// with these IDs.
func (c *ContentCategoriesListCall) Ids(ids ...int64) *ContentCategoriesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ContentCategoriesListCall) MaxResults(maxResults int64) *ContentCategoriesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *ContentCategoriesListCall) PageToken(pageToken string) *ContentCategoriesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "contentcategory*2015" will return objects with names like
// "contentcategory June 2015", "contentcategory April 2015", or simply
// "contentcategory 2015". Most of the searches also add wildcards
// implicitly at the start and the end of the search string. For
// example, a search string of "contentcategory" will match objects with
// name "my contentcategory", "contentcategory 2015", or simply
// "contentcategory".
func (c *ContentCategoriesListCall) SearchString(searchString string) *ContentCategoriesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *ContentCategoriesListCall) SortField(sortField string) *ContentCategoriesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *ContentCategoriesListCall) SortOrder(sortOrder string) *ContentCategoriesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesListCall) Fields(s ...googleapi.Field) *ContentCategoriesListCall {
	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 *ContentCategoriesListCall) IfNoneMatch(entityTag string) *ContentCategoriesListCall {
	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 *ContentCategoriesListCall) Context(ctx context.Context) *ContentCategoriesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/contentCategories")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.list" call.
// Exactly one of *ContentCategoriesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ContentCategoriesListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesListCall) Do(opts ...googleapi.CallOption) (*ContentCategoriesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategoriesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of content categories, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/contentCategories",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.contentCategories.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only content categories with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"contentcategory*2015\" will return objects with names like \"contentcategory June 2015\", \"contentcategory April 2015\", or simply \"contentcategory 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"contentcategory\" will match objects with name \"my contentcategory\", \"contentcategory 2015\", or simply \"contentcategory\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories",
	//   "response": {
	//     "$ref": "ContentCategoriesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *ContentCategoriesListCall) Pages(ctx context.Context, f func(*ContentCategoriesListResponse) 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 "dfareporting.contentCategories.patch":

type ContentCategoriesPatchCall struct {
	s               *Service
	profileId       int64
	contentcategory *ContentCategory
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Patch: Updates an existing content category. This method supports
// patch semantics.
func (r *ContentCategoriesService) Patch(profileId int64, contentcategory *ContentCategory) *ContentCategoriesPatchCall {
	c := &ContentCategoriesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.contentcategory = contentcategory
	return c
}

// Id sets the optional parameter "id": ContentCategory ID.
func (c *ContentCategoriesPatchCall) Id(id int64) *ContentCategoriesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesPatchCall) Fields(s ...googleapi.Field) *ContentCategoriesPatchCall {
	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 *ContentCategoriesPatchCall) Context(ctx context.Context) *ContentCategoriesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.contentcategory)
	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, "userprofiles/{profileId}/contentCategories")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.patch" call.
// Exactly one of *ContentCategory or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContentCategory.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesPatchCall) Do(opts ...googleapi.CallOption) (*ContentCategory, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategory{
		ServerResponse: googleapi.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 content category. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/contentCategories",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.contentCategories.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "ContentCategory ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories",
	//   "request": {
	//     "$ref": "ContentCategory"
	//   },
	//   "response": {
	//     "$ref": "ContentCategory"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.update":

type ContentCategoriesUpdateCall struct {
	s               *Service
	profileId       int64
	contentcategory *ContentCategory
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Update: Updates an existing content category.
func (r *ContentCategoriesService) Update(profileId int64, contentcategory *ContentCategory) *ContentCategoriesUpdateCall {
	c := &ContentCategoriesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.contentcategory = contentcategory
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesUpdateCall) Fields(s ...googleapi.Field) *ContentCategoriesUpdateCall {
	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 *ContentCategoriesUpdateCall) Context(ctx context.Context) *ContentCategoriesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.contentcategory)
	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, "userprofiles/{profileId}/contentCategories")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.update" call.
// Exactly one of *ContentCategory or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContentCategory.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesUpdateCall) Do(opts ...googleapi.CallOption) (*ContentCategory, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategory{
		ServerResponse: googleapi.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 content category.",
	//   "flatPath": "userprofiles/{profileId}/contentCategories",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.contentCategories.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories",
	//   "request": {
	//     "$ref": "ContentCategory"
	//   },
	//   "response": {
	//     "$ref": "ContentCategory"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.conversions.batchinsert":

type ConversionsBatchinsertCall struct {
	s                             *Service
	profileId                     int64
	conversionsbatchinsertrequest *ConversionsBatchInsertRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Batchinsert: Inserts conversions.
func (r *ConversionsService) Batchinsert(profileId int64, conversionsbatchinsertrequest *ConversionsBatchInsertRequest) *ConversionsBatchinsertCall {
	c := &ConversionsBatchinsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.conversionsbatchinsertrequest = conversionsbatchinsertrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ConversionsBatchinsertCall) Fields(s ...googleapi.Field) *ConversionsBatchinsertCall {
	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 *ConversionsBatchinsertCall) Context(ctx context.Context) *ConversionsBatchinsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ConversionsBatchinsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ConversionsBatchinsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.conversionsbatchinsertrequest)
	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, "userprofiles/{profileId}/conversions/batchinsert")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.conversions.batchinsert" call.
// Exactly one of *ConversionsBatchInsertResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ConversionsBatchInsertResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ConversionsBatchinsertCall) Do(opts ...googleapi.CallOption) (*ConversionsBatchInsertResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ConversionsBatchInsertResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts conversions.",
	//   "flatPath": "userprofiles/{profileId}/conversions/batchinsert",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.conversions.batchinsert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/conversions/batchinsert",
	//   "request": {
	//     "$ref": "ConversionsBatchInsertRequest"
	//   },
	//   "response": {
	//     "$ref": "ConversionsBatchInsertResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/ddmconversions"
	//   ]
	// }

}

// method id "dfareporting.conversions.batchupdate":

type ConversionsBatchupdateCall struct {
	s                             *Service
	profileId                     int64
	conversionsbatchupdaterequest *ConversionsBatchUpdateRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Batchupdate: Updates existing conversions.
func (r *ConversionsService) Batchupdate(profileId int64, conversionsbatchupdaterequest *ConversionsBatchUpdateRequest) *ConversionsBatchupdateCall {
	c := &ConversionsBatchupdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.conversionsbatchupdaterequest = conversionsbatchupdaterequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ConversionsBatchupdateCall) Fields(s ...googleapi.Field) *ConversionsBatchupdateCall {
	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 *ConversionsBatchupdateCall) Context(ctx context.Context) *ConversionsBatchupdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ConversionsBatchupdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ConversionsBatchupdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.conversionsbatchupdaterequest)
	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, "userprofiles/{profileId}/conversions/batchupdate")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.conversions.batchupdate" call.
// Exactly one of *ConversionsBatchUpdateResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ConversionsBatchUpdateResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ConversionsBatchupdateCall) Do(opts ...googleapi.CallOption) (*ConversionsBatchUpdateResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ConversionsBatchUpdateResponse{
		ServerResponse: googleapi.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 existing conversions.",
	//   "flatPath": "userprofiles/{profileId}/conversions/batchupdate",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.conversions.batchupdate",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/conversions/batchupdate",
	//   "request": {
	//     "$ref": "ConversionsBatchUpdateRequest"
	//   },
	//   "response": {
	//     "$ref": "ConversionsBatchUpdateResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/ddmconversions"
	//   ]
	// }

}

// method id "dfareporting.countries.get":

type CountriesGetCall struct {
	s            *Service
	profileId    int64
	dartId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one country by ID.
func (r *CountriesService) Get(profileId int64, dartId int64) *CountriesGetCall {
	c := &CountriesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.dartId = dartId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CountriesGetCall) Fields(s ...googleapi.Field) *CountriesGetCall {
	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 *CountriesGetCall) IfNoneMatch(entityTag string) *CountriesGetCall {
	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 *CountriesGetCall) Context(ctx context.Context) *CountriesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CountriesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CountriesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/countries/{dartId}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"dartId":    strconv.FormatInt(c.dartId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.countries.get" call.
// Exactly one of *Country or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Country.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *CountriesGetCall) Do(opts ...googleapi.CallOption) (*Country, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Country{
		ServerResponse: googleapi.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 one country by ID.",
	//   "flatPath": "userprofiles/{profileId}/countries/{dartId}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.countries.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "dartId"
	//   ],
	//   "parameters": {
	//     "dartId": {
	//       "description": "Country DART ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/countries/{dartId}",
	//   "response": {
	//     "$ref": "Country"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.countries.list":

type CountriesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of countries.
func (r *CountriesService) List(profileId int64) *CountriesListCall {
	c := &CountriesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CountriesListCall) Fields(s ...googleapi.Field) *CountriesListCall {
	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 *CountriesListCall) IfNoneMatch(entityTag string) *CountriesListCall {
	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 *CountriesListCall) Context(ctx context.Context) *CountriesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CountriesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CountriesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/countries")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.countries.list" call.
// Exactly one of *CountriesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CountriesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CountriesListCall) Do(opts ...googleapi.CallOption) (*CountriesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CountriesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of countries.",
	//   "flatPath": "userprofiles/{profileId}/countries",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.countries.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/countries",
	//   "response": {
	//     "$ref": "CountriesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeAssets.insert":

type CreativeAssetsInsertCall struct {
	s                     *Service
	profileId             int64
	advertiserId          int64
	creativeassetmetadata *CreativeAssetMetadata
	urlParams_            gensupport.URLParams
	mediaInfo_            *gensupport.MediaInfo
	ctx_                  context.Context
	header_               http.Header
}

// Insert: Inserts a new creative asset.
func (r *CreativeAssetsService) Insert(profileId int64, advertiserId int64, creativeassetmetadata *CreativeAssetMetadata) *CreativeAssetsInsertCall {
	c := &CreativeAssetsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertiserId = advertiserId
	c.creativeassetmetadata = creativeassetmetadata
	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 *CreativeAssetsInsertCall) Media(r io.Reader, options ...googleapi.MediaOption) *CreativeAssetsInsertCall {
	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 *CreativeAssetsInsertCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *CreativeAssetsInsertCall {
	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 *CreativeAssetsInsertCall) ProgressUpdater(pu googleapi.ProgressUpdater) *CreativeAssetsInsertCall {
	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 *CreativeAssetsInsertCall) Fields(s ...googleapi.Field) *CreativeAssetsInsertCall {
	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 *CreativeAssetsInsertCall) Context(ctx context.Context) *CreativeAssetsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeAssetsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeAssetsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativeassetmetadata)
	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, "userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/dfareporting/v3.4/userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets")
		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{
		"profileId":    strconv.FormatInt(c.profileId, 10),
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeAssets.insert" call.
// Exactly one of *CreativeAssetMetadata or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeAssetMetadata.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeAssetsInsertCall) Do(opts ...googleapi.CallOption) (*CreativeAssetMetadata, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.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 := &CreativeAssetMetadata{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative asset.",
	//   "flatPath": "userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creativeAssets.insert",
	//   "mediaUpload": {
	//     "accept": [
	//       "*/*"
	//     ],
	//     "maxSize": "1073741824",
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/dfareporting/v3.4/userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "profileId",
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Advertiser ID of this creative. This is a required field.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets",
	//   "request": {
	//     "$ref": "CreativeAssetMetadata"
	//   },
	//   "response": {
	//     "$ref": "CreativeAssetMetadata"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "dfareporting.creativeFieldValues.delete":

type CreativeFieldValuesDeleteCall struct {
	s               *Service
	profileId       int64
	creativeFieldId int64
	id              int64
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Delete: Deletes an existing creative field value.
func (r *CreativeFieldValuesService) Delete(profileId int64, creativeFieldId int64, id int64) *CreativeFieldValuesDeleteCall {
	c := &CreativeFieldValuesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesDeleteCall) Fields(s ...googleapi.Field) *CreativeFieldValuesDeleteCall {
	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 *CreativeFieldValuesDeleteCall) Context(ctx context.Context) *CreativeFieldValuesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}")
	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{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
		"id":              strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.delete" call.
func (c *CreativeFieldValuesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing creative field value.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.creativeFieldValues.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Creative Field Value ID",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFieldValues.get":

type CreativeFieldValuesGetCall struct {
	s               *Service
	profileId       int64
	creativeFieldId int64
	id              int64
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
	header_         http.Header
}

// Get: Gets one creative field value by ID.
func (r *CreativeFieldValuesService) Get(profileId int64, creativeFieldId int64, id int64) *CreativeFieldValuesGetCall {
	c := &CreativeFieldValuesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesGetCall) Fields(s ...googleapi.Field) *CreativeFieldValuesGetCall {
	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 *CreativeFieldValuesGetCall) IfNoneMatch(entityTag string) *CreativeFieldValuesGetCall {
	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 *CreativeFieldValuesGetCall) Context(ctx context.Context) *CreativeFieldValuesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}")
	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{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
		"id":              strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.get" call.
// Exactly one of *CreativeFieldValue or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeFieldValue.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesGetCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValue, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValue{
		ServerResponse: googleapi.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 one creative field value by ID.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeFieldValues.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Creative Field Value ID",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}",
	//   "response": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFieldValues.insert":

type CreativeFieldValuesInsertCall struct {
	s                  *Service
	profileId          int64
	creativeFieldId    int64
	creativefieldvalue *CreativeFieldValue
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Insert: Inserts a new creative field value.
func (r *CreativeFieldValuesService) Insert(profileId int64, creativeFieldId int64, creativefieldvalue *CreativeFieldValue) *CreativeFieldValuesInsertCall {
	c := &CreativeFieldValuesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.creativefieldvalue = creativefieldvalue
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesInsertCall) Fields(s ...googleapi.Field) *CreativeFieldValuesInsertCall {
	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 *CreativeFieldValuesInsertCall) Context(ctx context.Context) *CreativeFieldValuesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativefieldvalue)
	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, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues")
	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{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.insert" call.
// Exactly one of *CreativeFieldValue or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeFieldValue.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesInsertCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValue, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValue{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative field value.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creativeFieldValues.insert",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "request": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "response": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFieldValues.list":

type CreativeFieldValuesListCall struct {
	s               *Service
	profileId       int64
	creativeFieldId int64
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
	header_         http.Header
}

// List: Retrieves a list of creative field values, possibly filtered.
// This method supports paging.
func (r *CreativeFieldValuesService) List(profileId int64, creativeFieldId int64) *CreativeFieldValuesListCall {
	c := &CreativeFieldValuesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	return c
}

// Ids sets the optional parameter "ids": Select only creative field
// values with these IDs.
func (c *CreativeFieldValuesListCall) Ids(ids ...int64) *CreativeFieldValuesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CreativeFieldValuesListCall) MaxResults(maxResults int64) *CreativeFieldValuesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CreativeFieldValuesListCall) PageToken(pageToken string) *CreativeFieldValuesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for creative field values by their values. Wildcards (e.g.
// *) are not allowed.
func (c *CreativeFieldValuesListCall) SearchString(searchString string) *CreativeFieldValuesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "VALUE"
func (c *CreativeFieldValuesListCall) SortField(sortField string) *CreativeFieldValuesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *CreativeFieldValuesListCall) SortOrder(sortOrder string) *CreativeFieldValuesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesListCall) Fields(s ...googleapi.Field) *CreativeFieldValuesListCall {
	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 *CreativeFieldValuesListCall) IfNoneMatch(entityTag string) *CreativeFieldValuesListCall {
	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 *CreativeFieldValuesListCall) Context(ctx context.Context) *CreativeFieldValuesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues")
	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{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.list" call.
// Exactly one of *CreativeFieldValuesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *CreativeFieldValuesListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesListCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValuesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValuesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative field values, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeFieldValues.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only creative field values with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for creative field values by their values. Wildcards (e.g. *) are not allowed.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "VALUE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "response": {
	//     "$ref": "CreativeFieldValuesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *CreativeFieldValuesListCall) Pages(ctx context.Context, f func(*CreativeFieldValuesListResponse) 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 "dfareporting.creativeFieldValues.patch":

type CreativeFieldValuesPatchCall struct {
	s                  *Service
	profileId          int64
	creativeFieldId    int64
	creativefieldvalue *CreativeFieldValue
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Patch: Updates an existing creative field value. This method supports
// patch semantics.
func (r *CreativeFieldValuesService) Patch(profileId int64, creativeFieldId int64, creativefieldvalue *CreativeFieldValue) *CreativeFieldValuesPatchCall {
	c := &CreativeFieldValuesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.creativefieldvalue = creativefieldvalue
	return c
}

// Id sets the optional parameter "id": CreativeFieldValue ID.
func (c *CreativeFieldValuesPatchCall) Id(id int64) *CreativeFieldValuesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesPatchCall) Fields(s ...googleapi.Field) *CreativeFieldValuesPatchCall {
	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 *CreativeFieldValuesPatchCall) Context(ctx context.Context) *CreativeFieldValuesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativefieldvalue)
	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, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues")
	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{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.patch" call.
// Exactly one of *CreativeFieldValue or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeFieldValue.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesPatchCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValue, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValue{
		ServerResponse: googleapi.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 field value. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.creativeFieldValues.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "CreativeField ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "CreativeFieldValue ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "request": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "response": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFieldValues.update":

type CreativeFieldValuesUpdateCall struct {
	s                  *Service
	profileId          int64
	creativeFieldId    int64
	creativefieldvalue *CreativeFieldValue
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Update: Updates an existing creative field value.
func (r *CreativeFieldValuesService) Update(profileId int64, creativeFieldId int64, creativefieldvalue *CreativeFieldValue) *CreativeFieldValuesUpdateCall {
	c := &CreativeFieldValuesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.creativefieldvalue = creativefieldvalue
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesUpdateCall) Fields(s ...googleapi.Field) *CreativeFieldValuesUpdateCall {
	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 *CreativeFieldValuesUpdateCall) Context(ctx context.Context) *CreativeFieldValuesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativefieldvalue)
	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, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.update" call.
// Exactly one of *CreativeFieldValue or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeFieldValue.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesUpdateCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValue, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValue{
		ServerResponse: googleapi.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 field value.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.creativeFieldValues.update",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "request": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "response": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.delete":

type CreativeFieldsDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing creative field.
func (r *CreativeFieldsService) Delete(profileId int64, id int64) *CreativeFieldsDeleteCall {
	c := &CreativeFieldsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsDeleteCall) Fields(s ...googleapi.Field) *CreativeFieldsDeleteCall {
	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 *CreativeFieldsDeleteCall) Context(ctx context.Context) *CreativeFieldsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creativeFields/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.delete" call.
func (c *CreativeFieldsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing creative field.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields/{id}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.creativeFields.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative Field ID",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.get":

type CreativeFieldsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one creative field by ID.
func (r *CreativeFieldsService) Get(profileId int64, id int64) *CreativeFieldsGetCall {
	c := &CreativeFieldsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsGetCall) Fields(s ...googleapi.Field) *CreativeFieldsGetCall {
	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 *CreativeFieldsGetCall) IfNoneMatch(entityTag string) *CreativeFieldsGetCall {
	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 *CreativeFieldsGetCall) Context(ctx context.Context) *CreativeFieldsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creativeFields/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.get" call.
// Exactly one of *CreativeField or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeField.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsGetCall) Do(opts ...googleapi.CallOption) (*CreativeField, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeField{
		ServerResponse: googleapi.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 one creative field by ID.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeFields.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative Field ID",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{id}",
	//   "response": {
	//     "$ref": "CreativeField"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.insert":

type CreativeFieldsInsertCall struct {
	s             *Service
	profileId     int64
	creativefield *CreativeField
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Insert: Inserts a new creative field.
func (r *CreativeFieldsService) Insert(profileId int64, creativefield *CreativeField) *CreativeFieldsInsertCall {
	c := &CreativeFieldsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativefield = creativefield
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsInsertCall) Fields(s ...googleapi.Field) *CreativeFieldsInsertCall {
	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 *CreativeFieldsInsertCall) Context(ctx context.Context) *CreativeFieldsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativefield)
	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, "userprofiles/{profileId}/creativeFields")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.insert" call.
// Exactly one of *CreativeField or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeField.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsInsertCall) Do(opts ...googleapi.CallOption) (*CreativeField, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeField{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative field.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creativeFields.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields",
	//   "request": {
	//     "$ref": "CreativeField"
	//   },
	//   "response": {
	//     "$ref": "CreativeField"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.list":

type CreativeFieldsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of creative fields, possibly filtered. This
// method supports paging.
func (r *CreativeFieldsService) List(profileId int64) *CreativeFieldsListCall {
	c := &CreativeFieldsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only creative fields that belong to these advertisers.
func (c *CreativeFieldsListCall) AdvertiserIds(advertiserIds ...int64) *CreativeFieldsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only creative fields
// with these IDs.
func (c *CreativeFieldsListCall) Ids(ids ...int64) *CreativeFieldsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CreativeFieldsListCall) MaxResults(maxResults int64) *CreativeFieldsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CreativeFieldsListCall) PageToken(pageToken string) *CreativeFieldsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for creative fields by name or ID. Wildcards (*) are
// allowed. For example, "creativefield*2015" will return creative
// fields with names like "creativefield June 2015", "creativefield
// April 2015", or simply "creativefield 2015". Most of the searches
// also add wild-cards implicitly at the start and the end of the search
// string. For example, a search string of "creativefield" will match
// creative fields with the name "my creativefield", "creativefield
// 2015", or simply "creativefield".
func (c *CreativeFieldsListCall) SearchString(searchString string) *CreativeFieldsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *CreativeFieldsListCall) SortField(sortField string) *CreativeFieldsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *CreativeFieldsListCall) SortOrder(sortOrder string) *CreativeFieldsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsListCall) Fields(s ...googleapi.Field) *CreativeFieldsListCall {
	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 *CreativeFieldsListCall) IfNoneMatch(entityTag string) *CreativeFieldsListCall {
	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 *CreativeFieldsListCall) Context(ctx context.Context) *CreativeFieldsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creativeFields")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.list" call.
// Exactly one of *CreativeFieldsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CreativeFieldsListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsListCall) Do(opts ...googleapi.CallOption) (*CreativeFieldsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative fields, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeFields.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only creative fields that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only creative fields with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for creative fields by name or ID. Wildcards (*) are allowed. For example, \"creativefield*2015\" will return creative fields with names like \"creativefield June 2015\", \"creativefield April 2015\", or simply \"creativefield 2015\". Most of the searches also add wild-cards implicitly at the start and the end of the search string. For example, a search string of \"creativefield\" will match creative fields with the name \"my creativefield\", \"creativefield 2015\", or simply \"creativefield\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields",
	//   "response": {
	//     "$ref": "CreativeFieldsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *CreativeFieldsListCall) Pages(ctx context.Context, f func(*CreativeFieldsListResponse) 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 "dfareporting.creativeFields.patch":

type CreativeFieldsPatchCall struct {
	s             *Service
	profileId     int64
	creativefield *CreativeField
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Patch: Updates an existing creative field. This method supports patch
// semantics.
func (r *CreativeFieldsService) Patch(profileId int64, creativefield *CreativeField) *CreativeFieldsPatchCall {
	c := &CreativeFieldsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativefield = creativefield
	return c
}

// Id sets the optional parameter "id": CreativeField ID.
func (c *CreativeFieldsPatchCall) Id(id int64) *CreativeFieldsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsPatchCall) Fields(s ...googleapi.Field) *CreativeFieldsPatchCall {
	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 *CreativeFieldsPatchCall) Context(ctx context.Context) *CreativeFieldsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativefield)
	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, "userprofiles/{profileId}/creativeFields")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.patch" call.
// Exactly one of *CreativeField or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeField.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsPatchCall) Do(opts ...googleapi.CallOption) (*CreativeField, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeField{
		ServerResponse: googleapi.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 field. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.creativeFields.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "CreativeField ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields",
	//   "request": {
	//     "$ref": "CreativeField"
	//   },
	//   "response": {
	//     "$ref": "CreativeField"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.update":

type CreativeFieldsUpdateCall struct {
	s             *Service
	profileId     int64
	creativefield *CreativeField
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Updates an existing creative field.
func (r *CreativeFieldsService) Update(profileId int64, creativefield *CreativeField) *CreativeFieldsUpdateCall {
	c := &CreativeFieldsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativefield = creativefield
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsUpdateCall) Fields(s ...googleapi.Field) *CreativeFieldsUpdateCall {
	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 *CreativeFieldsUpdateCall) Context(ctx context.Context) *CreativeFieldsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativefield)
	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, "userprofiles/{profileId}/creativeFields")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.update" call.
// Exactly one of *CreativeField or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeField.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsUpdateCall) Do(opts ...googleapi.CallOption) (*CreativeField, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeField{
		ServerResponse: googleapi.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 field.",
	//   "flatPath": "userprofiles/{profileId}/creativeFields",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.creativeFields.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields",
	//   "request": {
	//     "$ref": "CreativeField"
	//   },
	//   "response": {
	//     "$ref": "CreativeField"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeGroups.get":

type CreativeGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one creative group by ID.
func (r *CreativeGroupsService) Get(profileId int64, id int64) *CreativeGroupsGetCall {
	c := &CreativeGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsGetCall) Fields(s ...googleapi.Field) *CreativeGroupsGetCall {
	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 *CreativeGroupsGetCall) IfNoneMatch(entityTag string) *CreativeGroupsGetCall {
	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 *CreativeGroupsGetCall) Context(ctx context.Context) *CreativeGroupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creativeGroups/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.get" call.
// Exactly one of *CreativeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsGetCall) Do(opts ...googleapi.CallOption) (*CreativeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroup{
		ServerResponse: googleapi.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 one creative group by ID.",
	//   "flatPath": "userprofiles/{profileId}/creativeGroups/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups/{id}",
	//   "response": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeGroups.insert":

type CreativeGroupsInsertCall struct {
	s             *Service
	profileId     int64
	creativegroup *CreativeGroup
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Insert: Inserts a new creative group.
func (r *CreativeGroupsService) Insert(profileId int64, creativegroup *CreativeGroup) *CreativeGroupsInsertCall {
	c := &CreativeGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativegroup = creativegroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsInsertCall) Fields(s ...googleapi.Field) *CreativeGroupsInsertCall {
	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 *CreativeGroupsInsertCall) Context(ctx context.Context) *CreativeGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativegroup)
	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, "userprofiles/{profileId}/creativeGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.insert" call.
// Exactly one of *CreativeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsInsertCall) Do(opts ...googleapi.CallOption) (*CreativeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative group.",
	//   "flatPath": "userprofiles/{profileId}/creativeGroups",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creativeGroups.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups",
	//   "request": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "response": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeGroups.list":

type CreativeGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of creative groups, possibly filtered. This
// method supports paging.
func (r *CreativeGroupsService) List(profileId int64) *CreativeGroupsListCall {
	c := &CreativeGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only creative groups that belong to these advertisers.
func (c *CreativeGroupsListCall) AdvertiserIds(advertiserIds ...int64) *CreativeGroupsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// GroupNumber sets the optional parameter "groupNumber": Select only
// creative groups that belong to this subgroup.
func (c *CreativeGroupsListCall) GroupNumber(groupNumber int64) *CreativeGroupsListCall {
	c.urlParams_.Set("groupNumber", fmt.Sprint(groupNumber))
	return c
}

// Ids sets the optional parameter "ids": Select only creative groups
// with these IDs.
func (c *CreativeGroupsListCall) Ids(ids ...int64) *CreativeGroupsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CreativeGroupsListCall) MaxResults(maxResults int64) *CreativeGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CreativeGroupsListCall) PageToken(pageToken string) *CreativeGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for creative groups by name or ID. Wildcards (*) are
// allowed. For example, "creativegroup*2015" will return creative
// groups with names like "creativegroup June 2015", "creativegroup
// April 2015", or simply "creativegroup 2015". Most of the searches
// also add wild-cards implicitly at the start and the end of the search
// string. For example, a search string of "creativegroup" will match
// creative groups with the name "my creativegroup", "creativegroup
// 2015", or simply "creativegroup".
func (c *CreativeGroupsListCall) SearchString(searchString string) *CreativeGroupsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *CreativeGroupsListCall) SortField(sortField string) *CreativeGroupsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *CreativeGroupsListCall) SortOrder(sortOrder string) *CreativeGroupsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsListCall) Fields(s ...googleapi.Field) *CreativeGroupsListCall {
	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 *CreativeGroupsListCall) IfNoneMatch(entityTag string) *CreativeGroupsListCall {
	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 *CreativeGroupsListCall) Context(ctx context.Context) *CreativeGroupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creativeGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.list" call.
// Exactly one of *CreativeGroupsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CreativeGroupsListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsListCall) Do(opts ...googleapi.CallOption) (*CreativeGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative groups, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/creativeGroups",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only creative groups that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "groupNumber": {
	//       "description": "Select only creative groups that belong to this subgroup.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "2",
	//       "minimum": "1",
	//       "type": "integer"
	//     },
	//     "ids": {
	//       "description": "Select only creative groups with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for creative groups by name or ID. Wildcards (*) are allowed. For example, \"creativegroup*2015\" will return creative groups with names like \"creativegroup June 2015\", \"creativegroup April 2015\", or simply \"creativegroup 2015\". Most of the searches also add wild-cards implicitly at the start and the end of the search string. For example, a search string of \"creativegroup\" will match creative groups with the name \"my creativegroup\", \"creativegroup 2015\", or simply \"creativegroup\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups",
	//   "response": {
	//     "$ref": "CreativeGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *CreativeGroupsListCall) Pages(ctx context.Context, f func(*CreativeGroupsListResponse) 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 "dfareporting.creativeGroups.patch":

type CreativeGroupsPatchCall struct {
	s             *Service
	profileId     int64
	creativegroup *CreativeGroup
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Patch: Updates an existing creative group. This method supports patch
// semantics.
func (r *CreativeGroupsService) Patch(profileId int64, creativegroup *CreativeGroup) *CreativeGroupsPatchCall {
	c := &CreativeGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativegroup = creativegroup
	return c
}

// Id sets the optional parameter "id": CreativeGroup ID.
func (c *CreativeGroupsPatchCall) Id(id int64) *CreativeGroupsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsPatchCall) Fields(s ...googleapi.Field) *CreativeGroupsPatchCall {
	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 *CreativeGroupsPatchCall) Context(ctx context.Context) *CreativeGroupsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativegroup)
	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, "userprofiles/{profileId}/creativeGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.patch" call.
// Exactly one of *CreativeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsPatchCall) Do(opts ...googleapi.CallOption) (*CreativeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroup{
		ServerResponse: googleapi.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 group. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/creativeGroups",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.creativeGroups.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "CreativeGroup ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups",
	//   "request": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "response": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeGroups.update":

type CreativeGroupsUpdateCall struct {
	s             *Service
	profileId     int64
	creativegroup *CreativeGroup
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Updates an existing creative group.
func (r *CreativeGroupsService) Update(profileId int64, creativegroup *CreativeGroup) *CreativeGroupsUpdateCall {
	c := &CreativeGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativegroup = creativegroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsUpdateCall) Fields(s ...googleapi.Field) *CreativeGroupsUpdateCall {
	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 *CreativeGroupsUpdateCall) Context(ctx context.Context) *CreativeGroupsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.creativegroup)
	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, "userprofiles/{profileId}/creativeGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.update" call.
// Exactly one of *CreativeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*CreativeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroup{
		ServerResponse: googleapi.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 group.",
	//   "flatPath": "userprofiles/{profileId}/creativeGroups",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.creativeGroups.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups",
	//   "request": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "response": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creatives.get":

type CreativesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one creative by ID.
func (r *CreativesService) Get(profileId int64, id int64) *CreativesGetCall {
	c := &CreativesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativesGetCall) Fields(s ...googleapi.Field) *CreativesGetCall {
	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 *CreativesGetCall) IfNoneMatch(entityTag string) *CreativesGetCall {
	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 *CreativesGetCall) Context(ctx context.Context) *CreativesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creatives/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.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 *CreativesGetCall) 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 one creative by ID.",
	//   "flatPath": "userprofiles/{profileId}/creatives/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creatives.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives/{id}",
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creatives.insert":

type CreativesInsertCall struct {
	s          *Service
	profileId  int64
	creative   *Creative
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new creative.
func (r *CreativesService) Insert(profileId int64, creative *Creative) *CreativesInsertCall {
	c := &CreativesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	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 *CreativesInsertCall) Fields(s ...googleapi.Field) *CreativesInsertCall {
	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 *CreativesInsertCall) Context(ctx context.Context) *CreativesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creatives.insert" 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 *CreativesInsertCall) 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": "Inserts a new creative.",
	//   "flatPath": "userprofiles/{profileId}/creatives",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creatives.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creatives.list":

type CreativesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of creatives, possibly filtered. This method
// supports paging.
func (r *CreativesService) List(profileId int64) *CreativesListCall {
	c := &CreativesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Active sets the optional parameter "active": Select only active
// creatives. Leave blank to select active and inactive creatives.
func (c *CreativesListCall) Active(active bool) *CreativesListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// creatives with this advertiser ID.
func (c *CreativesListCall) AdvertiserId(advertiserId int64) *CreativesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// creatives. Leave blank to select archived and unarchived creatives.
func (c *CreativesListCall) Archived(archived bool) *CreativesListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// CampaignId sets the optional parameter "campaignId": Select only
// creatives with this campaign ID.
func (c *CreativesListCall) CampaignId(campaignId int64) *CreativesListCall {
	c.urlParams_.Set("campaignId", fmt.Sprint(campaignId))
	return c
}

// CompanionCreativeIds sets the optional parameter
// "companionCreativeIds": Select only in-stream video creatives with
// these companion IDs.
func (c *CreativesListCall) CompanionCreativeIds(companionCreativeIds ...int64) *CreativesListCall {
	var companionCreativeIds_ []string
	for _, v := range companionCreativeIds {
		companionCreativeIds_ = append(companionCreativeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("companionCreativeIds", companionCreativeIds_)
	return c
}

// CreativeFieldIds sets the optional parameter "creativeFieldIds":
// Select only creatives with these creative field IDs.
func (c *CreativesListCall) CreativeFieldIds(creativeFieldIds ...int64) *CreativesListCall {
	var creativeFieldIds_ []string
	for _, v := range creativeFieldIds {
		creativeFieldIds_ = append(creativeFieldIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("creativeFieldIds", creativeFieldIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only creatives with
// these IDs.
func (c *CreativesListCall) Ids(ids ...int64) *CreativesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CreativesListCall) MaxResults(maxResults int64) *CreativesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CreativesListCall) PageToken(pageToken string) *CreativesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RenderingIds sets the optional parameter "renderingIds": Select only
// creatives with these rendering IDs.
func (c *CreativesListCall) RenderingIds(renderingIds ...int64) *CreativesListCall {
	var renderingIds_ []string
	for _, v := range renderingIds {
		renderingIds_ = append(renderingIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("renderingIds", renderingIds_)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "creative*2015" will return objects with names like
// "creative June 2015", "creative April 2015", or simply "creative
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "creative" will match objects with name "my creative", "creative
// 2015", or simply "creative".
func (c *CreativesListCall) SearchString(searchString string) *CreativesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SizeIds sets the optional parameter "sizeIds": Select only creatives
// with these size IDs.
func (c *CreativesListCall) SizeIds(sizeIds ...int64) *CreativesListCall {
	var sizeIds_ []string
	for _, v := range sizeIds {
		sizeIds_ = append(sizeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("sizeIds", sizeIds_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *CreativesListCall) SortField(sortField string) *CreativesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *CreativesListCall) SortOrder(sortOrder string) *CreativesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// StudioCreativeId sets the optional parameter "studioCreativeId":
// Select only creatives corresponding to this Studio creative ID.
func (c *CreativesListCall) StudioCreativeId(studioCreativeId int64) *CreativesListCall {
	c.urlParams_.Set("studioCreativeId", fmt.Sprint(studioCreativeId))
	return c
}

// Types sets the optional parameter "types": Select only creatives with
// these creative types.
//
// Possible values:
//   "IMAGE"
//   "DISPLAY_REDIRECT"
//   "CUSTOM_DISPLAY"
//   "INTERNAL_REDIRECT"
//   "CUSTOM_DISPLAY_INTERSTITIAL"
//   "INTERSTITIAL_INTERNAL_REDIRECT"
//   "TRACKING_TEXT"
//   "RICH_MEDIA_DISPLAY_BANNER"
//   "RICH_MEDIA_INPAGE_FLOATING"
//   "RICH_MEDIA_IM_EXPAND"
//   "RICH_MEDIA_DISPLAY_EXPANDING"
//   "RICH_MEDIA_DISPLAY_INTERSTITIAL"
//   "RICH_MEDIA_DISPLAY_MULTI_FLOATING_INTERSTITIAL"
//   "RICH_MEDIA_MOBILE_IN_APP"
//   "FLASH_INPAGE"
//   "INSTREAM_VIDEO"
//   "VPAID_LINEAR_VIDEO"
//   "VPAID_NON_LINEAR_VIDEO"
//   "INSTREAM_VIDEO_REDIRECT"
//   "RICH_MEDIA_PEEL_DOWN"
//   "HTML5_BANNER"
//   "DISPLAY"
//   "DISPLAY_IMAGE_GALLERY"
//   "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO"
//   "INSTREAM_AUDIO"
func (c *CreativesListCall) Types(types ...string) *CreativesListCall {
	c.urlParams_.SetMulti("types", append([]string{}, types...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativesListCall) Fields(s ...googleapi.Field) *CreativesListCall {
	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 *CreativesListCall) IfNoneMatch(entityTag string) *CreativesListCall {
	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 *CreativesListCall) Context(ctx context.Context) *CreativesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creatives.list" call.
// Exactly one of *CreativesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativesListCall) Do(opts ...googleapi.CallOption) (*CreativesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creatives, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/creatives",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creatives.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active creatives. Leave blank to select active and inactive creatives.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "advertiserId": {
	//       "description": "Select only creatives with this advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived creatives. Leave blank to select archived and unarchived creatives.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignId": {
	//       "description": "Select only creatives with this campaign ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "companionCreativeIds": {
	//       "description": "Select only in-stream video creatives with these companion IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "creativeFieldIds": {
	//       "description": "Select only creatives with these creative field IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only creatives with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "renderingIds": {
	//       "description": "Select only creatives with these rendering IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"creative*2015\" will return objects with names like \"creative June 2015\", \"creative April 2015\", or simply \"creative 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"creative\" will match objects with name \"my creative\", \"creative 2015\", or simply \"creative\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sizeIds": {
	//       "description": "Select only creatives with these size IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "studioCreativeId": {
	//       "description": "Select only creatives corresponding to this Studio creative ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "types": {
	//       "description": "Select only creatives with these creative types.",
	//       "enum": [
	//         "IMAGE",
	//         "DISPLAY_REDIRECT",
	//         "CUSTOM_DISPLAY",
	//         "INTERNAL_REDIRECT",
	//         "CUSTOM_DISPLAY_INTERSTITIAL",
	//         "INTERSTITIAL_INTERNAL_REDIRECT",
	//         "TRACKING_TEXT",
	//         "RICH_MEDIA_DISPLAY_BANNER",
	//         "RICH_MEDIA_INPAGE_FLOATING",
	//         "RICH_MEDIA_IM_EXPAND",
	//         "RICH_MEDIA_DISPLAY_EXPANDING",
	//         "RICH_MEDIA_DISPLAY_INTERSTITIAL",
	//         "RICH_MEDIA_DISPLAY_MULTI_FLOATING_INTERSTITIAL",
	//         "RICH_MEDIA_MOBILE_IN_APP",
	//         "FLASH_INPAGE",
	//         "INSTREAM_VIDEO",
	//         "VPAID_LINEAR_VIDEO",
	//         "VPAID_NON_LINEAR_VIDEO",
	//         "INSTREAM_VIDEO_REDIRECT",
	//         "RICH_MEDIA_PEEL_DOWN",
	//         "HTML5_BANNER",
	//         "DISPLAY",
	//         "DISPLAY_IMAGE_GALLERY",
	//         "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO",
	//         "INSTREAM_AUDIO"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives",
	//   "response": {
	//     "$ref": "CreativesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *CreativesListCall) Pages(ctx context.Context, f func(*CreativesListResponse) 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 "dfareporting.creatives.patch":

type CreativesPatchCall struct {
	s          *Service
	profileId  int64
	creative   *Creative
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing creative. This method supports patch
// semantics.
func (r *CreativesService) Patch(profileId int64, creative *Creative) *CreativesPatchCall {
	c := &CreativesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creative = creative
	return c
}

// Id sets the optional parameter "id": Creative ID.
func (c *CreativesPatchCall) Id(id int64) *CreativesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativesPatchCall) Fields(s ...googleapi.Field) *CreativesPatchCall {
	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 *CreativesPatchCall) Context(ctx context.Context) *CreativesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creatives")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.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 *CreativesPatchCall) 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. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/creatives",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.creatives.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creatives.update":

type CreativesUpdateCall struct {
	s          *Service
	profileId  int64
	creative   *Creative
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing creative.
func (r *CreativesService) Update(profileId int64, creative *Creative) *CreativesUpdateCall {
	c := &CreativesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	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 *CreativesUpdateCall) Fields(s ...googleapi.Field) *CreativesUpdateCall {
	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 *CreativesUpdateCall) Context(ctx context.Context) *CreativesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/creatives")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creatives.update" 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 *CreativesUpdateCall) 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.",
	//   "flatPath": "userprofiles/{profileId}/creatives",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.creatives.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.customEvents.batchinsert":

type CustomEventsBatchinsertCall struct {
	s                              *Service
	profileId                      int64
	customeventsbatchinsertrequest *CustomEventsBatchInsertRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Batchinsert: Inserts custom events.
func (r *CustomEventsService) Batchinsert(profileId int64, customeventsbatchinsertrequest *CustomEventsBatchInsertRequest) *CustomEventsBatchinsertCall {
	c := &CustomEventsBatchinsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.customeventsbatchinsertrequest = customeventsbatchinsertrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CustomEventsBatchinsertCall) Fields(s ...googleapi.Field) *CustomEventsBatchinsertCall {
	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 *CustomEventsBatchinsertCall) Context(ctx context.Context) *CustomEventsBatchinsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CustomEventsBatchinsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CustomEventsBatchinsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.customeventsbatchinsertrequest)
	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, "userprofiles/{profileId}/customEvents/batchinsert")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.customEvents.batchinsert" call.
// Exactly one of *CustomEventsBatchInsertResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *CustomEventsBatchInsertResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CustomEventsBatchinsertCall) Do(opts ...googleapi.CallOption) (*CustomEventsBatchInsertResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CustomEventsBatchInsertResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts custom events.",
	//   "flatPath": "userprofiles/{profileId}/customEvents/batchinsert",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.customEvents.batchinsert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/customEvents/batchinsert",
	//   "request": {
	//     "$ref": "CustomEventsBatchInsertRequest"
	//   },
	//   "response": {
	//     "$ref": "CustomEventsBatchInsertResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/ddmconversions"
	//   ]
	// }

}

// method id "dfareporting.dimensionValues.query":

type DimensionValuesQueryCall struct {
	s                     *Service
	profileId             int64
	dimensionvaluerequest *DimensionValueRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Query: Retrieves list of report dimension values for a list of
// filters.
func (r *DimensionValuesService) Query(profileId int64, dimensionvaluerequest *DimensionValueRequest) *DimensionValuesQueryCall {
	c := &DimensionValuesQueryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.dimensionvaluerequest = dimensionvaluerequest
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *DimensionValuesQueryCall) MaxResults(maxResults int64) *DimensionValuesQueryCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The value of the
// nextToken from the previous result page.
func (c *DimensionValuesQueryCall) PageToken(pageToken string) *DimensionValuesQueryCall {
	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 *DimensionValuesQueryCall) Fields(s ...googleapi.Field) *DimensionValuesQueryCall {
	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 *DimensionValuesQueryCall) Context(ctx context.Context) *DimensionValuesQueryCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DimensionValuesQueryCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DimensionValuesQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.dimensionvaluerequest)
	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, "userprofiles/{profileId}/dimensionvalues/query")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.dimensionValues.query" call.
// Exactly one of *DimensionValueList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DimensionValueList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DimensionValuesQueryCall) Do(opts ...googleapi.CallOption) (*DimensionValueList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DimensionValueList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves list of report dimension values for a list of filters.",
	//   "flatPath": "userprofiles/{profileId}/dimensionvalues/query",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.dimensionValues.query",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "default": "100",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "100",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value of the nextToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/dimensionvalues/query",
	//   "request": {
	//     "$ref": "DimensionValueRequest"
	//   },
	//   "response": {
	//     "$ref": "DimensionValueList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// 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 *DimensionValuesQueryCall) Pages(ctx context.Context, f func(*DimensionValueList) 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 "dfareporting.directorySites.get":

type DirectorySitesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one directory site by ID.
func (r *DirectorySitesService) Get(profileId int64, id int64) *DirectorySitesGetCall {
	c := &DirectorySitesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DirectorySitesGetCall) Fields(s ...googleapi.Field) *DirectorySitesGetCall {
	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 *DirectorySitesGetCall) IfNoneMatch(entityTag string) *DirectorySitesGetCall {
	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 *DirectorySitesGetCall) Context(ctx context.Context) *DirectorySitesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DirectorySitesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DirectorySitesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/directorySites/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.directorySites.get" call.
// Exactly one of *DirectorySite or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DirectorySite.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DirectorySitesGetCall) Do(opts ...googleapi.CallOption) (*DirectorySite, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DirectorySite{
		ServerResponse: googleapi.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 one directory site by ID.",
	//   "flatPath": "userprofiles/{profileId}/directorySites/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.directorySites.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Directory site ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/directorySites/{id}",
	//   "response": {
	//     "$ref": "DirectorySite"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.directorySites.insert":

type DirectorySitesInsertCall struct {
	s             *Service
	profileId     int64
	directorysite *DirectorySite
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Insert: Inserts a new directory site.
func (r *DirectorySitesService) Insert(profileId int64, directorysite *DirectorySite) *DirectorySitesInsertCall {
	c := &DirectorySitesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.directorysite = directorysite
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DirectorySitesInsertCall) Fields(s ...googleapi.Field) *DirectorySitesInsertCall {
	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 *DirectorySitesInsertCall) Context(ctx context.Context) *DirectorySitesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DirectorySitesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DirectorySitesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.directorysite)
	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, "userprofiles/{profileId}/directorySites")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.directorySites.insert" call.
// Exactly one of *DirectorySite or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DirectorySite.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DirectorySitesInsertCall) Do(opts ...googleapi.CallOption) (*DirectorySite, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DirectorySite{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new directory site.",
	//   "flatPath": "userprofiles/{profileId}/directorySites",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.directorySites.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/directorySites",
	//   "request": {
	//     "$ref": "DirectorySite"
	//   },
	//   "response": {
	//     "$ref": "DirectorySite"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.directorySites.list":

type DirectorySitesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of directory sites, possibly filtered. This
// method supports paging.
func (r *DirectorySitesService) List(profileId int64) *DirectorySitesListCall {
	c := &DirectorySitesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AcceptsInStreamVideoPlacements sets the optional parameter
// "acceptsInStreamVideoPlacements": This search filter is no longer
// supported and will have no effect on the results returned.
func (c *DirectorySitesListCall) AcceptsInStreamVideoPlacements(acceptsInStreamVideoPlacements bool) *DirectorySitesListCall {
	c.urlParams_.Set("acceptsInStreamVideoPlacements", fmt.Sprint(acceptsInStreamVideoPlacements))
	return c
}

// AcceptsInterstitialPlacements sets the optional parameter
// "acceptsInterstitialPlacements": This search filter is no longer
// supported and will have no effect on the results returned.
func (c *DirectorySitesListCall) AcceptsInterstitialPlacements(acceptsInterstitialPlacements bool) *DirectorySitesListCall {
	c.urlParams_.Set("acceptsInterstitialPlacements", fmt.Sprint(acceptsInterstitialPlacements))
	return c
}

// AcceptsPublisherPaidPlacements sets the optional parameter
// "acceptsPublisherPaidPlacements": Select only directory sites that
// accept publisher paid placements. This field can be left blank.
func (c *DirectorySitesListCall) AcceptsPublisherPaidPlacements(acceptsPublisherPaidPlacements bool) *DirectorySitesListCall {
	c.urlParams_.Set("acceptsPublisherPaidPlacements", fmt.Sprint(acceptsPublisherPaidPlacements))
	return c
}

// Active sets the optional parameter "active": Select only active
// directory sites. Leave blank to retrieve both active and inactive
// directory sites.
func (c *DirectorySitesListCall) Active(active bool) *DirectorySitesListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// DfpNetworkCode sets the optional parameter "dfpNetworkCode": Select
// only directory sites with this Ad Manager network code.
func (c *DirectorySitesListCall) DfpNetworkCode(dfpNetworkCode string) *DirectorySitesListCall {
	c.urlParams_.Set("dfpNetworkCode", dfpNetworkCode)
	return c
}

// Ids sets the optional parameter "ids": Select only directory sites
// with these IDs.
func (c *DirectorySitesListCall) Ids(ids ...int64) *DirectorySitesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *DirectorySitesListCall) MaxResults(maxResults int64) *DirectorySitesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *DirectorySitesListCall) PageToken(pageToken string) *DirectorySitesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name, ID or URL. Wildcards (*) are allowed.
// For example, "directory site*2015" will return objects with names
// like "directory site June 2015", "directory site April 2015", or
// simply "directory site 2015". Most of the searches also add wildcards
// implicitly at the start and the end of the search string. For
// example, a search string of "directory site" will match objects with
// name "my directory site", "directory site 2015" or simply, "directory
// site".
func (c *DirectorySitesListCall) SearchString(searchString string) *DirectorySitesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *DirectorySitesListCall) SortField(sortField string) *DirectorySitesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *DirectorySitesListCall) SortOrder(sortOrder string) *DirectorySitesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DirectorySitesListCall) Fields(s ...googleapi.Field) *DirectorySitesListCall {
	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 *DirectorySitesListCall) IfNoneMatch(entityTag string) *DirectorySitesListCall {
	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 *DirectorySitesListCall) Context(ctx context.Context) *DirectorySitesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DirectorySitesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DirectorySitesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/directorySites")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.directorySites.list" call.
// Exactly one of *DirectorySitesListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *DirectorySitesListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DirectorySitesListCall) Do(opts ...googleapi.CallOption) (*DirectorySitesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DirectorySitesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of directory sites, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/directorySites",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.directorySites.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "acceptsInStreamVideoPlacements": {
	//       "description": "This search filter is no longer supported and will have no effect on the results returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "acceptsInterstitialPlacements": {
	//       "description": "This search filter is no longer supported and will have no effect on the results returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "acceptsPublisherPaidPlacements": {
	//       "description": "Select only directory sites that accept publisher paid placements. This field can be left blank.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "active": {
	//       "description": "Select only active directory sites. Leave blank to retrieve both active and inactive directory sites.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "dfpNetworkCode": {
	//       "description": "Select only directory sites with this Ad Manager network code.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only directory sites with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name, ID or URL. Wildcards (*) are allowed. For example, \"directory site*2015\" will return objects with names like \"directory site June 2015\", \"directory site April 2015\", or simply \"directory site 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"directory site\" will match objects with name \"my directory site\", \"directory site 2015\" or simply, \"directory site\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/directorySites",
	//   "response": {
	//     "$ref": "DirectorySitesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *DirectorySitesListCall) Pages(ctx context.Context, f func(*DirectorySitesListResponse) 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 "dfareporting.dynamicTargetingKeys.delete":

type DynamicTargetingKeysDeleteCall struct {
	s          *Service
	profileId  int64
	objectId   int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing dynamic targeting key.
func (r *DynamicTargetingKeysService) Delete(profileId int64, objectId int64, name string, objectType string) *DynamicTargetingKeysDeleteCall {
	c := &DynamicTargetingKeysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.objectId = objectId
	c.urlParams_.Set("name", name)
	c.urlParams_.Set("objectType", objectType)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DynamicTargetingKeysDeleteCall) Fields(s ...googleapi.Field) *DynamicTargetingKeysDeleteCall {
	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 *DynamicTargetingKeysDeleteCall) Context(ctx context.Context) *DynamicTargetingKeysDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DynamicTargetingKeysDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DynamicTargetingKeysDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/dynamicTargetingKeys/{objectId}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"objectId":  strconv.FormatInt(c.objectId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.dynamicTargetingKeys.delete" call.
func (c *DynamicTargetingKeysDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing dynamic targeting key.",
	//   "flatPath": "userprofiles/{profileId}/dynamicTargetingKeys/{objectId}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.dynamicTargetingKeys.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "objectId",
	//     "name",
	//     "objectType"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of this dynamic targeting key. This is a required field. Must be less than 256 characters long and cannot contain commas. All characters are converted to lowercase.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "objectId": {
	//       "description": "ID of the object of this dynamic targeting key. This is a required field.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "objectType": {
	//       "description": "Type of the object of this dynamic targeting key. This is a required field.",
	//       "enum": [
	//         "OBJECT_ADVERTISER",
	//         "OBJECT_AD",
	//         "OBJECT_CREATIVE",
	//         "OBJECT_PLACEMENT"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/dynamicTargetingKeys/{objectId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.dynamicTargetingKeys.insert":

type DynamicTargetingKeysInsertCall struct {
	s                   *Service
	profileId           int64
	dynamictargetingkey *DynamicTargetingKey
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// Insert: Inserts a new dynamic targeting key. Keys must be created at
// the advertiser level before being assigned to the advertiser's ads,
// creatives, or placements. There is a maximum of 1000 keys per
// advertiser, out of which a maximum of 20 keys can be assigned per ad,
// creative, or placement.
func (r *DynamicTargetingKeysService) Insert(profileId int64, dynamictargetingkey *DynamicTargetingKey) *DynamicTargetingKeysInsertCall {
	c := &DynamicTargetingKeysInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.dynamictargetingkey = dynamictargetingkey
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DynamicTargetingKeysInsertCall) Fields(s ...googleapi.Field) *DynamicTargetingKeysInsertCall {
	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 *DynamicTargetingKeysInsertCall) Context(ctx context.Context) *DynamicTargetingKeysInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DynamicTargetingKeysInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DynamicTargetingKeysInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.dynamictargetingkey)
	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, "userprofiles/{profileId}/dynamicTargetingKeys")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.dynamicTargetingKeys.insert" call.
// Exactly one of *DynamicTargetingKey or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DynamicTargetingKey.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DynamicTargetingKeysInsertCall) Do(opts ...googleapi.CallOption) (*DynamicTargetingKey, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DynamicTargetingKey{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new dynamic targeting key. Keys must be created at the advertiser level before being assigned to the advertiser's ads, creatives, or placements. There is a maximum of 1000 keys per advertiser, out of which a maximum of 20 keys can be assigned per ad, creative, or placement.",
	//   "flatPath": "userprofiles/{profileId}/dynamicTargetingKeys",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.dynamicTargetingKeys.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/dynamicTargetingKeys",
	//   "request": {
	//     "$ref": "DynamicTargetingKey"
	//   },
	//   "response": {
	//     "$ref": "DynamicTargetingKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.dynamicTargetingKeys.list":

type DynamicTargetingKeysListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of dynamic targeting keys.
func (r *DynamicTargetingKeysService) List(profileId int64) *DynamicTargetingKeysListCall {
	c := &DynamicTargetingKeysListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// dynamic targeting keys whose object has this advertiser ID.
func (c *DynamicTargetingKeysListCall) AdvertiserId(advertiserId int64) *DynamicTargetingKeysListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Names sets the optional parameter "names": Select only dynamic
// targeting keys exactly matching these names.
func (c *DynamicTargetingKeysListCall) Names(names ...string) *DynamicTargetingKeysListCall {
	c.urlParams_.SetMulti("names", append([]string{}, names...))
	return c
}

// ObjectId sets the optional parameter "objectId": Select only dynamic
// targeting keys with this object ID.
func (c *DynamicTargetingKeysListCall) ObjectId(objectId int64) *DynamicTargetingKeysListCall {
	c.urlParams_.Set("objectId", fmt.Sprint(objectId))
	return c
}

// ObjectType sets the optional parameter "objectType": Select only
// dynamic targeting keys with this object type.
//
// Possible values:
//   "OBJECT_ADVERTISER"
//   "OBJECT_AD"
//   "OBJECT_CREATIVE"
//   "OBJECT_PLACEMENT"
func (c *DynamicTargetingKeysListCall) ObjectType(objectType string) *DynamicTargetingKeysListCall {
	c.urlParams_.Set("objectType", objectType)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DynamicTargetingKeysListCall) Fields(s ...googleapi.Field) *DynamicTargetingKeysListCall {
	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 *DynamicTargetingKeysListCall) IfNoneMatch(entityTag string) *DynamicTargetingKeysListCall {
	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 *DynamicTargetingKeysListCall) Context(ctx context.Context) *DynamicTargetingKeysListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DynamicTargetingKeysListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DynamicTargetingKeysListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/dynamicTargetingKeys")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.dynamicTargetingKeys.list" call.
// Exactly one of *DynamicTargetingKeysListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *DynamicTargetingKeysListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DynamicTargetingKeysListCall) Do(opts ...googleapi.CallOption) (*DynamicTargetingKeysListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DynamicTargetingKeysListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of dynamic targeting keys.",
	//   "flatPath": "userprofiles/{profileId}/dynamicTargetingKeys",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.dynamicTargetingKeys.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Select only dynamic targeting keys whose object has this advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "names": {
	//       "description": "Select only dynamic targeting keys exactly matching these names.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "objectId": {
	//       "description": "Select only dynamic targeting keys with this object ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "objectType": {
	//       "description": "Select only dynamic targeting keys with this object type.",
	//       "enum": [
	//         "OBJECT_ADVERTISER",
	//         "OBJECT_AD",
	//         "OBJECT_CREATIVE",
	//         "OBJECT_PLACEMENT"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/dynamicTargetingKeys",
	//   "response": {
	//     "$ref": "DynamicTargetingKeysListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.delete":

type EventTagsDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing event tag.
func (r *EventTagsService) Delete(profileId int64, id int64) *EventTagsDeleteCall {
	c := &EventTagsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsDeleteCall) Fields(s ...googleapi.Field) *EventTagsDeleteCall {
	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 *EventTagsDeleteCall) Context(ctx context.Context) *EventTagsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/eventTags/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.delete" call.
func (c *EventTagsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing event tag.",
	//   "flatPath": "userprofiles/{profileId}/eventTags/{id}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.eventTags.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Event tag ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.get":

type EventTagsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one event tag by ID.
func (r *EventTagsService) Get(profileId int64, id int64) *EventTagsGetCall {
	c := &EventTagsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsGetCall) Fields(s ...googleapi.Field) *EventTagsGetCall {
	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 *EventTagsGetCall) IfNoneMatch(entityTag string) *EventTagsGetCall {
	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 *EventTagsGetCall) Context(ctx context.Context) *EventTagsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/eventTags/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.get" call.
// Exactly one of *EventTag or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *EventTag.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *EventTagsGetCall) Do(opts ...googleapi.CallOption) (*EventTag, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTag{
		ServerResponse: googleapi.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 one event tag by ID.",
	//   "flatPath": "userprofiles/{profileId}/eventTags/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.eventTags.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Event tag ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags/{id}",
	//   "response": {
	//     "$ref": "EventTag"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.insert":

type EventTagsInsertCall struct {
	s          *Service
	profileId  int64
	eventtag   *EventTag
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new event tag.
func (r *EventTagsService) Insert(profileId int64, eventtag *EventTag) *EventTagsInsertCall {
	c := &EventTagsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.eventtag = eventtag
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsInsertCall) Fields(s ...googleapi.Field) *EventTagsInsertCall {
	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 *EventTagsInsertCall) Context(ctx context.Context) *EventTagsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.eventtag)
	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, "userprofiles/{profileId}/eventTags")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.insert" call.
// Exactly one of *EventTag or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *EventTag.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *EventTagsInsertCall) Do(opts ...googleapi.CallOption) (*EventTag, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTag{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new event tag.",
	//   "flatPath": "userprofiles/{profileId}/eventTags",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.eventTags.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags",
	//   "request": {
	//     "$ref": "EventTag"
	//   },
	//   "response": {
	//     "$ref": "EventTag"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.list":

type EventTagsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of event tags, possibly filtered.
func (r *EventTagsService) List(profileId int64) *EventTagsListCall {
	c := &EventTagsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdId sets the optional parameter "adId": Select only event tags that
// belong to this ad.
func (c *EventTagsListCall) AdId(adId int64) *EventTagsListCall {
	c.urlParams_.Set("adId", fmt.Sprint(adId))
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// event tags that belong to this advertiser.
func (c *EventTagsListCall) AdvertiserId(advertiserId int64) *EventTagsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// CampaignId sets the optional parameter "campaignId": Select only
// event tags that belong to this campaign.
func (c *EventTagsListCall) CampaignId(campaignId int64) *EventTagsListCall {
	c.urlParams_.Set("campaignId", fmt.Sprint(campaignId))
	return c
}

// DefinitionsOnly sets the optional parameter "definitionsOnly":
// Examine only the specified campaign or advertiser's event tags for
// matching selector criteria. When set to false, the parent advertiser
// and parent campaign of the specified ad or campaign is examined as
// well. In addition, when set to false, the status field is examined as
// well, along with the enabledByDefault field. This parameter can not
// be set to true when adId is specified as ads do not define their own
// even tags.
func (c *EventTagsListCall) DefinitionsOnly(definitionsOnly bool) *EventTagsListCall {
	c.urlParams_.Set("definitionsOnly", fmt.Sprint(definitionsOnly))
	return c
}

// Enabled sets the optional parameter "enabled": Select only enabled
// event tags. What is considered enabled or disabled depends on the
// definitionsOnly parameter. When definitionsOnly is set to true, only
// the specified advertiser or campaign's event tags' enabledByDefault
// field is examined. When definitionsOnly is set to false, the
// specified ad or specified campaign's parent advertiser's or parent
// campaign's event tags' enabledByDefault and status fields are
// examined as well.
func (c *EventTagsListCall) Enabled(enabled bool) *EventTagsListCall {
	c.urlParams_.Set("enabled", fmt.Sprint(enabled))
	return c
}

// EventTagTypes sets the optional parameter "eventTagTypes": Select
// only event tags with the specified event tag types. Event tag types
// can be used to specify whether to use a third-party pixel, a
// third-party JavaScript URL, or a third-party click-through URL for
// either impression or click tracking.
//
// Possible values:
//   "IMPRESSION_IMAGE_EVENT_TAG"
//   "IMPRESSION_JAVASCRIPT_EVENT_TAG"
//   "CLICK_THROUGH_EVENT_TAG"
func (c *EventTagsListCall) EventTagTypes(eventTagTypes ...string) *EventTagsListCall {
	c.urlParams_.SetMulti("eventTagTypes", append([]string{}, eventTagTypes...))
	return c
}

// Ids sets the optional parameter "ids": Select only event tags with
// these IDs.
func (c *EventTagsListCall) Ids(ids ...int64) *EventTagsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "eventtag*2015" will return objects with names like
// "eventtag June 2015", "eventtag April 2015", or simply "eventtag
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "eventtag" will match objects with name "my eventtag", "eventtag
// 2015", or simply "eventtag".
func (c *EventTagsListCall) SearchString(searchString string) *EventTagsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *EventTagsListCall) SortField(sortField string) *EventTagsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *EventTagsListCall) SortOrder(sortOrder string) *EventTagsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsListCall) Fields(s ...googleapi.Field) *EventTagsListCall {
	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 *EventTagsListCall) IfNoneMatch(entityTag string) *EventTagsListCall {
	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 *EventTagsListCall) Context(ctx context.Context) *EventTagsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/eventTags")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.list" call.
// Exactly one of *EventTagsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *EventTagsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *EventTagsListCall) Do(opts ...googleapi.CallOption) (*EventTagsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTagsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of event tags, possibly filtered.",
	//   "flatPath": "userprofiles/{profileId}/eventTags",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.eventTags.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "adId": {
	//       "description": "Select only event tags that belong to this ad.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "advertiserId": {
	//       "description": "Select only event tags that belong to this advertiser.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "campaignId": {
	//       "description": "Select only event tags that belong to this campaign.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "definitionsOnly": {
	//       "description": "Examine only the specified campaign or advertiser's event tags for matching selector criteria. When set to false, the parent advertiser and parent campaign of the specified ad or campaign is examined as well. In addition, when set to false, the status field is examined as well, along with the enabledByDefault field. This parameter can not be set to true when adId is specified as ads do not define their own even tags.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "enabled": {
	//       "description": "Select only enabled event tags. What is considered enabled or disabled depends on the definitionsOnly parameter. When definitionsOnly is set to true, only the specified advertiser or campaign's event tags' enabledByDefault field is examined. When definitionsOnly is set to false, the specified ad or specified campaign's parent advertiser's or parent campaign's event tags' enabledByDefault and status fields are examined as well.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "eventTagTypes": {
	//       "description": "Select only event tags with the specified event tag types. Event tag types can be used to specify whether to use a third-party pixel, a third-party JavaScript URL, or a third-party click-through URL for either impression or click tracking.",
	//       "enum": [
	//         "IMPRESSION_IMAGE_EVENT_TAG",
	//         "IMPRESSION_JAVASCRIPT_EVENT_TAG",
	//         "CLICK_THROUGH_EVENT_TAG"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only event tags with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"eventtag*2015\" will return objects with names like \"eventtag June 2015\", \"eventtag April 2015\", or simply \"eventtag 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"eventtag\" will match objects with name \"my eventtag\", \"eventtag 2015\", or simply \"eventtag\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags",
	//   "response": {
	//     "$ref": "EventTagsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.patch":

type EventTagsPatchCall struct {
	s          *Service
	profileId  int64
	eventtag   *EventTag
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing event tag. This method supports patch
// semantics.
func (r *EventTagsService) Patch(profileId int64, eventtag *EventTag) *EventTagsPatchCall {
	c := &EventTagsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.eventtag = eventtag
	return c
}

// Id sets the optional parameter "id": EventTag ID.
func (c *EventTagsPatchCall) Id(id int64) *EventTagsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsPatchCall) Fields(s ...googleapi.Field) *EventTagsPatchCall {
	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 *EventTagsPatchCall) Context(ctx context.Context) *EventTagsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.eventtag)
	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, "userprofiles/{profileId}/eventTags")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.patch" call.
// Exactly one of *EventTag or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *EventTag.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *EventTagsPatchCall) Do(opts ...googleapi.CallOption) (*EventTag, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTag{
		ServerResponse: googleapi.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 event tag. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/eventTags",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.eventTags.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "EventTag ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags",
	//   "request": {
	//     "$ref": "EventTag"
	//   },
	//   "response": {
	//     "$ref": "EventTag"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.update":

type EventTagsUpdateCall struct {
	s          *Service
	profileId  int64
	eventtag   *EventTag
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing event tag.
func (r *EventTagsService) Update(profileId int64, eventtag *EventTag) *EventTagsUpdateCall {
	c := &EventTagsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.eventtag = eventtag
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsUpdateCall) Fields(s ...googleapi.Field) *EventTagsUpdateCall {
	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 *EventTagsUpdateCall) Context(ctx context.Context) *EventTagsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.eventtag)
	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, "userprofiles/{profileId}/eventTags")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.update" call.
// Exactly one of *EventTag or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *EventTag.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *EventTagsUpdateCall) Do(opts ...googleapi.CallOption) (*EventTag, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTag{
		ServerResponse: googleapi.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 event tag.",
	//   "flatPath": "userprofiles/{profileId}/eventTags",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.eventTags.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags",
	//   "request": {
	//     "$ref": "EventTag"
	//   },
	//   "response": {
	//     "$ref": "EventTag"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.files.get":

type FilesGetCall struct {
	s            *Service
	reportId     int64
	fileId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves a report file by its report ID and file ID. This
// method supports media download.
func (r *FilesService) Get(reportId int64, fileId int64) *FilesGetCall {
	c := &FilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.reportId = reportId
	c.fileId = fileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FilesGetCall) Fields(s ...googleapi.Field) *FilesGetCall {
	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 *FilesGetCall) IfNoneMatch(entityTag string) *FilesGetCall {
	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 *FilesGetCall) Context(ctx context.Context) *FilesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "reports/{reportId}/files/{fileId}")
	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{
		"reportId": strconv.FormatInt(c.reportId, 10),
		"fileId":   strconv.FormatInt(c.fileId, 10),
	})
	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 *FilesGetCall) 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 "dfareporting.files.get" call.
// Exactly one of *File or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *File.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FilesGetCall) Do(opts ...googleapi.CallOption) (*File, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &File{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a report file by its report ID and file ID. This method supports media download.",
	//   "flatPath": "reports/{reportId}/files/{fileId}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.files.get",
	//   "parameterOrder": [
	//     "reportId",
	//     "fileId"
	//   ],
	//   "parameters": {
	//     "fileId": {
	//       "description": "The ID of the report file.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "reports/{reportId}/files/{fileId}",
	//   "response": {
	//     "$ref": "File"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ],
	//   "supportsMediaDownload": true
	// }

}

// method id "dfareporting.files.list":

type FilesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists files for a user profile.
func (r *FilesService) List(profileId int64) *FilesListCall {
	c := &FilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *FilesListCall) MaxResults(maxResults int64) *FilesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The value of the
// nextToken from the previous result page.
func (c *FilesListCall) PageToken(pageToken string) *FilesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Scope sets the optional parameter "scope": The scope that defines
// which results are returned.
//
// Possible values:
//   "ALL" - All files in account.
//   "MINE" (default) - My files.
//   "SHARED_WITH_ME" - Files shared with me.
func (c *FilesListCall) Scope(scope string) *FilesListCall {
	c.urlParams_.Set("scope", scope)
	return c
}

// SortField sets the optional parameter "sortField": The field by which
// to sort the list.
//
// Possible values:
//   "ID" - Sort by file ID.
//   "LAST_MODIFIED_TIME" (default) - Sort by 'lastmodifiedAt' field.
func (c *FilesListCall) SortField(sortField string) *FilesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" - Ascending order.
//   "DESCENDING" (default) - Descending order.
func (c *FilesListCall) SortOrder(sortOrder string) *FilesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FilesListCall) Fields(s ...googleapi.Field) *FilesListCall {
	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 *FilesListCall) IfNoneMatch(entityTag string) *FilesListCall {
	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 *FilesListCall) Context(ctx context.Context) *FilesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FilesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/files")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.files.list" call.
// Exactly one of *FileList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *FileList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FilesListCall) Do(opts ...googleapi.CallOption) (*FileList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FileList{
		ServerResponse: googleapi.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 files for a user profile.",
	//   "flatPath": "userprofiles/{profileId}/files",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.files.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "default": "10",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "10",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value of the nextToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "scope": {
	//       "default": "MINE",
	//       "description": "The scope that defines which results are returned.",
	//       "enum": [
	//         "ALL",
	//         "MINE",
	//         "SHARED_WITH_ME"
	//       ],
	//       "enumDescriptions": [
	//         "All files in account.",
	//         "My files.",
	//         "Files shared with me."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "LAST_MODIFIED_TIME",
	//       "description": "The field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "LAST_MODIFIED_TIME"
	//       ],
	//       "enumDescriptions": [
	//         "Sort by file ID.",
	//         "Sort by 'lastmodifiedAt' field."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "DESCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "Ascending order.",
	//         "Descending order."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/files",
	//   "response": {
	//     "$ref": "FileList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// 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 *FilesListCall) Pages(ctx context.Context, f func(*FileList) 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 "dfareporting.floodlightActivities.delete":

type FloodlightActivitiesDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing floodlight activity.
func (r *FloodlightActivitiesService) Delete(profileId int64, id int64) *FloodlightActivitiesDeleteCall {
	c := &FloodlightActivitiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesDeleteCall) Fields(s ...googleapi.Field) *FloodlightActivitiesDeleteCall {
	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 *FloodlightActivitiesDeleteCall) Context(ctx context.Context) *FloodlightActivitiesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/floodlightActivities/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.delete" call.
func (c *FloodlightActivitiesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing floodlight activity.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivities/{id}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.floodlightActivities.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.generatetag":

type FloodlightActivitiesGeneratetagCall struct {
	s          *Service
	profileId  int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Generatetag: Generates a tag for a floodlight activity.
func (r *FloodlightActivitiesService) Generatetag(profileId int64) *FloodlightActivitiesGeneratetagCall {
	c := &FloodlightActivitiesGeneratetagCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// FloodlightActivityId sets the optional parameter
// "floodlightActivityId": Floodlight activity ID for which we want to
// generate a tag.
func (c *FloodlightActivitiesGeneratetagCall) FloodlightActivityId(floodlightActivityId int64) *FloodlightActivitiesGeneratetagCall {
	c.urlParams_.Set("floodlightActivityId", fmt.Sprint(floodlightActivityId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesGeneratetagCall) Fields(s ...googleapi.Field) *FloodlightActivitiesGeneratetagCall {
	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 *FloodlightActivitiesGeneratetagCall) Context(ctx context.Context) *FloodlightActivitiesGeneratetagCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesGeneratetagCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesGeneratetagCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/floodlightActivities/generatetag")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.generatetag" call.
// Exactly one of *FloodlightActivitiesGenerateTagResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *FloodlightActivitiesGenerateTagResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesGeneratetagCall) Do(opts ...googleapi.CallOption) (*FloodlightActivitiesGenerateTagResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivitiesGenerateTagResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generates a tag for a floodlight activity.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivities/generatetag",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.floodlightActivities.generatetag",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "floodlightActivityId": {
	//       "description": "Floodlight activity ID for which we want to generate a tag.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities/generatetag",
	//   "response": {
	//     "$ref": "FloodlightActivitiesGenerateTagResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.get":

type FloodlightActivitiesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one floodlight activity by ID.
func (r *FloodlightActivitiesService) Get(profileId int64, id int64) *FloodlightActivitiesGetCall {
	c := &FloodlightActivitiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesGetCall) Fields(s ...googleapi.Field) *FloodlightActivitiesGetCall {
	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 *FloodlightActivitiesGetCall) IfNoneMatch(entityTag string) *FloodlightActivitiesGetCall {
	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 *FloodlightActivitiesGetCall) Context(ctx context.Context) *FloodlightActivitiesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/floodlightActivities/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.get" call.
// Exactly one of *FloodlightActivity or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesGetCall) Do(opts ...googleapi.CallOption) (*FloodlightActivity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivity{
		ServerResponse: googleapi.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 one floodlight activity by ID.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivities/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightActivities.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities/{id}",
	//   "response": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.insert":

type FloodlightActivitiesInsertCall struct {
	s                  *Service
	profileId          int64
	floodlightactivity *FloodlightActivity
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Insert: Inserts a new floodlight activity.
func (r *FloodlightActivitiesService) Insert(profileId int64, floodlightactivity *FloodlightActivity) *FloodlightActivitiesInsertCall {
	c := &FloodlightActivitiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivity = floodlightactivity
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesInsertCall) Fields(s ...googleapi.Field) *FloodlightActivitiesInsertCall {
	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 *FloodlightActivitiesInsertCall) Context(ctx context.Context) *FloodlightActivitiesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.floodlightactivity)
	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, "userprofiles/{profileId}/floodlightActivities")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.insert" call.
// Exactly one of *FloodlightActivity or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesInsertCall) Do(opts ...googleapi.CallOption) (*FloodlightActivity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivity{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new floodlight activity.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivities",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.floodlightActivities.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities",
	//   "request": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.list":

type FloodlightActivitiesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of floodlight activities, possibly filtered.
// This method supports paging.
func (r *FloodlightActivitiesService) List(profileId int64) *FloodlightActivitiesListCall {
	c := &FloodlightActivitiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// floodlight activities for the specified advertiser ID. Must specify
// either ids, advertiserId, or floodlightConfigurationId for a
// non-empty result.
func (c *FloodlightActivitiesListCall) AdvertiserId(advertiserId int64) *FloodlightActivitiesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// FloodlightActivityGroupIds sets the optional parameter
// "floodlightActivityGroupIds": Select only floodlight activities with
// the specified floodlight activity group IDs.
func (c *FloodlightActivitiesListCall) FloodlightActivityGroupIds(floodlightActivityGroupIds ...int64) *FloodlightActivitiesListCall {
	var floodlightActivityGroupIds_ []string
	for _, v := range floodlightActivityGroupIds {
		floodlightActivityGroupIds_ = append(floodlightActivityGroupIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("floodlightActivityGroupIds", floodlightActivityGroupIds_)
	return c
}

// FloodlightActivityGroupName sets the optional parameter
// "floodlightActivityGroupName": Select only floodlight activities with
// the specified floodlight activity group name.
func (c *FloodlightActivitiesListCall) FloodlightActivityGroupName(floodlightActivityGroupName string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("floodlightActivityGroupName", floodlightActivityGroupName)
	return c
}

// FloodlightActivityGroupTagString sets the optional parameter
// "floodlightActivityGroupTagString": Select only floodlight activities
// with the specified floodlight activity group tag string.
func (c *FloodlightActivitiesListCall) FloodlightActivityGroupTagString(floodlightActivityGroupTagString string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("floodlightActivityGroupTagString", floodlightActivityGroupTagString)
	return c
}

// FloodlightActivityGroupType sets the optional parameter
// "floodlightActivityGroupType": Select only floodlight activities with
// the specified floodlight activity group type.
//
// Possible values:
//   "COUNTER"
//   "SALE"
func (c *FloodlightActivitiesListCall) FloodlightActivityGroupType(floodlightActivityGroupType string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("floodlightActivityGroupType", floodlightActivityGroupType)
	return c
}

// FloodlightConfigurationId sets the optional parameter
// "floodlightConfigurationId": Select only floodlight activities for
// the specified floodlight configuration ID. Must specify either ids,
// advertiserId, or floodlightConfigurationId for a non-empty result.
func (c *FloodlightActivitiesListCall) FloodlightConfigurationId(floodlightConfigurationId int64) *FloodlightActivitiesListCall {
	c.urlParams_.Set("floodlightConfigurationId", fmt.Sprint(floodlightConfigurationId))
	return c
}

// Ids sets the optional parameter "ids": Select only floodlight
// activities with the specified IDs. Must specify either ids,
// advertiserId, or floodlightConfigurationId for a non-empty result.
func (c *FloodlightActivitiesListCall) Ids(ids ...int64) *FloodlightActivitiesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *FloodlightActivitiesListCall) MaxResults(maxResults int64) *FloodlightActivitiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *FloodlightActivitiesListCall) PageToken(pageToken string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "floodlightactivity*2015" will return objects with names
// like "floodlightactivity June 2015", "floodlightactivity April 2015",
// or simply "floodlightactivity 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "floodlightactivity" will match
// objects with name "my floodlightactivity activity",
// "floodlightactivity 2015", or simply "floodlightactivity".
func (c *FloodlightActivitiesListCall) SearchString(searchString string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *FloodlightActivitiesListCall) SortField(sortField string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *FloodlightActivitiesListCall) SortOrder(sortOrder string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// TagString sets the optional parameter "tagString": Select only
// floodlight activities with the specified tag string.
func (c *FloodlightActivitiesListCall) TagString(tagString string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("tagString", tagString)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesListCall) Fields(s ...googleapi.Field) *FloodlightActivitiesListCall {
	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 *FloodlightActivitiesListCall) IfNoneMatch(entityTag string) *FloodlightActivitiesListCall {
	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 *FloodlightActivitiesListCall) Context(ctx context.Context) *FloodlightActivitiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/floodlightActivities")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.list" call.
// Exactly one of *FloodlightActivitiesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *FloodlightActivitiesListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesListCall) Do(opts ...googleapi.CallOption) (*FloodlightActivitiesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivitiesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of floodlight activities, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivities",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightActivities.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Select only floodlight activities for the specified advertiser ID. Must specify either ids, advertiserId, or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightActivityGroupIds": {
	//       "description": "Select only floodlight activities with the specified floodlight activity group IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "floodlightActivityGroupName": {
	//       "description": "Select only floodlight activities with the specified floodlight activity group name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightActivityGroupTagString": {
	//       "description": "Select only floodlight activities with the specified floodlight activity group tag string.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightActivityGroupType": {
	//       "description": "Select only floodlight activities with the specified floodlight activity group type.",
	//       "enum": [
	//         "COUNTER",
	//         "SALE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightConfigurationId": {
	//       "description": "Select only floodlight activities for the specified floodlight configuration ID. Must specify either ids, advertiserId, or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only floodlight activities with the specified IDs. Must specify either ids, advertiserId, or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"floodlightactivity*2015\" will return objects with names like \"floodlightactivity June 2015\", \"floodlightactivity April 2015\", or simply \"floodlightactivity 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"floodlightactivity\" will match objects with name \"my floodlightactivity activity\", \"floodlightactivity 2015\", or simply \"floodlightactivity\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "tagString": {
	//       "description": "Select only floodlight activities with the specified tag string.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities",
	//   "response": {
	//     "$ref": "FloodlightActivitiesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *FloodlightActivitiesListCall) Pages(ctx context.Context, f func(*FloodlightActivitiesListResponse) 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 "dfareporting.floodlightActivities.patch":

type FloodlightActivitiesPatchCall struct {
	s                  *Service
	profileId          int64
	floodlightactivity *FloodlightActivity
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Patch: Updates an existing floodlight activity. This method supports
// patch semantics.
func (r *FloodlightActivitiesService) Patch(profileId int64, floodlightactivity *FloodlightActivity) *FloodlightActivitiesPatchCall {
	c := &FloodlightActivitiesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivity = floodlightactivity
	return c
}

// Id sets the optional parameter "id": FloodlightActivity ID.
func (c *FloodlightActivitiesPatchCall) Id(id int64) *FloodlightActivitiesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesPatchCall) Fields(s ...googleapi.Field) *FloodlightActivitiesPatchCall {
	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 *FloodlightActivitiesPatchCall) Context(ctx context.Context) *FloodlightActivitiesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.floodlightactivity)
	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, "userprofiles/{profileId}/floodlightActivities")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.patch" call.
// Exactly one of *FloodlightActivity or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesPatchCall) Do(opts ...googleapi.CallOption) (*FloodlightActivity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivity{
		ServerResponse: googleapi.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 activity. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivities",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.floodlightActivities.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "FloodlightActivity ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities",
	//   "request": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.update":

type FloodlightActivitiesUpdateCall struct {
	s                  *Service
	profileId          int64
	floodlightactivity *FloodlightActivity
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Update: Updates an existing floodlight activity.
func (r *FloodlightActivitiesService) Update(profileId int64, floodlightactivity *FloodlightActivity) *FloodlightActivitiesUpdateCall {
	c := &FloodlightActivitiesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivity = floodlightactivity
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesUpdateCall) Fields(s ...googleapi.Field) *FloodlightActivitiesUpdateCall {
	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 *FloodlightActivitiesUpdateCall) Context(ctx context.Context) *FloodlightActivitiesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.floodlightactivity)
	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, "userprofiles/{profileId}/floodlightActivities")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.update" call.
// Exactly one of *FloodlightActivity or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesUpdateCall) Do(opts ...googleapi.CallOption) (*FloodlightActivity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivity{
		ServerResponse: googleapi.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 activity.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivities",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.floodlightActivities.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities",
	//   "request": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.get":

type FloodlightActivityGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one floodlight activity group by ID.
func (r *FloodlightActivityGroupsService) Get(profileId int64, id int64) *FloodlightActivityGroupsGetCall {
	c := &FloodlightActivityGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsGetCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsGetCall {
	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 *FloodlightActivityGroupsGetCall) IfNoneMatch(entityTag string) *FloodlightActivityGroupsGetCall {
	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 *FloodlightActivityGroupsGetCall) Context(ctx context.Context) *FloodlightActivityGroupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/floodlightActivityGroups/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.get" call.
// Exactly one of *FloodlightActivityGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivityGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivityGroupsGetCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroup{
		ServerResponse: googleapi.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 one floodlight activity group by ID.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivityGroups/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightActivityGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity Group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups/{id}",
	//   "response": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.insert":

type FloodlightActivityGroupsInsertCall struct {
	s                       *Service
	profileId               int64
	floodlightactivitygroup *FloodlightActivityGroup
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Insert: Inserts a new floodlight activity group.
func (r *FloodlightActivityGroupsService) Insert(profileId int64, floodlightactivitygroup *FloodlightActivityGroup) *FloodlightActivityGroupsInsertCall {
	c := &FloodlightActivityGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivitygroup = floodlightactivitygroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsInsertCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsInsertCall {
	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 *FloodlightActivityGroupsInsertCall) Context(ctx context.Context) *FloodlightActivityGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.floodlightactivitygroup)
	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, "userprofiles/{profileId}/floodlightActivityGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.insert" call.
// Exactly one of *FloodlightActivityGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivityGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivityGroupsInsertCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new floodlight activity group.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.floodlightActivityGroups.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "request": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.list":

type FloodlightActivityGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of floodlight activity groups, possibly
// filtered. This method supports paging.
func (r *FloodlightActivityGroupsService) List(profileId int64) *FloodlightActivityGroupsListCall {
	c := &FloodlightActivityGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// floodlight activity groups with the specified advertiser ID. Must
// specify either advertiserId or floodlightConfigurationId for a
// non-empty result.
func (c *FloodlightActivityGroupsListCall) AdvertiserId(advertiserId int64) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// FloodlightConfigurationId sets the optional parameter
// "floodlightConfigurationId": Select only floodlight activity groups
// with the specified floodlight configuration ID. Must specify either
// advertiserId, or floodlightConfigurationId for a non-empty result.
func (c *FloodlightActivityGroupsListCall) FloodlightConfigurationId(floodlightConfigurationId int64) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("floodlightConfigurationId", fmt.Sprint(floodlightConfigurationId))
	return c
}

// Ids sets the optional parameter "ids": Select only floodlight
// activity groups with the specified IDs. Must specify either
// advertiserId or floodlightConfigurationId for a non-empty result.
func (c *FloodlightActivityGroupsListCall) Ids(ids ...int64) *FloodlightActivityGroupsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *FloodlightActivityGroupsListCall) MaxResults(maxResults int64) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *FloodlightActivityGroupsListCall) PageToken(pageToken string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "floodlightactivitygroup*2015" will return objects with
// names like "floodlightactivitygroup June 2015",
// "floodlightactivitygroup April 2015", or simply
// "floodlightactivitygroup 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "floodlightactivitygroup" will match
// objects with name "my floodlightactivitygroup activity",
// "floodlightactivitygroup 2015", or simply "floodlightactivitygroup".
func (c *FloodlightActivityGroupsListCall) SearchString(searchString string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *FloodlightActivityGroupsListCall) SortField(sortField string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *FloodlightActivityGroupsListCall) SortOrder(sortOrder string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Type sets the optional parameter "type": Select only floodlight
// activity groups with the specified floodlight activity group type.
//
// Possible values:
//   "COUNTER"
//   "SALE"
func (c *FloodlightActivityGroupsListCall) Type(type_ string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("type", type_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsListCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsListCall {
	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 *FloodlightActivityGroupsListCall) IfNoneMatch(entityTag string) *FloodlightActivityGroupsListCall {
	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 *FloodlightActivityGroupsListCall) Context(ctx context.Context) *FloodlightActivityGroupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/floodlightActivityGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.list" call.
// Exactly one of *FloodlightActivityGroupsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *FloodlightActivityGroupsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FloodlightActivityGroupsListCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of floodlight activity groups, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightActivityGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Select only floodlight activity groups with the specified advertiser ID. Must specify either advertiserId or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightConfigurationId": {
	//       "description": "Select only floodlight activity groups with the specified floodlight configuration ID. Must specify either advertiserId, or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only floodlight activity groups with the specified IDs. Must specify either advertiserId or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"floodlightactivitygroup*2015\" will return objects with names like \"floodlightactivitygroup June 2015\", \"floodlightactivitygroup April 2015\", or simply \"floodlightactivitygroup 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"floodlightactivitygroup\" will match objects with name \"my floodlightactivitygroup activity\", \"floodlightactivitygroup 2015\", or simply \"floodlightactivitygroup\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Select only floodlight activity groups with the specified floodlight activity group type.",
	//       "enum": [
	//         "COUNTER",
	//         "SALE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "response": {
	//     "$ref": "FloodlightActivityGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *FloodlightActivityGroupsListCall) Pages(ctx context.Context, f func(*FloodlightActivityGroupsListResponse) 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 "dfareporting.floodlightActivityGroups.patch":

type FloodlightActivityGroupsPatchCall struct {
	s                       *Service
	profileId               int64
	floodlightactivitygroup *FloodlightActivityGroup
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Patch: Updates an existing floodlight activity group. This method
// supports patch semantics.
func (r *FloodlightActivityGroupsService) Patch(profileId int64, floodlightactivitygroup *FloodlightActivityGroup) *FloodlightActivityGroupsPatchCall {
	c := &FloodlightActivityGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivitygroup = floodlightactivitygroup
	return c
}

// Id sets the optional parameter "id": FloodlightActivityGroup ID.
func (c *FloodlightActivityGroupsPatchCall) Id(id int64) *FloodlightActivityGroupsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsPatchCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsPatchCall {
	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 *FloodlightActivityGroupsPatchCall) Context(ctx context.Context) *FloodlightActivityGroupsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.floodlightactivitygroup)
	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, "userprofiles/{profileId}/floodlightActivityGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.patch" call.
// Exactly one of *FloodlightActivityGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivityGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivityGroupsPatchCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroup{
		ServerResponse: googleapi.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 activity group. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.floodlightActivityGroups.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "FloodlightActivityGroup ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "request": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.update":

type FloodlightActivityGroupsUpdateCall struct {
	s                       *Service
	profileId               int64
	floodlightactivitygroup *FloodlightActivityGroup
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Update: Updates an existing floodlight activity group.
func (r *FloodlightActivityGroupsService) Update(profileId int64, floodlightactivitygroup *FloodlightActivityGroup) *FloodlightActivityGroupsUpdateCall {
	c := &FloodlightActivityGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivitygroup = floodlightactivitygroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsUpdateCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsUpdateCall {
	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 *FloodlightActivityGroupsUpdateCall) Context(ctx context.Context) *FloodlightActivityGroupsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.floodlightactivitygroup)
	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, "userprofiles/{profileId}/floodlightActivityGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.update" call.
// Exactly one of *FloodlightActivityGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivityGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivityGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroup{
		ServerResponse: googleapi.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 activity group.",
	//   "flatPath": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.floodlightActivityGroups.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "request": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightConfigurations.get":

type FloodlightConfigurationsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one floodlight configuration by ID.
func (r *FloodlightConfigurationsService) Get(profileId int64, id int64) *FloodlightConfigurationsGetCall {
	c := &FloodlightConfigurationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightConfigurationsGetCall) Fields(s ...googleapi.Field) *FloodlightConfigurationsGetCall {
	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 *FloodlightConfigurationsGetCall) IfNoneMatch(entityTag string) *FloodlightConfigurationsGetCall {
	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 *FloodlightConfigurationsGetCall) Context(ctx context.Context) *FloodlightConfigurationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightConfigurationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightConfigurationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/floodlightConfigurations/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightConfigurations.get" call.
// Exactly one of *FloodlightConfiguration or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightConfiguration.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightConfigurationsGetCall) Do(opts ...googleapi.CallOption) (*FloodlightConfiguration, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightConfiguration{
		ServerResponse: googleapi.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 one floodlight configuration by ID.",
	//   "flatPath": "userprofiles/{profileId}/floodlightConfigurations/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightConfigurations.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight configuration ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightConfigurations/{id}",
	//   "response": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightConfigurations.list":

type FloodlightConfigurationsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of floodlight configurations, possibly
// filtered.
func (r *FloodlightConfigurationsService) List(profileId int64) *FloodlightConfigurationsListCall {
	c := &FloodlightConfigurationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Set of IDs of floodlight
// configurations to retrieve. Required field; otherwise an empty list
// will be returned.
func (c *FloodlightConfigurationsListCall) Ids(ids ...int64) *FloodlightConfigurationsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightConfigurationsListCall) Fields(s ...googleapi.Field) *FloodlightConfigurationsListCall {
	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 *FloodlightConfigurationsListCall) IfNoneMatch(entityTag string) *FloodlightConfigurationsListCall {
	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 *FloodlightConfigurationsListCall) Context(ctx context.Context) *FloodlightConfigurationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightConfigurationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightConfigurationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/floodlightConfigurations")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightConfigurations.list" call.
// Exactly one of *FloodlightConfigurationsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *FloodlightConfigurationsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FloodlightConfigurationsListCall) Do(opts ...googleapi.CallOption) (*FloodlightConfigurationsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightConfigurationsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of floodlight configurations, possibly filtered.",
	//   "flatPath": "userprofiles/{profileId}/floodlightConfigurations",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightConfigurations.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Set of IDs of floodlight configurations to retrieve. Required field; otherwise an empty list will be returned.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightConfigurations",
	//   "response": {
	//     "$ref": "FloodlightConfigurationsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightConfigurations.patch":

type FloodlightConfigurationsPatchCall struct {
	s                       *Service
	profileId               int64
	floodlightconfiguration *FloodlightConfiguration
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Patch: Updates an existing floodlight configuration. This method
// supports patch semantics.
func (r *FloodlightConfigurationsService) Patch(profileId int64, floodlightconfiguration *FloodlightConfiguration) *FloodlightConfigurationsPatchCall {
	c := &FloodlightConfigurationsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightconfiguration = floodlightconfiguration
	return c
}

// Id sets the optional parameter "id": FloodlightConfiguration ID.
func (c *FloodlightConfigurationsPatchCall) Id(id int64) *FloodlightConfigurationsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightConfigurationsPatchCall) Fields(s ...googleapi.Field) *FloodlightConfigurationsPatchCall {
	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 *FloodlightConfigurationsPatchCall) Context(ctx context.Context) *FloodlightConfigurationsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightConfigurationsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightConfigurationsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.floodlightconfiguration)
	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, "userprofiles/{profileId}/floodlightConfigurations")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightConfigurations.patch" call.
// Exactly one of *FloodlightConfiguration or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightConfiguration.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightConfigurationsPatchCall) Do(opts ...googleapi.CallOption) (*FloodlightConfiguration, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightConfiguration{
		ServerResponse: googleapi.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 configuration. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/floodlightConfigurations",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.floodlightConfigurations.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "FloodlightConfiguration ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightConfigurations",
	//   "request": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "response": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightConfigurations.update":

type FloodlightConfigurationsUpdateCall struct {
	s                       *Service
	profileId               int64
	floodlightconfiguration *FloodlightConfiguration
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Update: Updates an existing floodlight configuration.
func (r *FloodlightConfigurationsService) Update(profileId int64, floodlightconfiguration *FloodlightConfiguration) *FloodlightConfigurationsUpdateCall {
	c := &FloodlightConfigurationsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightconfiguration = floodlightconfiguration
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightConfigurationsUpdateCall) Fields(s ...googleapi.Field) *FloodlightConfigurationsUpdateCall {
	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 *FloodlightConfigurationsUpdateCall) Context(ctx context.Context) *FloodlightConfigurationsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightConfigurationsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightConfigurationsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.floodlightconfiguration)
	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, "userprofiles/{profileId}/floodlightConfigurations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightConfigurations.update" call.
// Exactly one of *FloodlightConfiguration or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightConfiguration.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightConfigurationsUpdateCall) Do(opts ...googleapi.CallOption) (*FloodlightConfiguration, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightConfiguration{
		ServerResponse: googleapi.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 configuration.",
	//   "flatPath": "userprofiles/{profileId}/floodlightConfigurations",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.floodlightConfigurations.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightConfigurations",
	//   "request": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "response": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.inventoryItems.get":

type InventoryItemsGetCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one inventory item by ID.
func (r *InventoryItemsService) Get(profileId int64, projectId int64, id int64) *InventoryItemsGetCall {
	c := &InventoryItemsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InventoryItemsGetCall) Fields(s ...googleapi.Field) *InventoryItemsGetCall {
	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 *InventoryItemsGetCall) IfNoneMatch(entityTag string) *InventoryItemsGetCall {
	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 *InventoryItemsGetCall) Context(ctx context.Context) *InventoryItemsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InventoryItemsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventoryItemsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/projects/{projectId}/inventoryItems/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"projectId": strconv.FormatInt(c.projectId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.inventoryItems.get" call.
// Exactly one of *InventoryItem or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InventoryItem.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InventoryItemsGetCall) Do(opts ...googleapi.CallOption) (*InventoryItem, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InventoryItem{
		ServerResponse: googleapi.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 one inventory item by ID.",
	//   "flatPath": "userprofiles/{profileId}/projects/{projectId}/inventoryItems/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.inventoryItems.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Inventory item ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID for order documents.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/inventoryItems/{id}",
	//   "response": {
	//     "$ref": "InventoryItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.inventoryItems.list":

type InventoryItemsListCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of inventory items, possibly filtered. This
// method supports paging.
func (r *InventoryItemsService) List(profileId int64, projectId int64) *InventoryItemsListCall {
	c := &InventoryItemsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	return c
}

// Ids sets the optional parameter "ids": Select only inventory items
// with these IDs.
func (c *InventoryItemsListCall) Ids(ids ...int64) *InventoryItemsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// InPlan sets the optional parameter "inPlan": Select only inventory
// items that are in plan.
func (c *InventoryItemsListCall) InPlan(inPlan bool) *InventoryItemsListCall {
	c.urlParams_.Set("inPlan", fmt.Sprint(inPlan))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *InventoryItemsListCall) MaxResults(maxResults int64) *InventoryItemsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderId sets the optional parameter "orderId": Select only inventory
// items that belong to specified orders.
func (c *InventoryItemsListCall) OrderId(orderId ...int64) *InventoryItemsListCall {
	var orderId_ []string
	for _, v := range orderId {
		orderId_ = append(orderId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("orderId", orderId_)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *InventoryItemsListCall) PageToken(pageToken string) *InventoryItemsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SiteId sets the optional parameter "siteId": Select only inventory
// items that are associated with these sites.
func (c *InventoryItemsListCall) SiteId(siteId ...int64) *InventoryItemsListCall {
	var siteId_ []string
	for _, v := range siteId {
		siteId_ = append(siteId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteId", siteId_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *InventoryItemsListCall) SortField(sortField string) *InventoryItemsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *InventoryItemsListCall) SortOrder(sortOrder string) *InventoryItemsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Type sets the optional parameter "type": Select only inventory items
// with this type.
//
// Possible values:
//   "PLANNING_PLACEMENT_TYPE_REGULAR"
//   "PLANNING_PLACEMENT_TYPE_CREDIT"
func (c *InventoryItemsListCall) Type(type_ string) *InventoryItemsListCall {
	c.urlParams_.Set("type", type_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *InventoryItemsListCall) Fields(s ...googleapi.Field) *InventoryItemsListCall {
	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 *InventoryItemsListCall) IfNoneMatch(entityTag string) *InventoryItemsListCall {
	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 *InventoryItemsListCall) Context(ctx context.Context) *InventoryItemsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InventoryItemsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventoryItemsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/projects/{projectId}/inventoryItems")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"projectId": strconv.FormatInt(c.projectId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.inventoryItems.list" call.
// Exactly one of *InventoryItemsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *InventoryItemsListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *InventoryItemsListCall) Do(opts ...googleapi.CallOption) (*InventoryItemsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &InventoryItemsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of inventory items, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/projects/{projectId}/inventoryItems",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.inventoryItems.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only inventory items with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "inPlan": {
	//       "description": "Select only inventory items that are in plan.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderId": {
	//       "description": "Select only inventory items that belong to specified orders.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID for order documents.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "siteId": {
	//       "description": "Select only inventory items that are associated with these sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Select only inventory items with this type.",
	//       "enum": [
	//         "PLANNING_PLACEMENT_TYPE_REGULAR",
	//         "PLANNING_PLACEMENT_TYPE_CREDIT"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/inventoryItems",
	//   "response": {
	//     "$ref": "InventoryItemsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *InventoryItemsListCall) Pages(ctx context.Context, f func(*InventoryItemsListResponse) 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 "dfareporting.languages.list":

type LanguagesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of languages.
func (r *LanguagesService) List(profileId int64) *LanguagesListCall {
	c := &LanguagesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LanguagesListCall) Fields(s ...googleapi.Field) *LanguagesListCall {
	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 *LanguagesListCall) IfNoneMatch(entityTag string) *LanguagesListCall {
	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 *LanguagesListCall) Context(ctx context.Context) *LanguagesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LanguagesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LanguagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/languages")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.languages.list" call.
// Exactly one of *LanguagesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LanguagesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LanguagesListCall) Do(opts ...googleapi.CallOption) (*LanguagesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LanguagesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of languages.",
	//   "flatPath": "userprofiles/{profileId}/languages",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.languages.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/languages",
	//   "response": {
	//     "$ref": "LanguagesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.metros.list":

type MetrosListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of metros.
func (r *MetrosService) List(profileId int64) *MetrosListCall {
	c := &MetrosListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MetrosListCall) Fields(s ...googleapi.Field) *MetrosListCall {
	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 *MetrosListCall) IfNoneMatch(entityTag string) *MetrosListCall {
	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 *MetrosListCall) Context(ctx context.Context) *MetrosListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MetrosListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MetrosListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/metros")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.metros.list" call.
// Exactly one of *MetrosListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *MetrosListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MetrosListCall) Do(opts ...googleapi.CallOption) (*MetrosListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MetrosListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of metros.",
	//   "flatPath": "userprofiles/{profileId}/metros",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.metros.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/metros",
	//   "response": {
	//     "$ref": "MetrosListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.mobileApps.get":

type MobileAppsGetCall struct {
	s            *Service
	profileId    int64
	id           string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one mobile app by ID.
func (r *MobileAppsService) Get(profileId int64, id string) *MobileAppsGetCall {
	c := &MobileAppsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MobileAppsGetCall) Fields(s ...googleapi.Field) *MobileAppsGetCall {
	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 *MobileAppsGetCall) IfNoneMatch(entityTag string) *MobileAppsGetCall {
	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 *MobileAppsGetCall) Context(ctx context.Context) *MobileAppsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MobileAppsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MobileAppsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/mobileApps/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        c.id,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.mobileApps.get" call.
// Exactly one of *MobileApp or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *MobileApp.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *MobileAppsGetCall) Do(opts ...googleapi.CallOption) (*MobileApp, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MobileApp{
		ServerResponse: googleapi.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 one mobile app by ID.",
	//   "flatPath": "userprofiles/{profileId}/mobileApps/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.mobileApps.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Mobile app ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/mobileApps/{id}",
	//   "response": {
	//     "$ref": "MobileApp"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.mobileApps.list":

type MobileAppsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves list of available mobile apps.
func (r *MobileAppsService) List(profileId int64) *MobileAppsListCall {
	c := &MobileAppsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Directories sets the optional parameter "directories": Select only
// apps from these directories.
//
// Possible values:
//   "UNKNOWN"
//   "APPLE_APP_STORE"
//   "GOOGLE_PLAY_STORE"
func (c *MobileAppsListCall) Directories(directories ...string) *MobileAppsListCall {
	c.urlParams_.SetMulti("directories", append([]string{}, directories...))
	return c
}

// Ids sets the optional parameter "ids": Select only apps with these
// IDs.
func (c *MobileAppsListCall) Ids(ids ...string) *MobileAppsListCall {
	c.urlParams_.SetMulti("ids", append([]string{}, ids...))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *MobileAppsListCall) MaxResults(maxResults int64) *MobileAppsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *MobileAppsListCall) PageToken(pageToken string) *MobileAppsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "app*2015" will return objects with names like "app Jan
// 2018", "app Jan 2018", or simply "app 2018". Most of the searches
// also add wildcards implicitly at the start and the end of the search
// string. For example, a search string of "app" will match objects with
// name "my app", "app 2018", or simply "app".
func (c *MobileAppsListCall) SearchString(searchString string) *MobileAppsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MobileAppsListCall) Fields(s ...googleapi.Field) *MobileAppsListCall {
	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 *MobileAppsListCall) IfNoneMatch(entityTag string) *MobileAppsListCall {
	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 *MobileAppsListCall) Context(ctx context.Context) *MobileAppsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MobileAppsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MobileAppsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/mobileApps")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.mobileApps.list" call.
// Exactly one of *MobileAppsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *MobileAppsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MobileAppsListCall) Do(opts ...googleapi.CallOption) (*MobileAppsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MobileAppsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves list of available mobile apps.",
	//   "flatPath": "userprofiles/{profileId}/mobileApps",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.mobileApps.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "directories": {
	//       "description": "Select only apps from these directories.",
	//       "enum": [
	//         "UNKNOWN",
	//         "APPLE_APP_STORE",
	//         "GOOGLE_PLAY_STORE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only apps with these IDs.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"app*2015\" will return objects with names like \"app Jan 2018\", \"app Jan 2018\", or simply \"app 2018\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"app\" will match objects with name \"my app\", \"app 2018\", or simply \"app\".",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/mobileApps",
	//   "response": {
	//     "$ref": "MobileAppsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *MobileAppsListCall) Pages(ctx context.Context, f func(*MobileAppsListResponse) 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 "dfareporting.mobileCarriers.get":

type MobileCarriersGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one mobile carrier by ID.
func (r *MobileCarriersService) Get(profileId int64, id int64) *MobileCarriersGetCall {
	c := &MobileCarriersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MobileCarriersGetCall) Fields(s ...googleapi.Field) *MobileCarriersGetCall {
	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 *MobileCarriersGetCall) IfNoneMatch(entityTag string) *MobileCarriersGetCall {
	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 *MobileCarriersGetCall) Context(ctx context.Context) *MobileCarriersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MobileCarriersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MobileCarriersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/mobileCarriers/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.mobileCarriers.get" call.
// Exactly one of *MobileCarrier or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *MobileCarrier.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MobileCarriersGetCall) Do(opts ...googleapi.CallOption) (*MobileCarrier, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MobileCarrier{
		ServerResponse: googleapi.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 one mobile carrier by ID.",
	//   "flatPath": "userprofiles/{profileId}/mobileCarriers/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.mobileCarriers.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Mobile carrier ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/mobileCarriers/{id}",
	//   "response": {
	//     "$ref": "MobileCarrier"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.mobileCarriers.list":

type MobileCarriersListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of mobile carriers.
func (r *MobileCarriersService) List(profileId int64) *MobileCarriersListCall {
	c := &MobileCarriersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MobileCarriersListCall) Fields(s ...googleapi.Field) *MobileCarriersListCall {
	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 *MobileCarriersListCall) IfNoneMatch(entityTag string) *MobileCarriersListCall {
	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 *MobileCarriersListCall) Context(ctx context.Context) *MobileCarriersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MobileCarriersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MobileCarriersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/mobileCarriers")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.mobileCarriers.list" call.
// Exactly one of *MobileCarriersListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *MobileCarriersListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MobileCarriersListCall) Do(opts ...googleapi.CallOption) (*MobileCarriersListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MobileCarriersListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of mobile carriers.",
	//   "flatPath": "userprofiles/{profileId}/mobileCarriers",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.mobileCarriers.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/mobileCarriers",
	//   "response": {
	//     "$ref": "MobileCarriersListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.operatingSystemVersions.get":

type OperatingSystemVersionsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one operating system version by ID.
func (r *OperatingSystemVersionsService) Get(profileId int64, id int64) *OperatingSystemVersionsGetCall {
	c := &OperatingSystemVersionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OperatingSystemVersionsGetCall) Fields(s ...googleapi.Field) *OperatingSystemVersionsGetCall {
	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 *OperatingSystemVersionsGetCall) IfNoneMatch(entityTag string) *OperatingSystemVersionsGetCall {
	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 *OperatingSystemVersionsGetCall) Context(ctx context.Context) *OperatingSystemVersionsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperatingSystemVersionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperatingSystemVersionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/operatingSystemVersions/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.operatingSystemVersions.get" call.
// Exactly one of *OperatingSystemVersion or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *OperatingSystemVersion.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OperatingSystemVersionsGetCall) Do(opts ...googleapi.CallOption) (*OperatingSystemVersion, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperatingSystemVersion{
		ServerResponse: googleapi.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 one operating system version by ID.",
	//   "flatPath": "userprofiles/{profileId}/operatingSystemVersions/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.operatingSystemVersions.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Operating system version ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/operatingSystemVersions/{id}",
	//   "response": {
	//     "$ref": "OperatingSystemVersion"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.operatingSystemVersions.list":

type OperatingSystemVersionsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of operating system versions.
func (r *OperatingSystemVersionsService) List(profileId int64) *OperatingSystemVersionsListCall {
	c := &OperatingSystemVersionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OperatingSystemVersionsListCall) Fields(s ...googleapi.Field) *OperatingSystemVersionsListCall {
	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 *OperatingSystemVersionsListCall) IfNoneMatch(entityTag string) *OperatingSystemVersionsListCall {
	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 *OperatingSystemVersionsListCall) Context(ctx context.Context) *OperatingSystemVersionsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperatingSystemVersionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperatingSystemVersionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/operatingSystemVersions")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.operatingSystemVersions.list" call.
// Exactly one of *OperatingSystemVersionsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *OperatingSystemVersionsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *OperatingSystemVersionsListCall) Do(opts ...googleapi.CallOption) (*OperatingSystemVersionsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperatingSystemVersionsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of operating system versions.",
	//   "flatPath": "userprofiles/{profileId}/operatingSystemVersions",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.operatingSystemVersions.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/operatingSystemVersions",
	//   "response": {
	//     "$ref": "OperatingSystemVersionsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.operatingSystems.get":

type OperatingSystemsGetCall struct {
	s            *Service
	profileId    int64
	dartId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one operating system by DART ID.
func (r *OperatingSystemsService) Get(profileId int64, dartId int64) *OperatingSystemsGetCall {
	c := &OperatingSystemsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.dartId = dartId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OperatingSystemsGetCall) Fields(s ...googleapi.Field) *OperatingSystemsGetCall {
	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 *OperatingSystemsGetCall) IfNoneMatch(entityTag string) *OperatingSystemsGetCall {
	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 *OperatingSystemsGetCall) Context(ctx context.Context) *OperatingSystemsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperatingSystemsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperatingSystemsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/operatingSystems/{dartId}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"dartId":    strconv.FormatInt(c.dartId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.operatingSystems.get" call.
// Exactly one of *OperatingSystem or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *OperatingSystem.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OperatingSystemsGetCall) Do(opts ...googleapi.CallOption) (*OperatingSystem, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperatingSystem{
		ServerResponse: googleapi.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 one operating system by DART ID.",
	//   "flatPath": "userprofiles/{profileId}/operatingSystems/{dartId}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.operatingSystems.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "dartId"
	//   ],
	//   "parameters": {
	//     "dartId": {
	//       "description": "Operating system DART ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/operatingSystems/{dartId}",
	//   "response": {
	//     "$ref": "OperatingSystem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.operatingSystems.list":

type OperatingSystemsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of operating systems.
func (r *OperatingSystemsService) List(profileId int64) *OperatingSystemsListCall {
	c := &OperatingSystemsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OperatingSystemsListCall) Fields(s ...googleapi.Field) *OperatingSystemsListCall {
	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 *OperatingSystemsListCall) IfNoneMatch(entityTag string) *OperatingSystemsListCall {
	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 *OperatingSystemsListCall) Context(ctx context.Context) *OperatingSystemsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperatingSystemsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperatingSystemsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/operatingSystems")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.operatingSystems.list" call.
// Exactly one of *OperatingSystemsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *OperatingSystemsListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OperatingSystemsListCall) Do(opts ...googleapi.CallOption) (*OperatingSystemsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperatingSystemsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of operating systems.",
	//   "flatPath": "userprofiles/{profileId}/operatingSystems",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.operatingSystems.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/operatingSystems",
	//   "response": {
	//     "$ref": "OperatingSystemsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.orderDocuments.get":

type OrderDocumentsGetCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one order document by ID.
func (r *OrderDocumentsService) Get(profileId int64, projectId int64, id int64) *OrderDocumentsGetCall {
	c := &OrderDocumentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrderDocumentsGetCall) Fields(s ...googleapi.Field) *OrderDocumentsGetCall {
	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 *OrderDocumentsGetCall) IfNoneMatch(entityTag string) *OrderDocumentsGetCall {
	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 *OrderDocumentsGetCall) Context(ctx context.Context) *OrderDocumentsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrderDocumentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrderDocumentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/projects/{projectId}/orderDocuments/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"projectId": strconv.FormatInt(c.projectId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.orderDocuments.get" call.
// Exactly one of *OrderDocument or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *OrderDocument.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OrderDocumentsGetCall) Do(opts ...googleapi.CallOption) (*OrderDocument, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OrderDocument{
		ServerResponse: googleapi.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 one order document by ID.",
	//   "flatPath": "userprofiles/{profileId}/projects/{projectId}/orderDocuments/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.orderDocuments.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Order document ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID for order documents.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/orderDocuments/{id}",
	//   "response": {
	//     "$ref": "OrderDocument"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.orderDocuments.list":

type OrderDocumentsListCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of order documents, possibly filtered. This
// method supports paging.
func (r *OrderDocumentsService) List(profileId int64, projectId int64) *OrderDocumentsListCall {
	c := &OrderDocumentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	return c
}

// Approved sets the optional parameter "approved": Select only order
// documents that have been approved by at least one user.
func (c *OrderDocumentsListCall) Approved(approved bool) *OrderDocumentsListCall {
	c.urlParams_.Set("approved", fmt.Sprint(approved))
	return c
}

// Ids sets the optional parameter "ids": Select only order documents
// with these IDs.
func (c *OrderDocumentsListCall) Ids(ids ...int64) *OrderDocumentsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *OrderDocumentsListCall) MaxResults(maxResults int64) *OrderDocumentsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderId sets the optional parameter "orderId": Select only order
// documents for specified orders.
func (c *OrderDocumentsListCall) OrderId(orderId ...int64) *OrderDocumentsListCall {
	var orderId_ []string
	for _, v := range orderId {
		orderId_ = append(orderId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("orderId", orderId_)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *OrderDocumentsListCall) PageToken(pageToken string) *OrderDocumentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for order documents by name or ID. Wildcards (*) are
// allowed. For example, "orderdocument*2015" will return order
// documents with names like "orderdocument June 2015", "orderdocument
// April 2015", or simply "orderdocument 2015". Most of the searches
// also add wildcards implicitly at the start and the end of the search
// string. For example, a search string of "orderdocument" will match
// order documents with name "my orderdocument", "orderdocument 2015",
// or simply "orderdocument".
func (c *OrderDocumentsListCall) SearchString(searchString string) *OrderDocumentsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SiteId sets the optional parameter "siteId": Select only order
// documents that are associated with these sites.
func (c *OrderDocumentsListCall) SiteId(siteId ...int64) *OrderDocumentsListCall {
	var siteId_ []string
	for _, v := range siteId {
		siteId_ = append(siteId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteId", siteId_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *OrderDocumentsListCall) SortField(sortField string) *OrderDocumentsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *OrderDocumentsListCall) SortOrder(sortOrder string) *OrderDocumentsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrderDocumentsListCall) Fields(s ...googleapi.Field) *OrderDocumentsListCall {
	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 *OrderDocumentsListCall) IfNoneMatch(entityTag string) *OrderDocumentsListCall {
	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 *OrderDocumentsListCall) Context(ctx context.Context) *OrderDocumentsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrderDocumentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrderDocumentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/projects/{projectId}/orderDocuments")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"projectId": strconv.FormatInt(c.projectId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.orderDocuments.list" call.
// Exactly one of *OrderDocumentsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *OrderDocumentsListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OrderDocumentsListCall) Do(opts ...googleapi.CallOption) (*OrderDocumentsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OrderDocumentsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of order documents, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/projects/{projectId}/orderDocuments",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.orderDocuments.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "approved": {
	//       "description": "Select only order documents that have been approved by at least one user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only order documents with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderId": {
	//       "description": "Select only order documents for specified orders.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID for order documents.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for order documents by name or ID. Wildcards (*) are allowed. For example, \"orderdocument*2015\" will return order documents with names like \"orderdocument June 2015\", \"orderdocument April 2015\", or simply \"orderdocument 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"orderdocument\" will match order documents with name \"my orderdocument\", \"orderdocument 2015\", or simply \"orderdocument\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "siteId": {
	//       "description": "Select only order documents that are associated with these sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/orderDocuments",
	//   "response": {
	//     "$ref": "OrderDocumentsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *OrderDocumentsListCall) Pages(ctx context.Context, f func(*OrderDocumentsListResponse) 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 "dfareporting.orders.get":

type OrdersGetCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one order by ID.
func (r *OrdersService) Get(profileId int64, projectId int64, id int64) *OrdersGetCall {
	c := &OrdersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrdersGetCall) Fields(s ...googleapi.Field) *OrdersGetCall {
	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 *OrdersGetCall) IfNoneMatch(entityTag string) *OrdersGetCall {
	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 *OrdersGetCall) Context(ctx context.Context) *OrdersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrdersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrdersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/projects/{projectId}/orders/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"projectId": strconv.FormatInt(c.projectId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.orders.get" call.
// Exactly one of *Order or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Order.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *OrdersGetCall) Do(opts ...googleapi.CallOption) (*Order, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Order{
		ServerResponse: googleapi.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 one order by ID.",
	//   "flatPath": "userprofiles/{profileId}/projects/{projectId}/orders/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.orders.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Order ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID for orders.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/orders/{id}",
	//   "response": {
	//     "$ref": "Order"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.orders.list":

type OrdersListCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of orders, possibly filtered. This method
// supports paging.
func (r *OrdersService) List(profileId int64, projectId int64) *OrdersListCall {
	c := &OrdersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	return c
}

// Ids sets the optional parameter "ids": Select only orders with these
// IDs.
func (c *OrdersListCall) Ids(ids ...int64) *OrdersListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *OrdersListCall) MaxResults(maxResults int64) *OrdersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *OrdersListCall) PageToken(pageToken string) *OrdersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for orders by name or ID. Wildcards (*) are allowed. For
// example, "order*2015" will return orders with names like "order June
// 2015", "order April 2015", or simply "order 2015". Most of the
// searches also add wildcards implicitly at the start and the end of
// the search string. For example, a search string of "order" will match
// orders with name "my order", "order 2015", or simply "order".
func (c *OrdersListCall) SearchString(searchString string) *OrdersListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SiteId sets the optional parameter "siteId": Select only orders that
// are associated with these site IDs.
func (c *OrdersListCall) SiteId(siteId ...int64) *OrdersListCall {
	var siteId_ []string
	for _, v := range siteId {
		siteId_ = append(siteId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteId", siteId_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *OrdersListCall) SortField(sortField string) *OrdersListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *OrdersListCall) SortOrder(sortOrder string) *OrdersListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OrdersListCall) Fields(s ...googleapi.Field) *OrdersListCall {
	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 *OrdersListCall) IfNoneMatch(entityTag string) *OrdersListCall {
	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 *OrdersListCall) Context(ctx context.Context) *OrdersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrdersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrdersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/projects/{projectId}/orders")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"projectId": strconv.FormatInt(c.projectId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.orders.list" call.
// Exactly one of *OrdersListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *OrdersListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OrdersListCall) Do(opts ...googleapi.CallOption) (*OrdersListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OrdersListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of orders, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/projects/{projectId}/orders",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.orders.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only orders with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID for orders.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for orders by name or ID. Wildcards (*) are allowed. For example, \"order*2015\" will return orders with names like \"order June 2015\", \"order April 2015\", or simply \"order 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"order\" will match orders with name \"my order\", \"order 2015\", or simply \"order\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "siteId": {
	//       "description": "Select only orders that are associated with these site IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/orders",
	//   "response": {
	//     "$ref": "OrdersListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *OrdersListCall) Pages(ctx context.Context, f func(*OrdersListResponse) 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 "dfareporting.placementGroups.get":

type PlacementGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one placement group by ID.
func (r *PlacementGroupsService) Get(profileId int64, id int64) *PlacementGroupsGetCall {
	c := &PlacementGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsGetCall) Fields(s ...googleapi.Field) *PlacementGroupsGetCall {
	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 *PlacementGroupsGetCall) IfNoneMatch(entityTag string) *PlacementGroupsGetCall {
	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 *PlacementGroupsGetCall) Context(ctx context.Context) *PlacementGroupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/placementGroups/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.get" call.
// Exactly one of *PlacementGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlacementGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsGetCall) Do(opts ...googleapi.CallOption) (*PlacementGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroup{
		ServerResponse: googleapi.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 one placement group by ID.",
	//   "flatPath": "userprofiles/{profileId}/placementGroups/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placementGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups/{id}",
	//   "response": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementGroups.insert":

type PlacementGroupsInsertCall struct {
	s              *Service
	profileId      int64
	placementgroup *PlacementGroup
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Insert: Inserts a new placement group.
func (r *PlacementGroupsService) Insert(profileId int64, placementgroup *PlacementGroup) *PlacementGroupsInsertCall {
	c := &PlacementGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementgroup = placementgroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsInsertCall) Fields(s ...googleapi.Field) *PlacementGroupsInsertCall {
	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 *PlacementGroupsInsertCall) Context(ctx context.Context) *PlacementGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placementgroup)
	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, "userprofiles/{profileId}/placementGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.insert" call.
// Exactly one of *PlacementGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlacementGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsInsertCall) Do(opts ...googleapi.CallOption) (*PlacementGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new placement group.",
	//   "flatPath": "userprofiles/{profileId}/placementGroups",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.placementGroups.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups",
	//   "request": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "response": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementGroups.list":

type PlacementGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of placement groups, possibly filtered. This
// method supports paging.
func (r *PlacementGroupsService) List(profileId int64) *PlacementGroupsListCall {
	c := &PlacementGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only placement groups that belong to these advertisers.
func (c *PlacementGroupsListCall) AdvertiserIds(advertiserIds ...int64) *PlacementGroupsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// placements. Don't set this field to select both archived and
// non-archived placements.
func (c *PlacementGroupsListCall) Archived(archived bool) *PlacementGroupsListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// placement groups that belong to these campaigns.
func (c *PlacementGroupsListCall) CampaignIds(campaignIds ...int64) *PlacementGroupsListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// ContentCategoryIds sets the optional parameter "contentCategoryIds":
// Select only placement groups that are associated with these content
// categories.
func (c *PlacementGroupsListCall) ContentCategoryIds(contentCategoryIds ...int64) *PlacementGroupsListCall {
	var contentCategoryIds_ []string
	for _, v := range contentCategoryIds {
		contentCategoryIds_ = append(contentCategoryIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("contentCategoryIds", contentCategoryIds_)
	return c
}

// DirectorySiteIds sets the optional parameter "directorySiteIds":
// Select only placement groups that are associated with these directory
// sites.
func (c *PlacementGroupsListCall) DirectorySiteIds(directorySiteIds ...int64) *PlacementGroupsListCall {
	var directorySiteIds_ []string
	for _, v := range directorySiteIds {
		directorySiteIds_ = append(directorySiteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("directorySiteIds", directorySiteIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only placement groups
// with these IDs.
func (c *PlacementGroupsListCall) Ids(ids ...int64) *PlacementGroupsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxEndDate sets the optional parameter "maxEndDate": Select only
// placements or placement groups whose end date is on or before the
// specified maxEndDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementGroupsListCall) MaxEndDate(maxEndDate string) *PlacementGroupsListCall {
	c.urlParams_.Set("maxEndDate", maxEndDate)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *PlacementGroupsListCall) MaxResults(maxResults int64) *PlacementGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// MaxStartDate sets the optional parameter "maxStartDate": Select only
// placements or placement groups whose start date is on or before the
// specified maxStartDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementGroupsListCall) MaxStartDate(maxStartDate string) *PlacementGroupsListCall {
	c.urlParams_.Set("maxStartDate", maxStartDate)
	return c
}

// MinEndDate sets the optional parameter "minEndDate": Select only
// placements or placement groups whose end date is on or after the
// specified minEndDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementGroupsListCall) MinEndDate(minEndDate string) *PlacementGroupsListCall {
	c.urlParams_.Set("minEndDate", minEndDate)
	return c
}

// MinStartDate sets the optional parameter "minStartDate": Select only
// placements or placement groups whose start date is on or after the
// specified minStartDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementGroupsListCall) MinStartDate(minStartDate string) *PlacementGroupsListCall {
	c.urlParams_.Set("minStartDate", minStartDate)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *PlacementGroupsListCall) PageToken(pageToken string) *PlacementGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PlacementGroupType sets the optional parameter "placementGroupType":
// Select only placement groups belonging with this group type. A
// package is a simple group of placements that acts as a single pricing
// point for a group of tags. A roadblock is a group of placements that
// not only acts as a single pricing point but also assumes that all the
// tags in it will be served at the same time. A roadblock requires one
// of its assigned placements to be marked as primary for reporting.
//
// Possible values:
//   "PLACEMENT_PACKAGE"
//   "PLACEMENT_ROADBLOCK"
func (c *PlacementGroupsListCall) PlacementGroupType(placementGroupType string) *PlacementGroupsListCall {
	c.urlParams_.Set("placementGroupType", placementGroupType)
	return c
}

// PlacementStrategyIds sets the optional parameter
// "placementStrategyIds": Select only placement groups that are
// associated with these placement strategies.
func (c *PlacementGroupsListCall) PlacementStrategyIds(placementStrategyIds ...int64) *PlacementGroupsListCall {
	var placementStrategyIds_ []string
	for _, v := range placementStrategyIds {
		placementStrategyIds_ = append(placementStrategyIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("placementStrategyIds", placementStrategyIds_)
	return c
}

// PricingTypes sets the optional parameter "pricingTypes": Select only
// placement groups with these pricing types.
//
// Possible values:
//   "PRICING_TYPE_CPM"
//   "PRICING_TYPE_CPC"
//   "PRICING_TYPE_CPA"
//   "PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
//   "PRICING_TYPE_FLAT_RATE_CLICKS"
//   "PRICING_TYPE_CPM_ACTIVEVIEW"
func (c *PlacementGroupsListCall) PricingTypes(pricingTypes ...string) *PlacementGroupsListCall {
	c.urlParams_.SetMulti("pricingTypes", append([]string{}, pricingTypes...))
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for placement groups by name or ID. Wildcards (*) are
// allowed. For example, "placement*2015" will return placement groups
// with names like "placement group June 2015", "placement group May
// 2015", or simply "placements 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "placementgroup" will match placement
// groups with name "my placementgroup", "placementgroup 2015", or
// simply "placementgroup".
func (c *PlacementGroupsListCall) SearchString(searchString string) *PlacementGroupsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SiteIds sets the optional parameter "siteIds": Select only placement
// groups that are associated with these sites.
func (c *PlacementGroupsListCall) SiteIds(siteIds ...int64) *PlacementGroupsListCall {
	var siteIds_ []string
	for _, v := range siteIds {
		siteIds_ = append(siteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteIds", siteIds_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *PlacementGroupsListCall) SortField(sortField string) *PlacementGroupsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *PlacementGroupsListCall) SortOrder(sortOrder string) *PlacementGroupsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsListCall) Fields(s ...googleapi.Field) *PlacementGroupsListCall {
	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 *PlacementGroupsListCall) IfNoneMatch(entityTag string) *PlacementGroupsListCall {
	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 *PlacementGroupsListCall) Context(ctx context.Context) *PlacementGroupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/placementGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.list" call.
// Exactly one of *PlacementGroupsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *PlacementGroupsListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsListCall) Do(opts ...googleapi.CallOption) (*PlacementGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placement groups, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/placementGroups",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placementGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only placement groups that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived placements. Don't set this field to select both archived and non-archived placements.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignIds": {
	//       "description": "Select only placement groups that belong to these campaigns.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "contentCategoryIds": {
	//       "description": "Select only placement groups that are associated with these content categories.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "directorySiteIds": {
	//       "description": "Select only placement groups that are associated with these directory sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only placement groups with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxEndDate": {
	//       "description": "Select only placements or placement groups whose end date is on or before the specified maxEndDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "800",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "800",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "maxStartDate": {
	//       "description": "Select only placements or placement groups whose start date is on or before the specified maxStartDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minEndDate": {
	//       "description": "Select only placements or placement groups whose end date is on or after the specified minEndDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minStartDate": {
	//       "description": "Select only placements or placement groups whose start date is on or after the specified minStartDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementGroupType": {
	//       "description": "Select only placement groups belonging with this group type. A package is a simple group of placements that acts as a single pricing point for a group of tags. A roadblock is a group of placements that not only acts as a single pricing point but also assumes that all the tags in it will be served at the same time. A roadblock requires one of its assigned placements to be marked as primary for reporting.",
	//       "enum": [
	//         "PLACEMENT_PACKAGE",
	//         "PLACEMENT_ROADBLOCK"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementStrategyIds": {
	//       "description": "Select only placement groups that are associated with these placement strategies.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pricingTypes": {
	//       "description": "Select only placement groups with these pricing types.",
	//       "enum": [
	//         "PRICING_TYPE_CPM",
	//         "PRICING_TYPE_CPC",
	//         "PRICING_TYPE_CPA",
	//         "PRICING_TYPE_FLAT_RATE_IMPRESSIONS",
	//         "PRICING_TYPE_FLAT_RATE_CLICKS",
	//         "PRICING_TYPE_CPM_ACTIVEVIEW"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for placement groups by name or ID. Wildcards (*) are allowed. For example, \"placement*2015\" will return placement groups with names like \"placement group June 2015\", \"placement group May 2015\", or simply \"placements 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"placementgroup\" will match placement groups with name \"my placementgroup\", \"placementgroup 2015\", or simply \"placementgroup\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "siteIds": {
	//       "description": "Select only placement groups that are associated with these sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups",
	//   "response": {
	//     "$ref": "PlacementGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *PlacementGroupsListCall) Pages(ctx context.Context, f func(*PlacementGroupsListResponse) 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 "dfareporting.placementGroups.patch":

type PlacementGroupsPatchCall struct {
	s              *Service
	profileId      int64
	placementgroup *PlacementGroup
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Patch: Updates an existing placement group. This method supports
// patch semantics.
func (r *PlacementGroupsService) Patch(profileId int64, placementgroup *PlacementGroup) *PlacementGroupsPatchCall {
	c := &PlacementGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementgroup = placementgroup
	return c
}

// Id sets the optional parameter "id": PlacementGroup ID.
func (c *PlacementGroupsPatchCall) Id(id int64) *PlacementGroupsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsPatchCall) Fields(s ...googleapi.Field) *PlacementGroupsPatchCall {
	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 *PlacementGroupsPatchCall) Context(ctx context.Context) *PlacementGroupsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placementgroup)
	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, "userprofiles/{profileId}/placementGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.patch" call.
// Exactly one of *PlacementGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlacementGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsPatchCall) Do(opts ...googleapi.CallOption) (*PlacementGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroup{
		ServerResponse: googleapi.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 placement group. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/placementGroups",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.placementGroups.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "PlacementGroup ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups",
	//   "request": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "response": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementGroups.update":

type PlacementGroupsUpdateCall struct {
	s              *Service
	profileId      int64
	placementgroup *PlacementGroup
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Update: Updates an existing placement group.
func (r *PlacementGroupsService) Update(profileId int64, placementgroup *PlacementGroup) *PlacementGroupsUpdateCall {
	c := &PlacementGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementgroup = placementgroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsUpdateCall) Fields(s ...googleapi.Field) *PlacementGroupsUpdateCall {
	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 *PlacementGroupsUpdateCall) Context(ctx context.Context) *PlacementGroupsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placementgroup)
	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, "userprofiles/{profileId}/placementGroups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.update" call.
// Exactly one of *PlacementGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlacementGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*PlacementGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroup{
		ServerResponse: googleapi.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 placement group.",
	//   "flatPath": "userprofiles/{profileId}/placementGroups",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.placementGroups.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups",
	//   "request": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "response": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.delete":

type PlacementStrategiesDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing placement strategy.
func (r *PlacementStrategiesService) Delete(profileId int64, id int64) *PlacementStrategiesDeleteCall {
	c := &PlacementStrategiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesDeleteCall) Fields(s ...googleapi.Field) *PlacementStrategiesDeleteCall {
	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 *PlacementStrategiesDeleteCall) Context(ctx context.Context) *PlacementStrategiesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/placementStrategies/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.delete" call.
func (c *PlacementStrategiesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing placement strategy.",
	//   "flatPath": "userprofiles/{profileId}/placementStrategies/{id}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.placementStrategies.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement strategy ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.get":

type PlacementStrategiesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one placement strategy by ID.
func (r *PlacementStrategiesService) Get(profileId int64, id int64) *PlacementStrategiesGetCall {
	c := &PlacementStrategiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesGetCall) Fields(s ...googleapi.Field) *PlacementStrategiesGetCall {
	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 *PlacementStrategiesGetCall) IfNoneMatch(entityTag string) *PlacementStrategiesGetCall {
	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 *PlacementStrategiesGetCall) Context(ctx context.Context) *PlacementStrategiesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/placementStrategies/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.get" call.
// Exactly one of *PlacementStrategy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementStrategy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesGetCall) Do(opts ...googleapi.CallOption) (*PlacementStrategy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategy{
		ServerResponse: googleapi.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 one placement strategy by ID.",
	//   "flatPath": "userprofiles/{profileId}/placementStrategies/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placementStrategies.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement strategy ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies/{id}",
	//   "response": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.insert":

type PlacementStrategiesInsertCall struct {
	s                 *Service
	profileId         int64
	placementstrategy *PlacementStrategy
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Insert: Inserts a new placement strategy.
func (r *PlacementStrategiesService) Insert(profileId int64, placementstrategy *PlacementStrategy) *PlacementStrategiesInsertCall {
	c := &PlacementStrategiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementstrategy = placementstrategy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesInsertCall) Fields(s ...googleapi.Field) *PlacementStrategiesInsertCall {
	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 *PlacementStrategiesInsertCall) Context(ctx context.Context) *PlacementStrategiesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placementstrategy)
	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, "userprofiles/{profileId}/placementStrategies")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.insert" call.
// Exactly one of *PlacementStrategy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementStrategy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesInsertCall) Do(opts ...googleapi.CallOption) (*PlacementStrategy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new placement strategy.",
	//   "flatPath": "userprofiles/{profileId}/placementStrategies",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.placementStrategies.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies",
	//   "request": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "response": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.list":

type PlacementStrategiesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of placement strategies, possibly filtered.
// This method supports paging.
func (r *PlacementStrategiesService) List(profileId int64) *PlacementStrategiesListCall {
	c := &PlacementStrategiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only placement
// strategies with these IDs.
func (c *PlacementStrategiesListCall) Ids(ids ...int64) *PlacementStrategiesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *PlacementStrategiesListCall) MaxResults(maxResults int64) *PlacementStrategiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *PlacementStrategiesListCall) PageToken(pageToken string) *PlacementStrategiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "placementstrategy*2015" will return objects with names like
// "placementstrategy June 2015", "placementstrategy April 2015", or
// simply "placementstrategy 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "placementstrategy" will match
// objects with name "my placementstrategy", "placementstrategy 2015",
// or simply "placementstrategy".
func (c *PlacementStrategiesListCall) SearchString(searchString string) *PlacementStrategiesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *PlacementStrategiesListCall) SortField(sortField string) *PlacementStrategiesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *PlacementStrategiesListCall) SortOrder(sortOrder string) *PlacementStrategiesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesListCall) Fields(s ...googleapi.Field) *PlacementStrategiesListCall {
	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 *PlacementStrategiesListCall) IfNoneMatch(entityTag string) *PlacementStrategiesListCall {
	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 *PlacementStrategiesListCall) Context(ctx context.Context) *PlacementStrategiesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/placementStrategies")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.list" call.
// Exactly one of *PlacementStrategiesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *PlacementStrategiesListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesListCall) Do(opts ...googleapi.CallOption) (*PlacementStrategiesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategiesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placement strategies, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/placementStrategies",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placementStrategies.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only placement strategies with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"placementstrategy*2015\" will return objects with names like \"placementstrategy June 2015\", \"placementstrategy April 2015\", or simply \"placementstrategy 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"placementstrategy\" will match objects with name \"my placementstrategy\", \"placementstrategy 2015\", or simply \"placementstrategy\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies",
	//   "response": {
	//     "$ref": "PlacementStrategiesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *PlacementStrategiesListCall) Pages(ctx context.Context, f func(*PlacementStrategiesListResponse) 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 "dfareporting.placementStrategies.patch":

type PlacementStrategiesPatchCall struct {
	s                 *Service
	profileId         int64
	placementstrategy *PlacementStrategy
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Patch: Updates an existing placement strategy. This method supports
// patch semantics.
func (r *PlacementStrategiesService) Patch(profileId int64, placementstrategy *PlacementStrategy) *PlacementStrategiesPatchCall {
	c := &PlacementStrategiesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementstrategy = placementstrategy
	return c
}

// Id sets the optional parameter "id": PlacementStrategy ID.
func (c *PlacementStrategiesPatchCall) Id(id int64) *PlacementStrategiesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesPatchCall) Fields(s ...googleapi.Field) *PlacementStrategiesPatchCall {
	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 *PlacementStrategiesPatchCall) Context(ctx context.Context) *PlacementStrategiesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placementstrategy)
	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, "userprofiles/{profileId}/placementStrategies")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.patch" call.
// Exactly one of *PlacementStrategy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementStrategy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesPatchCall) Do(opts ...googleapi.CallOption) (*PlacementStrategy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategy{
		ServerResponse: googleapi.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 placement strategy. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/placementStrategies",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.placementStrategies.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "PlacementStrategy ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies",
	//   "request": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "response": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.update":

type PlacementStrategiesUpdateCall struct {
	s                 *Service
	profileId         int64
	placementstrategy *PlacementStrategy
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Update: Updates an existing placement strategy.
func (r *PlacementStrategiesService) Update(profileId int64, placementstrategy *PlacementStrategy) *PlacementStrategiesUpdateCall {
	c := &PlacementStrategiesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementstrategy = placementstrategy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesUpdateCall) Fields(s ...googleapi.Field) *PlacementStrategiesUpdateCall {
	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 *PlacementStrategiesUpdateCall) Context(ctx context.Context) *PlacementStrategiesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placementstrategy)
	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, "userprofiles/{profileId}/placementStrategies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.update" call.
// Exactly one of *PlacementStrategy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementStrategy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesUpdateCall) Do(opts ...googleapi.CallOption) (*PlacementStrategy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategy{
		ServerResponse: googleapi.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 placement strategy.",
	//   "flatPath": "userprofiles/{profileId}/placementStrategies",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.placementStrategies.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies",
	//   "request": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "response": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.generatetags":

type PlacementsGeneratetagsCall struct {
	s          *Service
	profileId  int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Generatetags: Generates tags for a placement.
func (r *PlacementsService) Generatetags(profileId int64) *PlacementsGeneratetagsCall {
	c := &PlacementsGeneratetagsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// CampaignId sets the optional parameter "campaignId": Generate
// placements belonging to this campaign. This is a required field.
func (c *PlacementsGeneratetagsCall) CampaignId(campaignId int64) *PlacementsGeneratetagsCall {
	c.urlParams_.Set("campaignId", fmt.Sprint(campaignId))
	return c
}

// PlacementIds sets the optional parameter "placementIds": Generate
// tags for these placements.
func (c *PlacementsGeneratetagsCall) PlacementIds(placementIds ...int64) *PlacementsGeneratetagsCall {
	var placementIds_ []string
	for _, v := range placementIds {
		placementIds_ = append(placementIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("placementIds", placementIds_)
	return c
}

// TagFormats sets the optional parameter "tagFormats": Tag formats to
// generate for these placements. *Note:* PLACEMENT_TAG_STANDARD can
// only be generated for 1x1 placements.
//
// Possible values:
//   "PLACEMENT_TAG_STANDARD"
//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT"
//   "PLACEMENT_TAG_IFRAME_ILAYER"
//   "PLACEMENT_TAG_INTERNAL_REDIRECT"
//   "PLACEMENT_TAG_JAVASCRIPT"
//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT"
//   "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT"
//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT"
//   "PLACEMENT_TAG_CLICK_COMMANDS"
//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH"
//   "PLACEMENT_TAG_TRACKING"
//   "PLACEMENT_TAG_TRACKING_IFRAME"
//   "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3"
//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT_LEGACY"
//   "PLACEMENT_TAG_JAVASCRIPT_LEGACY"
//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT_LEGACY"
//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT_LEGACY"
//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_4"
func (c *PlacementsGeneratetagsCall) TagFormats(tagFormats ...string) *PlacementsGeneratetagsCall {
	c.urlParams_.SetMulti("tagFormats", append([]string{}, tagFormats...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsGeneratetagsCall) Fields(s ...googleapi.Field) *PlacementsGeneratetagsCall {
	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 *PlacementsGeneratetagsCall) Context(ctx context.Context) *PlacementsGeneratetagsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsGeneratetagsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsGeneratetagsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/placements/generatetags")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.generatetags" call.
// Exactly one of *PlacementsGenerateTagsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *PlacementsGenerateTagsResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementsGeneratetagsCall) Do(opts ...googleapi.CallOption) (*PlacementsGenerateTagsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementsGenerateTagsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generates tags for a placement.",
	//   "flatPath": "userprofiles/{profileId}/placements/generatetags",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.placements.generatetags",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Generate placements belonging to this campaign. This is a required field.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementIds": {
	//       "description": "Generate tags for these placements.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "tagFormats": {
	//       "description": "Tag formats to generate for these placements. *Note:* PLACEMENT_TAG_STANDARD can only be generated for 1x1 placements.",
	//       "enum": [
	//         "PLACEMENT_TAG_STANDARD",
	//         "PLACEMENT_TAG_IFRAME_JAVASCRIPT",
	//         "PLACEMENT_TAG_IFRAME_ILAYER",
	//         "PLACEMENT_TAG_INTERNAL_REDIRECT",
	//         "PLACEMENT_TAG_JAVASCRIPT",
	//         "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT",
	//         "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT",
	//         "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT",
	//         "PLACEMENT_TAG_CLICK_COMMANDS",
	//         "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH",
	//         "PLACEMENT_TAG_TRACKING",
	//         "PLACEMENT_TAG_TRACKING_IFRAME",
	//         "PLACEMENT_TAG_TRACKING_JAVASCRIPT",
	//         "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3",
	//         "PLACEMENT_TAG_IFRAME_JAVASCRIPT_LEGACY",
	//         "PLACEMENT_TAG_JAVASCRIPT_LEGACY",
	//         "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT_LEGACY",
	//         "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT_LEGACY",
	//         "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_4"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements/generatetags",
	//   "response": {
	//     "$ref": "PlacementsGenerateTagsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.get":

type PlacementsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one placement by ID.
func (r *PlacementsService) Get(profileId int64, id int64) *PlacementsGetCall {
	c := &PlacementsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsGetCall) Fields(s ...googleapi.Field) *PlacementsGetCall {
	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 *PlacementsGetCall) IfNoneMatch(entityTag string) *PlacementsGetCall {
	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 *PlacementsGetCall) Context(ctx context.Context) *PlacementsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/placements/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.get" call.
// Exactly one of *Placement or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Placement.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlacementsGetCall) Do(opts ...googleapi.CallOption) (*Placement, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Placement{
		ServerResponse: googleapi.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 one placement by ID.",
	//   "flatPath": "userprofiles/{profileId}/placements/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placements.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements/{id}",
	//   "response": {
	//     "$ref": "Placement"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.insert":

type PlacementsInsertCall struct {
	s          *Service
	profileId  int64
	placement  *Placement
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new placement.
func (r *PlacementsService) Insert(profileId int64, placement *Placement) *PlacementsInsertCall {
	c := &PlacementsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placement = placement
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsInsertCall) Fields(s ...googleapi.Field) *PlacementsInsertCall {
	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 *PlacementsInsertCall) Context(ctx context.Context) *PlacementsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placement)
	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, "userprofiles/{profileId}/placements")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.insert" call.
// Exactly one of *Placement or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Placement.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlacementsInsertCall) Do(opts ...googleapi.CallOption) (*Placement, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Placement{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new placement.",
	//   "flatPath": "userprofiles/{profileId}/placements",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.placements.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements",
	//   "request": {
	//     "$ref": "Placement"
	//   },
	//   "response": {
	//     "$ref": "Placement"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.list":

type PlacementsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of placements, possibly filtered. This method
// supports paging.
func (r *PlacementsService) List(profileId int64) *PlacementsListCall {
	c := &PlacementsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only placements that belong to these advertisers.
func (c *PlacementsListCall) AdvertiserIds(advertiserIds ...int64) *PlacementsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// placements. Don't set this field to select both archived and
// non-archived placements.
func (c *PlacementsListCall) Archived(archived bool) *PlacementsListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// placements that belong to these campaigns.
func (c *PlacementsListCall) CampaignIds(campaignIds ...int64) *PlacementsListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// Compatibilities sets the optional parameter "compatibilities": Select
// only placements that are associated with these compatibilities.
// DISPLAY and DISPLAY_INTERSTITIAL refer to rendering either on desktop
// or on mobile devices for regular or interstitial ads respectively.
// APP and APP_INTERSTITIAL are for rendering in mobile apps.
// IN_STREAM_VIDEO refers to rendering in in-stream video ads developed
// with the VAST standard.
//
// Possible values:
//   "DISPLAY"
//   "DISPLAY_INTERSTITIAL"
//   "APP"
//   "APP_INTERSTITIAL"
//   "IN_STREAM_VIDEO"
//   "IN_STREAM_AUDIO"
func (c *PlacementsListCall) Compatibilities(compatibilities ...string) *PlacementsListCall {
	c.urlParams_.SetMulti("compatibilities", append([]string{}, compatibilities...))
	return c
}

// ContentCategoryIds sets the optional parameter "contentCategoryIds":
// Select only placements that are associated with these content
// categories.
func (c *PlacementsListCall) ContentCategoryIds(contentCategoryIds ...int64) *PlacementsListCall {
	var contentCategoryIds_ []string
	for _, v := range contentCategoryIds {
		contentCategoryIds_ = append(contentCategoryIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("contentCategoryIds", contentCategoryIds_)
	return c
}

// DirectorySiteIds sets the optional parameter "directorySiteIds":
// Select only placements that are associated with these directory
// sites.
func (c *PlacementsListCall) DirectorySiteIds(directorySiteIds ...int64) *PlacementsListCall {
	var directorySiteIds_ []string
	for _, v := range directorySiteIds {
		directorySiteIds_ = append(directorySiteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("directorySiteIds", directorySiteIds_)
	return c
}

// GroupIds sets the optional parameter "groupIds": Select only
// placements that belong to these placement groups.
func (c *PlacementsListCall) GroupIds(groupIds ...int64) *PlacementsListCall {
	var groupIds_ []string
	for _, v := range groupIds {
		groupIds_ = append(groupIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("groupIds", groupIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only placements with
// these IDs.
func (c *PlacementsListCall) Ids(ids ...int64) *PlacementsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxEndDate sets the optional parameter "maxEndDate": Select only
// placements or placement groups whose end date is on or before the
// specified maxEndDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementsListCall) MaxEndDate(maxEndDate string) *PlacementsListCall {
	c.urlParams_.Set("maxEndDate", maxEndDate)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *PlacementsListCall) MaxResults(maxResults int64) *PlacementsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// MaxStartDate sets the optional parameter "maxStartDate": Select only
// placements or placement groups whose start date is on or before the
// specified maxStartDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementsListCall) MaxStartDate(maxStartDate string) *PlacementsListCall {
	c.urlParams_.Set("maxStartDate", maxStartDate)
	return c
}

// MinEndDate sets the optional parameter "minEndDate": Select only
// placements or placement groups whose end date is on or after the
// specified minEndDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementsListCall) MinEndDate(minEndDate string) *PlacementsListCall {
	c.urlParams_.Set("minEndDate", minEndDate)
	return c
}

// MinStartDate sets the optional parameter "minStartDate": Select only
// placements or placement groups whose start date is on or after the
// specified minStartDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementsListCall) MinStartDate(minStartDate string) *PlacementsListCall {
	c.urlParams_.Set("minStartDate", minStartDate)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *PlacementsListCall) PageToken(pageToken string) *PlacementsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PaymentSource sets the optional parameter "paymentSource": Select
// only placements with this payment source.
//
// Possible values:
//   "PLACEMENT_AGENCY_PAID"
//   "PLACEMENT_PUBLISHER_PAID"
func (c *PlacementsListCall) PaymentSource(paymentSource string) *PlacementsListCall {
	c.urlParams_.Set("paymentSource", paymentSource)
	return c
}

// PlacementStrategyIds sets the optional parameter
// "placementStrategyIds": Select only placements that are associated
// with these placement strategies.
func (c *PlacementsListCall) PlacementStrategyIds(placementStrategyIds ...int64) *PlacementsListCall {
	var placementStrategyIds_ []string
	for _, v := range placementStrategyIds {
		placementStrategyIds_ = append(placementStrategyIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("placementStrategyIds", placementStrategyIds_)
	return c
}

// PricingTypes sets the optional parameter "pricingTypes": Select only
// placements with these pricing types.
//
// Possible values:
//   "PRICING_TYPE_CPM"
//   "PRICING_TYPE_CPC"
//   "PRICING_TYPE_CPA"
//   "PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
//   "PRICING_TYPE_FLAT_RATE_CLICKS"
//   "PRICING_TYPE_CPM_ACTIVEVIEW"
func (c *PlacementsListCall) PricingTypes(pricingTypes ...string) *PlacementsListCall {
	c.urlParams_.SetMulti("pricingTypes", append([]string{}, pricingTypes...))
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for placements by name or ID. Wildcards (*) are allowed.
// For example, "placement*2015" will return placements with names like
// "placement June 2015", "placement May 2015", or simply "placements
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "placement" will match placements with name "my placement",
// "placement 2015", or simply "placement" .
func (c *PlacementsListCall) SearchString(searchString string) *PlacementsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SiteIds sets the optional parameter "siteIds": Select only placements
// that are associated with these sites.
func (c *PlacementsListCall) SiteIds(siteIds ...int64) *PlacementsListCall {
	var siteIds_ []string
	for _, v := range siteIds {
		siteIds_ = append(siteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteIds", siteIds_)
	return c
}

// SizeIds sets the optional parameter "sizeIds": Select only placements
// that are associated with these sizes.
func (c *PlacementsListCall) SizeIds(sizeIds ...int64) *PlacementsListCall {
	var sizeIds_ []string
	for _, v := range sizeIds {
		sizeIds_ = append(sizeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("sizeIds", sizeIds_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *PlacementsListCall) SortField(sortField string) *PlacementsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *PlacementsListCall) SortOrder(sortOrder string) *PlacementsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsListCall) Fields(s ...googleapi.Field) *PlacementsListCall {
	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 *PlacementsListCall) IfNoneMatch(entityTag string) *PlacementsListCall {
	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 *PlacementsListCall) Context(ctx context.Context) *PlacementsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/placements")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.list" call.
// Exactly one of *PlacementsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementsListCall) Do(opts ...googleapi.CallOption) (*PlacementsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placements, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/placements",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placements.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only placements that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived placements. Don't set this field to select both archived and non-archived placements.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignIds": {
	//       "description": "Select only placements that belong to these campaigns.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "compatibilities": {
	//       "description": "Select only placements that are associated with these compatibilities. DISPLAY and DISPLAY_INTERSTITIAL refer to rendering either on desktop or on mobile devices for regular or interstitial ads respectively. APP and APP_INTERSTITIAL are for rendering in mobile apps. IN_STREAM_VIDEO refers to rendering in in-stream video ads developed with the VAST standard.",
	//       "enum": [
	//         "DISPLAY",
	//         "DISPLAY_INTERSTITIAL",
	//         "APP",
	//         "APP_INTERSTITIAL",
	//         "IN_STREAM_VIDEO",
	//         "IN_STREAM_AUDIO"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "contentCategoryIds": {
	//       "description": "Select only placements that are associated with these content categories.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "directorySiteIds": {
	//       "description": "Select only placements that are associated with these directory sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "groupIds": {
	//       "description": "Select only placements that belong to these placement groups.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only placements with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxEndDate": {
	//       "description": "Select only placements or placement groups whose end date is on or before the specified maxEndDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "maxStartDate": {
	//       "description": "Select only placements or placement groups whose start date is on or before the specified maxStartDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minEndDate": {
	//       "description": "Select only placements or placement groups whose end date is on or after the specified minEndDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minStartDate": {
	//       "description": "Select only placements or placement groups whose start date is on or after the specified minStartDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "paymentSource": {
	//       "description": "Select only placements with this payment source.",
	//       "enum": [
	//         "PLACEMENT_AGENCY_PAID",
	//         "PLACEMENT_PUBLISHER_PAID"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementStrategyIds": {
	//       "description": "Select only placements that are associated with these placement strategies.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pricingTypes": {
	//       "description": "Select only placements with these pricing types.",
	//       "enum": [
	//         "PRICING_TYPE_CPM",
	//         "PRICING_TYPE_CPC",
	//         "PRICING_TYPE_CPA",
	//         "PRICING_TYPE_FLAT_RATE_IMPRESSIONS",
	//         "PRICING_TYPE_FLAT_RATE_CLICKS",
	//         "PRICING_TYPE_CPM_ACTIVEVIEW"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for placements by name or ID. Wildcards (*) are allowed. For example, \"placement*2015\" will return placements with names like \"placement June 2015\", \"placement May 2015\", or simply \"placements 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"placement\" will match placements with name \"my placement\", \"placement 2015\", or simply \"placement\" .",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "siteIds": {
	//       "description": "Select only placements that are associated with these sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sizeIds": {
	//       "description": "Select only placements that are associated with these sizes.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements",
	//   "response": {
	//     "$ref": "PlacementsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *PlacementsListCall) Pages(ctx context.Context, f func(*PlacementsListResponse) 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 "dfareporting.placements.patch":

type PlacementsPatchCall struct {
	s          *Service
	profileId  int64
	placement  *Placement
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing placement. This method supports patch
// semantics.
func (r *PlacementsService) Patch(profileId int64, placement *Placement) *PlacementsPatchCall {
	c := &PlacementsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placement = placement
	return c
}

// Id sets the optional parameter "id": Placement ID.
func (c *PlacementsPatchCall) Id(id int64) *PlacementsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsPatchCall) Fields(s ...googleapi.Field) *PlacementsPatchCall {
	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 *PlacementsPatchCall) Context(ctx context.Context) *PlacementsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placement)
	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, "userprofiles/{profileId}/placements")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.patch" call.
// Exactly one of *Placement or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Placement.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlacementsPatchCall) Do(opts ...googleapi.CallOption) (*Placement, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Placement{
		ServerResponse: googleapi.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 placement. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/placements",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.placements.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements",
	//   "request": {
	//     "$ref": "Placement"
	//   },
	//   "response": {
	//     "$ref": "Placement"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.update":

type PlacementsUpdateCall struct {
	s          *Service
	profileId  int64
	placement  *Placement
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing placement.
func (r *PlacementsService) Update(profileId int64, placement *Placement) *PlacementsUpdateCall {
	c := &PlacementsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placement = placement
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsUpdateCall) Fields(s ...googleapi.Field) *PlacementsUpdateCall {
	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 *PlacementsUpdateCall) Context(ctx context.Context) *PlacementsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.placement)
	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, "userprofiles/{profileId}/placements")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.update" call.
// Exactly one of *Placement or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Placement.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlacementsUpdateCall) Do(opts ...googleapi.CallOption) (*Placement, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Placement{
		ServerResponse: googleapi.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 placement.",
	//   "flatPath": "userprofiles/{profileId}/placements",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.placements.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements",
	//   "request": {
	//     "$ref": "Placement"
	//   },
	//   "response": {
	//     "$ref": "Placement"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.platformTypes.get":

type PlatformTypesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one platform type by ID.
func (r *PlatformTypesService) Get(profileId int64, id int64) *PlatformTypesGetCall {
	c := &PlatformTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlatformTypesGetCall) Fields(s ...googleapi.Field) *PlatformTypesGetCall {
	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 *PlatformTypesGetCall) IfNoneMatch(entityTag string) *PlatformTypesGetCall {
	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 *PlatformTypesGetCall) Context(ctx context.Context) *PlatformTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlatformTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlatformTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/platformTypes/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.platformTypes.get" call.
// Exactly one of *PlatformType or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlatformType.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlatformTypesGetCall) Do(opts ...googleapi.CallOption) (*PlatformType, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlatformType{
		ServerResponse: googleapi.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 one platform type by ID.",
	//   "flatPath": "userprofiles/{profileId}/platformTypes/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.platformTypes.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Platform type ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/platformTypes/{id}",
	//   "response": {
	//     "$ref": "PlatformType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.platformTypes.list":

type PlatformTypesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of platform types.
func (r *PlatformTypesService) List(profileId int64) *PlatformTypesListCall {
	c := &PlatformTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlatformTypesListCall) Fields(s ...googleapi.Field) *PlatformTypesListCall {
	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 *PlatformTypesListCall) IfNoneMatch(entityTag string) *PlatformTypesListCall {
	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 *PlatformTypesListCall) Context(ctx context.Context) *PlatformTypesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlatformTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlatformTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/platformTypes")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.platformTypes.list" call.
// Exactly one of *PlatformTypesListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *PlatformTypesListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlatformTypesListCall) Do(opts ...googleapi.CallOption) (*PlatformTypesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlatformTypesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of platform types.",
	//   "flatPath": "userprofiles/{profileId}/platformTypes",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.platformTypes.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/platformTypes",
	//   "response": {
	//     "$ref": "PlatformTypesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.postalCodes.get":

type PostalCodesGetCall struct {
	s            *Service
	profileId    int64
	code         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one postal code by ID.
func (r *PostalCodesService) Get(profileId int64, code string) *PostalCodesGetCall {
	c := &PostalCodesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.code = code
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PostalCodesGetCall) Fields(s ...googleapi.Field) *PostalCodesGetCall {
	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 *PostalCodesGetCall) IfNoneMatch(entityTag string) *PostalCodesGetCall {
	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 *PostalCodesGetCall) Context(ctx context.Context) *PostalCodesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PostalCodesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PostalCodesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/postalCodes/{code}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"code":      c.code,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.postalCodes.get" call.
// Exactly one of *PostalCode or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PostalCode.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PostalCodesGetCall) Do(opts ...googleapi.CallOption) (*PostalCode, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PostalCode{
		ServerResponse: googleapi.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 one postal code by ID.",
	//   "flatPath": "userprofiles/{profileId}/postalCodes/{code}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.postalCodes.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "code"
	//   ],
	//   "parameters": {
	//     "code": {
	//       "description": "Postal code ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/postalCodes/{code}",
	//   "response": {
	//     "$ref": "PostalCode"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.postalCodes.list":

type PostalCodesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of postal codes.
func (r *PostalCodesService) List(profileId int64) *PostalCodesListCall {
	c := &PostalCodesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PostalCodesListCall) Fields(s ...googleapi.Field) *PostalCodesListCall {
	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 *PostalCodesListCall) IfNoneMatch(entityTag string) *PostalCodesListCall {
	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 *PostalCodesListCall) Context(ctx context.Context) *PostalCodesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PostalCodesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PostalCodesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/postalCodes")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.postalCodes.list" call.
// Exactly one of *PostalCodesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PostalCodesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PostalCodesListCall) Do(opts ...googleapi.CallOption) (*PostalCodesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PostalCodesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of postal codes.",
	//   "flatPath": "userprofiles/{profileId}/postalCodes",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.postalCodes.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/postalCodes",
	//   "response": {
	//     "$ref": "PostalCodesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.projects.get":

type ProjectsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one project by ID.
func (r *ProjectsService) Get(profileId int64, id int64) *ProjectsGetCall {
	c := &ProjectsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsGetCall) Fields(s ...googleapi.Field) *ProjectsGetCall {
	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 *ProjectsGetCall) IfNoneMatch(entityTag string) *ProjectsGetCall {
	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 *ProjectsGetCall) Context(ctx context.Context) *ProjectsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/projects/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.projects.get" call.
// Exactly one of *Project or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Project.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ProjectsGetCall) Do(opts ...googleapi.CallOption) (*Project, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Project{
		ServerResponse: googleapi.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 one project by ID.",
	//   "flatPath": "userprofiles/{profileId}/projects/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.projects.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Project ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{id}",
	//   "response": {
	//     "$ref": "Project"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.projects.list":

type ProjectsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of projects, possibly filtered. This method
// supports paging .
func (r *ProjectsService) List(profileId int64) *ProjectsListCall {
	c := &ProjectsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only projects with these advertiser IDs.
func (c *ProjectsListCall) AdvertiserIds(advertiserIds ...int64) *ProjectsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only projects with
// these IDs.
func (c *ProjectsListCall) Ids(ids ...int64) *ProjectsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ProjectsListCall) MaxResults(maxResults int64) *ProjectsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *ProjectsListCall) PageToken(pageToken string) *ProjectsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for projects by name or ID. Wildcards (*) are allowed. For
// example, "project*2015" will return projects with names like "project
// June 2015", "project April 2015", or simply "project 2015". Most of
// the searches also add wildcards implicitly at the start and the end
// of the search string. For example, a search string of "project" will
// match projects with name "my project", "project 2015", or simply
// "project".
func (c *ProjectsListCall) SearchString(searchString string) *ProjectsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *ProjectsListCall) SortField(sortField string) *ProjectsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *ProjectsListCall) SortOrder(sortOrder string) *ProjectsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsListCall) Fields(s ...googleapi.Field) *ProjectsListCall {
	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 *ProjectsListCall) IfNoneMatch(entityTag string) *ProjectsListCall {
	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 *ProjectsListCall) Context(ctx context.Context) *ProjectsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/projects")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.projects.list" call.
// Exactly one of *ProjectsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ProjectsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ProjectsListCall) Do(opts ...googleapi.CallOption) (*ProjectsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ProjectsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of projects, possibly filtered. This method supports paging .",
	//   "flatPath": "userprofiles/{profileId}/projects",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.projects.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only projects with these advertiser IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only projects with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for projects by name or ID. Wildcards (*) are allowed. For example, \"project*2015\" will return projects with names like \"project June 2015\", \"project April 2015\", or simply \"project 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"project\" will match projects with name \"my project\", \"project 2015\", or simply \"project\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects",
	//   "response": {
	//     "$ref": "ProjectsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *ProjectsListCall) Pages(ctx context.Context, f func(*ProjectsListResponse) 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 "dfareporting.regions.list":

type RegionsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of regions.
func (r *RegionsService) List(profileId int64) *RegionsListCall {
	c := &RegionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionsListCall) Fields(s ...googleapi.Field) *RegionsListCall {
	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 *RegionsListCall) IfNoneMatch(entityTag string) *RegionsListCall {
	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 *RegionsListCall) Context(ctx context.Context) *RegionsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/regions")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.regions.list" call.
// Exactly one of *RegionsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RegionsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionsListCall) Do(opts ...googleapi.CallOption) (*RegionsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of regions.",
	//   "flatPath": "userprofiles/{profileId}/regions",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.regions.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/regions",
	//   "response": {
	//     "$ref": "RegionsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingListShares.get":

type RemarketingListSharesGetCall struct {
	s                 *Service
	profileId         int64
	remarketingListId int64
	urlParams_        gensupport.URLParams
	ifNoneMatch_      string
	ctx_              context.Context
	header_           http.Header
}

// Get: Gets one remarketing list share by remarketing list ID.
func (r *RemarketingListSharesService) Get(profileId int64, remarketingListId int64) *RemarketingListSharesGetCall {
	c := &RemarketingListSharesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketingListId = remarketingListId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RemarketingListSharesGetCall) Fields(s ...googleapi.Field) *RemarketingListSharesGetCall {
	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 *RemarketingListSharesGetCall) IfNoneMatch(entityTag string) *RemarketingListSharesGetCall {
	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 *RemarketingListSharesGetCall) Context(ctx context.Context) *RemarketingListSharesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListSharesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListSharesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/remarketingListShares/{remarketingListId}")
	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{
		"profileId":         strconv.FormatInt(c.profileId, 10),
		"remarketingListId": strconv.FormatInt(c.remarketingListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingListShares.get" call.
// Exactly one of *RemarketingListShare or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RemarketingListShare.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RemarketingListSharesGetCall) Do(opts ...googleapi.CallOption) (*RemarketingListShare, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RemarketingListShare{
		ServerResponse: googleapi.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 one remarketing list share by remarketing list ID.",
	//   "flatPath": "userprofiles/{profileId}/remarketingListShares/{remarketingListId}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.remarketingListShares.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "remarketingListId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "remarketingListId": {
	//       "description": "Remarketing list ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingListShares/{remarketingListId}",
	//   "response": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingListShares.patch":

type RemarketingListSharesPatchCall struct {
	s                    *Service
	profileId            int64
	remarketingListId    int64
	remarketinglistshare *RemarketingListShare
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Patch: Updates an existing remarketing list share. This method
// supports patch semantics.
func (r *RemarketingListSharesService) Patch(profileId int64, remarketingListId int64, remarketinglistshare *RemarketingListShare) *RemarketingListSharesPatchCall {
	c := &RemarketingListSharesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketingListId = remarketingListId
	c.remarketinglistshare = remarketinglistshare
	return c
}

// Id sets the optional parameter "id": RemarketingListShare ID.
func (c *RemarketingListSharesPatchCall) Id(id int64) *RemarketingListSharesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RemarketingListSharesPatchCall) Fields(s ...googleapi.Field) *RemarketingListSharesPatchCall {
	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 *RemarketingListSharesPatchCall) Context(ctx context.Context) *RemarketingListSharesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListSharesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListSharesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.remarketinglistshare)
	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, "userprofiles/{profileId}/remarketingLists/{remarketingListId}/remarketingListShares")
	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{
		"profileId":         strconv.FormatInt(c.profileId, 10),
		"remarketingListId": strconv.FormatInt(c.remarketingListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingListShares.patch" call.
// Exactly one of *RemarketingListShare or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RemarketingListShare.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RemarketingListSharesPatchCall) Do(opts ...googleapi.CallOption) (*RemarketingListShare, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RemarketingListShare{
		ServerResponse: googleapi.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 remarketing list share. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/remarketingLists/{remarketingListId}/remarketingListShares",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.remarketingListShares.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "remarketingListId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "RemarketingListShare ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "remarketingListId": {
	//       "description": "RemarketingList ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists/{remarketingListId}/remarketingListShares",
	//   "request": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "response": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingListShares.update":

type RemarketingListSharesUpdateCall struct {
	s                    *Service
	profileId            int64
	remarketinglistshare *RemarketingListShare
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Update: Updates an existing remarketing list share.
func (r *RemarketingListSharesService) Update(profileId int64, remarketinglistshare *RemarketingListShare) *RemarketingListSharesUpdateCall {
	c := &RemarketingListSharesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketinglistshare = remarketinglistshare
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RemarketingListSharesUpdateCall) Fields(s ...googleapi.Field) *RemarketingListSharesUpdateCall {
	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 *RemarketingListSharesUpdateCall) Context(ctx context.Context) *RemarketingListSharesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListSharesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListSharesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.remarketinglistshare)
	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, "userprofiles/{profileId}/remarketingListShares")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingListShares.update" call.
// Exactly one of *RemarketingListShare or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RemarketingListShare.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RemarketingListSharesUpdateCall) Do(opts ...googleapi.CallOption) (*RemarketingListShare, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RemarketingListShare{
		ServerResponse: googleapi.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 remarketing list share.",
	//   "flatPath": "userprofiles/{profileId}/remarketingListShares",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.remarketingListShares.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingListShares",
	//   "request": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "response": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingLists.get":

type RemarketingListsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one remarketing list by ID.
func (r *RemarketingListsService) Get(profileId int64, id int64) *RemarketingListsGetCall {
	c := &RemarketingListsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RemarketingListsGetCall) Fields(s ...googleapi.Field) *RemarketingListsGetCall {
	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 *RemarketingListsGetCall) IfNoneMatch(entityTag string) *RemarketingListsGetCall {
	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 *RemarketingListsGetCall) Context(ctx context.Context) *RemarketingListsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/remarketingLists/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingLists.get" call.
// Exactly one of *RemarketingList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RemarketingList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RemarketingListsGetCall) Do(opts ...googleapi.CallOption) (*RemarketingList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RemarketingList{
		ServerResponse: googleapi.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 one remarketing list by ID.",
	//   "flatPath": "userprofiles/{profileId}/remarketingLists/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.remarketingLists.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Remarketing list ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists/{id}",
	//   "response": {
	//     "$ref": "RemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingLists.insert":

type RemarketingListsInsertCall struct {
	s               *Service
	profileId       int64
	remarketinglist *RemarketingList
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Insert: Inserts a new remarketing list.
func (r *RemarketingListsService) Insert(profileId int64, remarketinglist *RemarketingList) *RemarketingListsInsertCall {
	c := &RemarketingListsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketinglist = remarketinglist
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RemarketingListsInsertCall) Fields(s ...googleapi.Field) *RemarketingListsInsertCall {
	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 *RemarketingListsInsertCall) Context(ctx context.Context) *RemarketingListsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.remarketinglist)
	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, "userprofiles/{profileId}/remarketingLists")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingLists.insert" call.
// Exactly one of *RemarketingList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RemarketingList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RemarketingListsInsertCall) Do(opts ...googleapi.CallOption) (*RemarketingList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RemarketingList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new remarketing list.",
	//   "flatPath": "userprofiles/{profileId}/remarketingLists",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.remarketingLists.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists",
	//   "request": {
	//     "$ref": "RemarketingList"
	//   },
	//   "response": {
	//     "$ref": "RemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingLists.list":

type RemarketingListsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of remarketing lists, possibly filtered. This
// method supports paging.
func (r *RemarketingListsService) List(profileId int64, advertiserId int64) *RemarketingListsListCall {
	c := &RemarketingListsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Active sets the optional parameter "active": Select only active or
// only inactive remarketing lists.
func (c *RemarketingListsListCall) Active(active bool) *RemarketingListsListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// FloodlightActivityId sets the optional parameter
// "floodlightActivityId": Select only remarketing lists that have this
// floodlight activity ID.
func (c *RemarketingListsListCall) FloodlightActivityId(floodlightActivityId int64) *RemarketingListsListCall {
	c.urlParams_.Set("floodlightActivityId", fmt.Sprint(floodlightActivityId))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *RemarketingListsListCall) MaxResults(maxResults int64) *RemarketingListsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Name sets the optional parameter "name": Allows searching for objects
// by name or ID. Wildcards (*) are allowed. For example, "remarketing
// list*2015" will return objects with names like "remarketing list June
// 2015", "remarketing list April 2015", or simply "remarketing list
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "remarketing list" will match objects with name "my remarketing
// list", "remarketing list 2015", or simply "remarketing list".
func (c *RemarketingListsListCall) Name(name string) *RemarketingListsListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *RemarketingListsListCall) PageToken(pageToken string) *RemarketingListsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *RemarketingListsListCall) SortField(sortField string) *RemarketingListsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *RemarketingListsListCall) SortOrder(sortOrder string) *RemarketingListsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RemarketingListsListCall) Fields(s ...googleapi.Field) *RemarketingListsListCall {
	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 *RemarketingListsListCall) IfNoneMatch(entityTag string) *RemarketingListsListCall {
	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 *RemarketingListsListCall) Context(ctx context.Context) *RemarketingListsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/remarketingLists")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingLists.list" call.
// Exactly one of *RemarketingListsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *RemarketingListsListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RemarketingListsListCall) Do(opts ...googleapi.CallOption) (*RemarketingListsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RemarketingListsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of remarketing lists, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/remarketingLists",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.remarketingLists.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active or only inactive remarketing lists.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "advertiserId": {
	//       "description": "Select only remarketing lists owned by this advertiser.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "floodlightActivityId": {
	//       "description": "Select only remarketing lists that have this floodlight activity ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"remarketing list*2015\" will return objects with names like \"remarketing list June 2015\", \"remarketing list April 2015\", or simply \"remarketing list 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"remarketing list\" will match objects with name \"my remarketing list\", \"remarketing list 2015\", or simply \"remarketing list\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists",
	//   "response": {
	//     "$ref": "RemarketingListsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *RemarketingListsListCall) Pages(ctx context.Context, f func(*RemarketingListsListResponse) 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 "dfareporting.remarketingLists.patch":

type RemarketingListsPatchCall struct {
	s               *Service
	profileId       int64
	remarketinglist *RemarketingList
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Patch: Updates an existing remarketing list. This method supports
// patch semantics.
func (r *RemarketingListsService) Patch(profileId int64, remarketinglist *RemarketingList) *RemarketingListsPatchCall {
	c := &RemarketingListsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketinglist = remarketinglist
	return c
}

// Id sets the optional parameter "id": RemarketingList ID.
func (c *RemarketingListsPatchCall) Id(id int64) *RemarketingListsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RemarketingListsPatchCall) Fields(s ...googleapi.Field) *RemarketingListsPatchCall {
	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 *RemarketingListsPatchCall) Context(ctx context.Context) *RemarketingListsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.remarketinglist)
	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, "userprofiles/{profileId}/remarketingLists")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingLists.patch" call.
// Exactly one of *RemarketingList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RemarketingList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RemarketingListsPatchCall) Do(opts ...googleapi.CallOption) (*RemarketingList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RemarketingList{
		ServerResponse: googleapi.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 remarketing list. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/remarketingLists",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.remarketingLists.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "RemarketingList ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists",
	//   "request": {
	//     "$ref": "RemarketingList"
	//   },
	//   "response": {
	//     "$ref": "RemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingLists.update":

type RemarketingListsUpdateCall struct {
	s               *Service
	profileId       int64
	remarketinglist *RemarketingList
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Update: Updates an existing remarketing list.
func (r *RemarketingListsService) Update(profileId int64, remarketinglist *RemarketingList) *RemarketingListsUpdateCall {
	c := &RemarketingListsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketinglist = remarketinglist
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RemarketingListsUpdateCall) Fields(s ...googleapi.Field) *RemarketingListsUpdateCall {
	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 *RemarketingListsUpdateCall) Context(ctx context.Context) *RemarketingListsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.remarketinglist)
	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, "userprofiles/{profileId}/remarketingLists")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingLists.update" call.
// Exactly one of *RemarketingList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RemarketingList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RemarketingListsUpdateCall) Do(opts ...googleapi.CallOption) (*RemarketingList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RemarketingList{
		ServerResponse: googleapi.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 remarketing list.",
	//   "flatPath": "userprofiles/{profileId}/remarketingLists",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.remarketingLists.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists",
	//   "request": {
	//     "$ref": "RemarketingList"
	//   },
	//   "response": {
	//     "$ref": "RemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.reports.delete":

type ReportsDeleteCall struct {
	s          *Service
	profileId  int64
	reportId   int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a report by its ID.
func (r *ReportsService) Delete(profileId int64, reportId int64) *ReportsDeleteCall {
	c := &ReportsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsDeleteCall) Fields(s ...googleapi.Field) *ReportsDeleteCall {
	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 *ReportsDeleteCall) Context(ctx context.Context) *ReportsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/reports/{reportId}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.delete" call.
func (c *ReportsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a report by its ID.",
	//   "flatPath": "userprofiles/{profileId}/reports/{reportId}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.reports.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.get":

type ReportsGetCall struct {
	s            *Service
	profileId    int64
	reportId     int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves a report by its ID.
func (r *ReportsService) Get(profileId int64, reportId int64) *ReportsGetCall {
	c := &ReportsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsGetCall) Fields(s ...googleapi.Field) *ReportsGetCall {
	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 *ReportsGetCall) IfNoneMatch(entityTag string) *ReportsGetCall {
	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 *ReportsGetCall) Context(ctx context.Context) *ReportsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/reports/{reportId}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.get" call.
// Exactly one of *Report or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Report.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReportsGetCall) Do(opts ...googleapi.CallOption) (*Report, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Report{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a report by its ID.",
	//   "flatPath": "userprofiles/{profileId}/reports/{reportId}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}",
	//   "response": {
	//     "$ref": "Report"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.insert":

type ReportsInsertCall struct {
	s          *Service
	profileId  int64
	report     *Report
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a report.
func (r *ReportsService) Insert(profileId int64, report *Report) *ReportsInsertCall {
	c := &ReportsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.report = report
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsInsertCall) Fields(s ...googleapi.Field) *ReportsInsertCall {
	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 *ReportsInsertCall) Context(ctx context.Context) *ReportsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.report)
	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, "userprofiles/{profileId}/reports")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.insert" call.
// Exactly one of *Report or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Report.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReportsInsertCall) Do(opts ...googleapi.CallOption) (*Report, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Report{
		ServerResponse: googleapi.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 report.",
	//   "flatPath": "userprofiles/{profileId}/reports",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.reports.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports",
	//   "request": {
	//     "$ref": "Report"
	//   },
	//   "response": {
	//     "$ref": "Report"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.list":

type ReportsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves list of reports.
func (r *ReportsService) List(profileId int64) *ReportsListCall {
	c := &ReportsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ReportsListCall) MaxResults(maxResults int64) *ReportsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The value of the
// nextToken from the previous result page.
func (c *ReportsListCall) PageToken(pageToken string) *ReportsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Scope sets the optional parameter "scope": The scope that defines
// which results are returned.
//
// Possible values:
//   "ALL" - All reports in account.
//   "MINE" (default) - My reports.
func (c *ReportsListCall) Scope(scope string) *ReportsListCall {
	c.urlParams_.Set("scope", scope)
	return c
}

// SortField sets the optional parameter "sortField": The field by which
// to sort the list.
//
// Possible values:
//   "ID" - Sort by report ID.
//   "LAST_MODIFIED_TIME" (default) - Sort by 'lastModifiedTime' field.
//   "NAME" - Sort by name of reports.
func (c *ReportsListCall) SortField(sortField string) *ReportsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" - Ascending order.
//   "DESCENDING" (default) - Descending order.
func (c *ReportsListCall) SortOrder(sortOrder string) *ReportsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsListCall) Fields(s ...googleapi.Field) *ReportsListCall {
	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 *ReportsListCall) IfNoneMatch(entityTag string) *ReportsListCall {
	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 *ReportsListCall) Context(ctx context.Context) *ReportsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/reports")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.list" call.
// Exactly one of *ReportList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ReportList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ReportsListCall) Do(opts ...googleapi.CallOption) (*ReportList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ReportList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves list of reports.",
	//   "flatPath": "userprofiles/{profileId}/reports",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "default": "10",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "10",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value of the nextToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "scope": {
	//       "default": "MINE",
	//       "description": "The scope that defines which results are returned.",
	//       "enum": [
	//         "ALL",
	//         "MINE"
	//       ],
	//       "enumDescriptions": [
	//         "All reports in account.",
	//         "My reports."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "LAST_MODIFIED_TIME",
	//       "description": "The field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "LAST_MODIFIED_TIME",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "Sort by report ID.",
	//         "Sort by 'lastModifiedTime' field.",
	//         "Sort by name of reports."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "DESCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "Ascending order.",
	//         "Descending order."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports",
	//   "response": {
	//     "$ref": "ReportList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// 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 *ReportsListCall) Pages(ctx context.Context, f func(*ReportList) 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 "dfareporting.reports.patch":

type ReportsPatchCall struct {
	s          *Service
	profileId  int64
	reportId   int64
	report     *Report
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing report. This method supports patch
// semantics.
func (r *ReportsService) Patch(profileId int64, reportId int64, report *Report) *ReportsPatchCall {
	c := &ReportsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	c.report = report
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsPatchCall) Fields(s ...googleapi.Field) *ReportsPatchCall {
	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 *ReportsPatchCall) Context(ctx context.Context) *ReportsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.report)
	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, "userprofiles/{profileId}/reports/{reportId}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.patch" call.
// Exactly one of *Report or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Report.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReportsPatchCall) Do(opts ...googleapi.CallOption) (*Report, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Report{
		ServerResponse: googleapi.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 report. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/reports/{reportId}",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.reports.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}",
	//   "request": {
	//     "$ref": "Report"
	//   },
	//   "response": {
	//     "$ref": "Report"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.run":

type ReportsRunCall struct {
	s          *Service
	profileId  int64
	reportId   int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Run: Runs a report.
func (r *ReportsService) Run(profileId int64, reportId int64) *ReportsRunCall {
	c := &ReportsRunCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	return c
}

// Synchronous sets the optional parameter "synchronous": If set and
// true, tries to run the report synchronously.
func (c *ReportsRunCall) Synchronous(synchronous bool) *ReportsRunCall {
	c.urlParams_.Set("synchronous", fmt.Sprint(synchronous))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsRunCall) Fields(s ...googleapi.Field) *ReportsRunCall {
	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 *ReportsRunCall) Context(ctx context.Context) *ReportsRunCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsRunCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsRunCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/reports/{reportId}/run")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.run" call.
// Exactly one of *File or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *File.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ReportsRunCall) Do(opts ...googleapi.CallOption) (*File, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &File{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Runs a report.",
	//   "flatPath": "userprofiles/{profileId}/reports/{reportId}/run",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.reports.run",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "synchronous": {
	//       "default": "false",
	//       "description": "If set and true, tries to run the report synchronously.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}/run",
	//   "response": {
	//     "$ref": "File"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.update":

type ReportsUpdateCall struct {
	s          *Service
	profileId  int64
	reportId   int64
	report     *Report
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates a report.
func (r *ReportsService) Update(profileId int64, reportId int64, report *Report) *ReportsUpdateCall {
	c := &ReportsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	c.report = report
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsUpdateCall) Fields(s ...googleapi.Field) *ReportsUpdateCall {
	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 *ReportsUpdateCall) Context(ctx context.Context) *ReportsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.report)
	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, "userprofiles/{profileId}/reports/{reportId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.update" call.
// Exactly one of *Report or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Report.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReportsUpdateCall) Do(opts ...googleapi.CallOption) (*Report, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Report{
		ServerResponse: googleapi.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 report.",
	//   "flatPath": "userprofiles/{profileId}/reports/{reportId}",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.reports.update",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}",
	//   "request": {
	//     "$ref": "Report"
	//   },
	//   "response": {
	//     "$ref": "Report"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.compatibleFields.query":

type ReportsCompatibleFieldsQueryCall struct {
	s          *Service
	profileId  int64
	report     *Report
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Query: Returns the fields that are compatible to be selected in the
// respective sections of a report criteria, given the fields already
// selected in the input report and user permissions.
func (r *ReportsCompatibleFieldsService) Query(profileId int64, report *Report) *ReportsCompatibleFieldsQueryCall {
	c := &ReportsCompatibleFieldsQueryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.report = report
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsCompatibleFieldsQueryCall) Fields(s ...googleapi.Field) *ReportsCompatibleFieldsQueryCall {
	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 *ReportsCompatibleFieldsQueryCall) Context(ctx context.Context) *ReportsCompatibleFieldsQueryCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsCompatibleFieldsQueryCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsCompatibleFieldsQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.report)
	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, "userprofiles/{profileId}/reports/compatiblefields/query")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.compatibleFields.query" call.
// Exactly one of *CompatibleFields or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CompatibleFields.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ReportsCompatibleFieldsQueryCall) Do(opts ...googleapi.CallOption) (*CompatibleFields, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CompatibleFields{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the fields that are compatible to be selected in the respective sections of a report criteria, given the fields already selected in the input report and user permissions.",
	//   "flatPath": "userprofiles/{profileId}/reports/compatiblefields/query",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.reports.compatibleFields.query",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/compatiblefields/query",
	//   "request": {
	//     "$ref": "Report"
	//   },
	//   "response": {
	//     "$ref": "CompatibleFields"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.files.get":

type ReportsFilesGetCall struct {
	s            *Service
	profileId    int64
	reportId     int64
	fileId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves a report file by its report ID and file ID. This
// method supports media download.
func (r *ReportsFilesService) Get(profileId int64, reportId int64, fileId int64) *ReportsFilesGetCall {
	c := &ReportsFilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	c.fileId = fileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsFilesGetCall) Fields(s ...googleapi.Field) *ReportsFilesGetCall {
	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 *ReportsFilesGetCall) IfNoneMatch(entityTag string) *ReportsFilesGetCall {
	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 *ReportsFilesGetCall) Context(ctx context.Context) *ReportsFilesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsFilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsFilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/reports/{reportId}/files/{fileId}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
		"fileId":    strconv.FormatInt(c.fileId, 10),
	})
	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 *ReportsFilesGetCall) 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 "dfareporting.reports.files.get" call.
// Exactly one of *File or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *File.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ReportsFilesGetCall) Do(opts ...googleapi.CallOption) (*File, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &File{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a report file by its report ID and file ID. This method supports media download.",
	//   "flatPath": "userprofiles/{profileId}/reports/{reportId}/files/{fileId}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.files.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId",
	//     "fileId"
	//   ],
	//   "parameters": {
	//     "fileId": {
	//       "description": "The ID of the report file.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}/files/{fileId}",
	//   "response": {
	//     "$ref": "File"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ],
	//   "supportsMediaDownload": true
	// }

}

// method id "dfareporting.reports.files.list":

type ReportsFilesListCall struct {
	s            *Service
	profileId    int64
	reportId     int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists files for a report.
func (r *ReportsFilesService) List(profileId int64, reportId int64) *ReportsFilesListCall {
	c := &ReportsFilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ReportsFilesListCall) MaxResults(maxResults int64) *ReportsFilesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The value of the
// nextToken from the previous result page.
func (c *ReportsFilesListCall) PageToken(pageToken string) *ReportsFilesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortField sets the optional parameter "sortField": The field by which
// to sort the list.
//
// Possible values:
//   "ID"
//   "LAST_MODIFIED_TIME" (default)
func (c *ReportsFilesListCall) SortField(sortField string) *ReportsFilesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING" (default)
func (c *ReportsFilesListCall) SortOrder(sortOrder string) *ReportsFilesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsFilesListCall) Fields(s ...googleapi.Field) *ReportsFilesListCall {
	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 *ReportsFilesListCall) IfNoneMatch(entityTag string) *ReportsFilesListCall {
	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 *ReportsFilesListCall) Context(ctx context.Context) *ReportsFilesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsFilesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsFilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/reports/{reportId}/files")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.files.list" call.
// Exactly one of *FileList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *FileList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ReportsFilesListCall) Do(opts ...googleapi.CallOption) (*FileList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FileList{
		ServerResponse: googleapi.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 files for a report.",
	//   "flatPath": "userprofiles/{profileId}/reports/{reportId}/files",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.files.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "default": "10",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "10",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value of the nextToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the parent report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "LAST_MODIFIED_TIME",
	//       "description": "The field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "LAST_MODIFIED_TIME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "DESCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}/files",
	//   "response": {
	//     "$ref": "FileList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// 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 *ReportsFilesListCall) Pages(ctx context.Context, f func(*FileList) 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 "dfareporting.sites.get":

type SitesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one site by ID.
func (r *SitesService) Get(profileId int64, id int64) *SitesGetCall {
	c := &SitesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesGetCall) Fields(s ...googleapi.Field) *SitesGetCall {
	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 *SitesGetCall) IfNoneMatch(entityTag string) *SitesGetCall {
	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 *SitesGetCall) Context(ctx context.Context) *SitesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/sites/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.get" 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 *SitesGetCall) 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": "Gets one site by ID.",
	//   "flatPath": "userprofiles/{profileId}/sites/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.sites.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Site ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites/{id}",
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sites.insert":

type SitesInsertCall struct {
	s          *Service
	profileId  int64
	site       *Site
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new site.
func (r *SitesService) Insert(profileId int64, site *Site) *SitesInsertCall {
	c := &SitesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.site = site
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesInsertCall) Fields(s ...googleapi.Field) *SitesInsertCall {
	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 *SitesInsertCall) Context(ctx context.Context) *SitesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.insert" 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 *SitesInsertCall) 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": "Inserts a new site.",
	//   "flatPath": "userprofiles/{profileId}/sites",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.sites.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites",
	//   "request": {
	//     "$ref": "Site"
	//   },
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sites.list":

type SitesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of sites, possibly filtered. This method
// supports paging.
func (r *SitesService) List(profileId int64) *SitesListCall {
	c := &SitesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AcceptsInStreamVideoPlacements sets the optional parameter
// "acceptsInStreamVideoPlacements": This search filter is no longer
// supported and will have no effect on the results returned.
func (c *SitesListCall) AcceptsInStreamVideoPlacements(acceptsInStreamVideoPlacements bool) *SitesListCall {
	c.urlParams_.Set("acceptsInStreamVideoPlacements", fmt.Sprint(acceptsInStreamVideoPlacements))
	return c
}

// AcceptsInterstitialPlacements sets the optional parameter
// "acceptsInterstitialPlacements": This search filter is no longer
// supported and will have no effect on the results returned.
func (c *SitesListCall) AcceptsInterstitialPlacements(acceptsInterstitialPlacements bool) *SitesListCall {
	c.urlParams_.Set("acceptsInterstitialPlacements", fmt.Sprint(acceptsInterstitialPlacements))
	return c
}

// AcceptsPublisherPaidPlacements sets the optional parameter
// "acceptsPublisherPaidPlacements": Select only sites that accept
// publisher paid placements.
func (c *SitesListCall) AcceptsPublisherPaidPlacements(acceptsPublisherPaidPlacements bool) *SitesListCall {
	c.urlParams_.Set("acceptsPublisherPaidPlacements", fmt.Sprint(acceptsPublisherPaidPlacements))
	return c
}

// AdWordsSite sets the optional parameter "adWordsSite": Select only
// AdWords sites.
func (c *SitesListCall) AdWordsSite(adWordsSite bool) *SitesListCall {
	c.urlParams_.Set("adWordsSite", fmt.Sprint(adWordsSite))
	return c
}

// Approved sets the optional parameter "approved": Select only approved
// sites.
func (c *SitesListCall) Approved(approved bool) *SitesListCall {
	c.urlParams_.Set("approved", fmt.Sprint(approved))
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// sites with these campaign IDs.
func (c *SitesListCall) CampaignIds(campaignIds ...int64) *SitesListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// DirectorySiteIds sets the optional parameter "directorySiteIds":
// Select only sites with these directory site IDs.
func (c *SitesListCall) DirectorySiteIds(directorySiteIds ...int64) *SitesListCall {
	var directorySiteIds_ []string
	for _, v := range directorySiteIds {
		directorySiteIds_ = append(directorySiteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("directorySiteIds", directorySiteIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only sites with these
// IDs.
func (c *SitesListCall) Ids(ids ...int64) *SitesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *SitesListCall) MaxResults(maxResults int64) *SitesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *SitesListCall) PageToken(pageToken string) *SitesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name, ID or keyName. Wildcards (*) are
// allowed. For example, "site*2015" will return objects with names like
// "site June 2015", "site April 2015", or simply "site 2015". Most of
// the searches also add wildcards implicitly at the start and the end
// of the search string. For example, a search string of "site" will
// match objects with name "my site", "site 2015", or simply "site".
func (c *SitesListCall) SearchString(searchString string) *SitesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *SitesListCall) SortField(sortField string) *SitesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *SitesListCall) SortOrder(sortOrder string) *SitesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// sites with this subaccount ID.
func (c *SitesListCall) SubaccountId(subaccountId int64) *SitesListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// UnmappedSite sets the optional parameter "unmappedSite": Select only
// sites that have not been mapped to a directory site.
func (c *SitesListCall) UnmappedSite(unmappedSite bool) *SitesListCall {
	c.urlParams_.Set("unmappedSite", fmt.Sprint(unmappedSite))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesListCall) Fields(s ...googleapi.Field) *SitesListCall {
	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 *SitesListCall) IfNoneMatch(entityTag string) *SitesListCall {
	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 *SitesListCall) Context(ctx context.Context) *SitesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.list" call.
// Exactly one of *SitesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SitesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SitesListCall) Do(opts ...googleapi.CallOption) (*SitesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SitesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of sites, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/sites",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.sites.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "acceptsInStreamVideoPlacements": {
	//       "description": "This search filter is no longer supported and will have no effect on the results returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "acceptsInterstitialPlacements": {
	//       "description": "This search filter is no longer supported and will have no effect on the results returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "acceptsPublisherPaidPlacements": {
	//       "description": "Select only sites that accept publisher paid placements.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "adWordsSite": {
	//       "description": "Select only AdWords sites.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "approved": {
	//       "description": "Select only approved sites.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignIds": {
	//       "description": "Select only sites with these campaign IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "directorySiteIds": {
	//       "description": "Select only sites with these directory site IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only sites with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name, ID or keyName. Wildcards (*) are allowed. For example, \"site*2015\" will return objects with names like \"site June 2015\", \"site April 2015\", or simply \"site 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"site\" will match objects with name \"my site\", \"site 2015\", or simply \"site\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only sites with this subaccount ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "unmappedSite": {
	//       "description": "Select only sites that have not been mapped to a directory site.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites",
	//   "response": {
	//     "$ref": "SitesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *SitesListCall) Pages(ctx context.Context, f func(*SitesListResponse) 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 "dfareporting.sites.patch":

type SitesPatchCall struct {
	s          *Service
	profileId  int64
	site       *Site
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing site. This method supports patch
// semantics.
func (r *SitesService) Patch(profileId int64, site *Site) *SitesPatchCall {
	c := &SitesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.site = site
	return c
}

// Id sets the optional parameter "id": Site ID.
func (c *SitesPatchCall) Id(id int64) *SitesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesPatchCall) Fields(s ...googleapi.Field) *SitesPatchCall {
	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 *SitesPatchCall) Context(ctx context.Context) *SitesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/sites")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.patch" 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 *SitesPatchCall) 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": "Updates an existing site. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/sites",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.sites.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Site ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites",
	//   "request": {
	//     "$ref": "Site"
	//   },
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sites.update":

type SitesUpdateCall struct {
	s          *Service
	profileId  int64
	site       *Site
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing site.
func (r *SitesService) Update(profileId int64, site *Site) *SitesUpdateCall {
	c := &SitesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.site = site
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesUpdateCall) Fields(s ...googleapi.Field) *SitesUpdateCall {
	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 *SitesUpdateCall) Context(ctx context.Context) *SitesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/sites")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.update" 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 *SitesUpdateCall) 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": "Updates an existing site.",
	//   "flatPath": "userprofiles/{profileId}/sites",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.sites.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites",
	//   "request": {
	//     "$ref": "Site"
	//   },
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sizes.get":

type SizesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one size by ID.
func (r *SizesService) Get(profileId int64, id int64) *SizesGetCall {
	c := &SizesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SizesGetCall) Fields(s ...googleapi.Field) *SizesGetCall {
	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 *SizesGetCall) IfNoneMatch(entityTag string) *SizesGetCall {
	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 *SizesGetCall) Context(ctx context.Context) *SizesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SizesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SizesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/sizes/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sizes.get" call.
// Exactly one of *Size or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Size.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SizesGetCall) Do(opts ...googleapi.CallOption) (*Size, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Size{
		ServerResponse: googleapi.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 one size by ID.",
	//   "flatPath": "userprofiles/{profileId}/sizes/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.sizes.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Size ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sizes/{id}",
	//   "response": {
	//     "$ref": "Size"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sizes.insert":

type SizesInsertCall struct {
	s          *Service
	profileId  int64
	size       *Size
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new size.
func (r *SizesService) Insert(profileId int64, size *Size) *SizesInsertCall {
	c := &SizesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.size = size
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SizesInsertCall) Fields(s ...googleapi.Field) *SizesInsertCall {
	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 *SizesInsertCall) Context(ctx context.Context) *SizesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SizesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SizesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.size)
	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, "userprofiles/{profileId}/sizes")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sizes.insert" call.
// Exactly one of *Size or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Size.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SizesInsertCall) Do(opts ...googleapi.CallOption) (*Size, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Size{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new size.",
	//   "flatPath": "userprofiles/{profileId}/sizes",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.sizes.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sizes",
	//   "request": {
	//     "$ref": "Size"
	//   },
	//   "response": {
	//     "$ref": "Size"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sizes.list":

type SizesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of sizes, possibly filtered. Retrieved sizes
// are globally unique and may include values not currently in use by
// your account. Due to this, the list of sizes returned by this method
// may differ from the list seen in the Trafficking UI.
func (r *SizesService) List(profileId int64) *SizesListCall {
	c := &SizesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Height sets the optional parameter "height": Select only sizes with
// this height.
func (c *SizesListCall) Height(height int64) *SizesListCall {
	c.urlParams_.Set("height", fmt.Sprint(height))
	return c
}

// IabStandard sets the optional parameter "iabStandard": Select only
// IAB standard sizes.
func (c *SizesListCall) IabStandard(iabStandard bool) *SizesListCall {
	c.urlParams_.Set("iabStandard", fmt.Sprint(iabStandard))
	return c
}

// Ids sets the optional parameter "ids": Select only sizes with these
// IDs.
func (c *SizesListCall) Ids(ids ...int64) *SizesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// Width sets the optional parameter "width": Select only sizes with
// this width.
func (c *SizesListCall) Width(width int64) *SizesListCall {
	c.urlParams_.Set("width", fmt.Sprint(width))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SizesListCall) Fields(s ...googleapi.Field) *SizesListCall {
	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 *SizesListCall) IfNoneMatch(entityTag string) *SizesListCall {
	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 *SizesListCall) Context(ctx context.Context) *SizesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SizesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SizesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/sizes")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sizes.list" call.
// Exactly one of *SizesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SizesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SizesListCall) Do(opts ...googleapi.CallOption) (*SizesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SizesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of sizes, possibly filtered. Retrieved sizes are globally unique and may include values not currently in use by your account. Due to this, the list of sizes returned by this method may differ from the list seen in the Trafficking UI.",
	//   "flatPath": "userprofiles/{profileId}/sizes",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.sizes.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "height": {
	//       "description": "Select only sizes with this height.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "32767",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "iabStandard": {
	//       "description": "Select only IAB standard sizes.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only sizes with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "width": {
	//       "description": "Select only sizes with this width.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "32767",
	//       "minimum": "0",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sizes",
	//   "response": {
	//     "$ref": "SizesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.subaccounts.get":

type SubaccountsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one subaccount by ID.
func (r *SubaccountsService) Get(profileId int64, id int64) *SubaccountsGetCall {
	c := &SubaccountsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsGetCall) Fields(s ...googleapi.Field) *SubaccountsGetCall {
	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 *SubaccountsGetCall) IfNoneMatch(entityTag string) *SubaccountsGetCall {
	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 *SubaccountsGetCall) Context(ctx context.Context) *SubaccountsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/subaccounts/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.get" call.
// Exactly one of *Subaccount or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subaccount.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubaccountsGetCall) Do(opts ...googleapi.CallOption) (*Subaccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subaccount{
		ServerResponse: googleapi.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 one subaccount by ID.",
	//   "flatPath": "userprofiles/{profileId}/subaccounts/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.subaccounts.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Subaccount ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts/{id}",
	//   "response": {
	//     "$ref": "Subaccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.subaccounts.insert":

type SubaccountsInsertCall struct {
	s          *Service
	profileId  int64
	subaccount *Subaccount
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new subaccount.
func (r *SubaccountsService) Insert(profileId int64, subaccount *Subaccount) *SubaccountsInsertCall {
	c := &SubaccountsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.subaccount = subaccount
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsInsertCall) Fields(s ...googleapi.Field) *SubaccountsInsertCall {
	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 *SubaccountsInsertCall) Context(ctx context.Context) *SubaccountsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.subaccount)
	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, "userprofiles/{profileId}/subaccounts")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.insert" call.
// Exactly one of *Subaccount or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subaccount.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubaccountsInsertCall) Do(opts ...googleapi.CallOption) (*Subaccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subaccount{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new subaccount.",
	//   "flatPath": "userprofiles/{profileId}/subaccounts",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.subaccounts.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts",
	//   "request": {
	//     "$ref": "Subaccount"
	//   },
	//   "response": {
	//     "$ref": "Subaccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.subaccounts.list":

type SubaccountsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Gets a list of subaccounts, possibly filtered. This method
// supports paging.
func (r *SubaccountsService) List(profileId int64) *SubaccountsListCall {
	c := &SubaccountsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only subaccounts with
// these IDs.
func (c *SubaccountsListCall) Ids(ids ...int64) *SubaccountsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *SubaccountsListCall) MaxResults(maxResults int64) *SubaccountsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *SubaccountsListCall) PageToken(pageToken string) *SubaccountsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "subaccount*2015" will return objects with names like
// "subaccount June 2015", "subaccount April 2015", or simply
// "subaccount 2015". Most of the searches also add wildcards implicitly
// at the start and the end of the search string. For example, a search
// string of "subaccount" will match objects with name "my subaccount",
// "subaccount 2015", or simply "subaccount" .
func (c *SubaccountsListCall) SearchString(searchString string) *SubaccountsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *SubaccountsListCall) SortField(sortField string) *SubaccountsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *SubaccountsListCall) SortOrder(sortOrder string) *SubaccountsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsListCall) Fields(s ...googleapi.Field) *SubaccountsListCall {
	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 *SubaccountsListCall) IfNoneMatch(entityTag string) *SubaccountsListCall {
	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 *SubaccountsListCall) Context(ctx context.Context) *SubaccountsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/subaccounts")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.list" call.
// Exactly one of *SubaccountsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SubaccountsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SubaccountsListCall) Do(opts ...googleapi.CallOption) (*SubaccountsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SubaccountsListResponse{
		ServerResponse: googleapi.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 list of subaccounts, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/subaccounts",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.subaccounts.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only subaccounts with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"subaccount*2015\" will return objects with names like \"subaccount June 2015\", \"subaccount April 2015\", or simply \"subaccount 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"subaccount\" will match objects with name \"my subaccount\", \"subaccount 2015\", or simply \"subaccount\" .",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts",
	//   "response": {
	//     "$ref": "SubaccountsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *SubaccountsListCall) Pages(ctx context.Context, f func(*SubaccountsListResponse) 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 "dfareporting.subaccounts.patch":

type SubaccountsPatchCall struct {
	s          *Service
	profileId  int64
	subaccount *Subaccount
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing subaccount. This method supports patch
// semantics.
func (r *SubaccountsService) Patch(profileId int64, subaccount *Subaccount) *SubaccountsPatchCall {
	c := &SubaccountsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.subaccount = subaccount
	return c
}

// Id sets the optional parameter "id": Subaccount ID.
func (c *SubaccountsPatchCall) Id(id int64) *SubaccountsPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsPatchCall) Fields(s ...googleapi.Field) *SubaccountsPatchCall {
	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 *SubaccountsPatchCall) Context(ctx context.Context) *SubaccountsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.subaccount)
	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, "userprofiles/{profileId}/subaccounts")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.patch" call.
// Exactly one of *Subaccount or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subaccount.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubaccountsPatchCall) Do(opts ...googleapi.CallOption) (*Subaccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subaccount{
		ServerResponse: googleapi.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 subaccount. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/subaccounts",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.subaccounts.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Subaccount ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts",
	//   "request": {
	//     "$ref": "Subaccount"
	//   },
	//   "response": {
	//     "$ref": "Subaccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.subaccounts.update":

type SubaccountsUpdateCall struct {
	s          *Service
	profileId  int64
	subaccount *Subaccount
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing subaccount.
func (r *SubaccountsService) Update(profileId int64, subaccount *Subaccount) *SubaccountsUpdateCall {
	c := &SubaccountsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.subaccount = subaccount
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsUpdateCall) Fields(s ...googleapi.Field) *SubaccountsUpdateCall {
	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 *SubaccountsUpdateCall) Context(ctx context.Context) *SubaccountsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.subaccount)
	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, "userprofiles/{profileId}/subaccounts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.update" call.
// Exactly one of *Subaccount or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subaccount.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubaccountsUpdateCall) Do(opts ...googleapi.CallOption) (*Subaccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subaccount{
		ServerResponse: googleapi.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 subaccount.",
	//   "flatPath": "userprofiles/{profileId}/subaccounts",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.subaccounts.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts",
	//   "request": {
	//     "$ref": "Subaccount"
	//   },
	//   "response": {
	//     "$ref": "Subaccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetableRemarketingLists.get":

type TargetableRemarketingListsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one remarketing list by ID.
func (r *TargetableRemarketingListsService) Get(profileId int64, id int64) *TargetableRemarketingListsGetCall {
	c := &TargetableRemarketingListsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetableRemarketingListsGetCall) Fields(s ...googleapi.Field) *TargetableRemarketingListsGetCall {
	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 *TargetableRemarketingListsGetCall) IfNoneMatch(entityTag string) *TargetableRemarketingListsGetCall {
	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 *TargetableRemarketingListsGetCall) Context(ctx context.Context) *TargetableRemarketingListsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetableRemarketingListsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetableRemarketingListsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/targetableRemarketingLists/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.targetableRemarketingLists.get" call.
// Exactly one of *TargetableRemarketingList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *TargetableRemarketingList.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetableRemarketingListsGetCall) Do(opts ...googleapi.CallOption) (*TargetableRemarketingList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetableRemarketingList{
		ServerResponse: googleapi.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 one remarketing list by ID.",
	//   "flatPath": "userprofiles/{profileId}/targetableRemarketingLists/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.targetableRemarketingLists.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Remarketing list ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetableRemarketingLists/{id}",
	//   "response": {
	//     "$ref": "TargetableRemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetableRemarketingLists.list":

type TargetableRemarketingListsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of targetable remarketing lists, possibly
// filtered. This method supports paging.
func (r *TargetableRemarketingListsService) List(profileId int64, advertiserId int64) *TargetableRemarketingListsListCall {
	c := &TargetableRemarketingListsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Active sets the optional parameter "active": Select only active or
// only inactive targetable remarketing lists.
func (c *TargetableRemarketingListsListCall) Active(active bool) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *TargetableRemarketingListsListCall) MaxResults(maxResults int64) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Name sets the optional parameter "name": Allows searching for objects
// by name or ID. Wildcards (*) are allowed. For example, "remarketing
// list*2015" will return objects with names like "remarketing list June
// 2015", "remarketing list April 2015", or simply "remarketing list
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "remarketing list" will match objects with name "my remarketing
// list", "remarketing list 2015", or simply "remarketing list".
func (c *TargetableRemarketingListsListCall) Name(name string) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *TargetableRemarketingListsListCall) PageToken(pageToken string) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *TargetableRemarketingListsListCall) SortField(sortField string) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *TargetableRemarketingListsListCall) SortOrder(sortOrder string) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetableRemarketingListsListCall) Fields(s ...googleapi.Field) *TargetableRemarketingListsListCall {
	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 *TargetableRemarketingListsListCall) IfNoneMatch(entityTag string) *TargetableRemarketingListsListCall {
	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 *TargetableRemarketingListsListCall) Context(ctx context.Context) *TargetableRemarketingListsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetableRemarketingListsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetableRemarketingListsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/targetableRemarketingLists")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.targetableRemarketingLists.list" call.
// Exactly one of *TargetableRemarketingListsListResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *TargetableRemarketingListsListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetableRemarketingListsListCall) Do(opts ...googleapi.CallOption) (*TargetableRemarketingListsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetableRemarketingListsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of targetable remarketing lists, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/targetableRemarketingLists",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.targetableRemarketingLists.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active or only inactive targetable remarketing lists.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "advertiserId": {
	//       "description": "Select only targetable remarketing lists targetable by these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"remarketing list*2015\" will return objects with names like \"remarketing list June 2015\", \"remarketing list April 2015\", or simply \"remarketing list 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"remarketing list\" will match objects with name \"my remarketing list\", \"remarketing list 2015\", or simply \"remarketing list\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetableRemarketingLists",
	//   "response": {
	//     "$ref": "TargetableRemarketingListsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *TargetableRemarketingListsListCall) Pages(ctx context.Context, f func(*TargetableRemarketingListsListResponse) 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 "dfareporting.targetingTemplates.get":

type TargetingTemplatesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one targeting template by ID.
func (r *TargetingTemplatesService) Get(profileId int64, id int64) *TargetingTemplatesGetCall {
	c := &TargetingTemplatesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetingTemplatesGetCall) Fields(s ...googleapi.Field) *TargetingTemplatesGetCall {
	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 *TargetingTemplatesGetCall) IfNoneMatch(entityTag string) *TargetingTemplatesGetCall {
	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 *TargetingTemplatesGetCall) Context(ctx context.Context) *TargetingTemplatesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/targetingTemplates/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.targetingTemplates.get" call.
// Exactly one of *TargetingTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetingTemplate.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetingTemplatesGetCall) Do(opts ...googleapi.CallOption) (*TargetingTemplate, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetingTemplate{
		ServerResponse: googleapi.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 one targeting template by ID.",
	//   "flatPath": "userprofiles/{profileId}/targetingTemplates/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.targetingTemplates.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Targeting template ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetingTemplates/{id}",
	//   "response": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetingTemplates.insert":

type TargetingTemplatesInsertCall struct {
	s                 *Service
	profileId         int64
	targetingtemplate *TargetingTemplate
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Insert: Inserts a new targeting template.
func (r *TargetingTemplatesService) Insert(profileId int64, targetingtemplate *TargetingTemplate) *TargetingTemplatesInsertCall {
	c := &TargetingTemplatesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.targetingtemplate = targetingtemplate
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetingTemplatesInsertCall) Fields(s ...googleapi.Field) *TargetingTemplatesInsertCall {
	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 *TargetingTemplatesInsertCall) Context(ctx context.Context) *TargetingTemplatesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.targetingtemplate)
	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, "userprofiles/{profileId}/targetingTemplates")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.targetingTemplates.insert" call.
// Exactly one of *TargetingTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetingTemplate.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetingTemplatesInsertCall) Do(opts ...googleapi.CallOption) (*TargetingTemplate, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetingTemplate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new targeting template.",
	//   "flatPath": "userprofiles/{profileId}/targetingTemplates",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.targetingTemplates.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetingTemplates",
	//   "request": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "response": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetingTemplates.list":

type TargetingTemplatesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of targeting templates, optionally filtered.
// This method supports paging.
func (r *TargetingTemplatesService) List(profileId int64) *TargetingTemplatesListCall {
	c := &TargetingTemplatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// targeting templates with this advertiser ID.
func (c *TargetingTemplatesListCall) AdvertiserId(advertiserId int64) *TargetingTemplatesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Ids sets the optional parameter "ids": Select only targeting
// templates with these IDs.
func (c *TargetingTemplatesListCall) Ids(ids ...int64) *TargetingTemplatesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *TargetingTemplatesListCall) MaxResults(maxResults int64) *TargetingTemplatesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *TargetingTemplatesListCall) PageToken(pageToken string) *TargetingTemplatesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "template*2015" will return objects with names like
// "template June 2015", "template April 2015", or simply "template
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "template" will match objects with name "my template", "template
// 2015", or simply "template".
func (c *TargetingTemplatesListCall) SearchString(searchString string) *TargetingTemplatesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *TargetingTemplatesListCall) SortField(sortField string) *TargetingTemplatesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *TargetingTemplatesListCall) SortOrder(sortOrder string) *TargetingTemplatesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetingTemplatesListCall) Fields(s ...googleapi.Field) *TargetingTemplatesListCall {
	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 *TargetingTemplatesListCall) IfNoneMatch(entityTag string) *TargetingTemplatesListCall {
	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 *TargetingTemplatesListCall) Context(ctx context.Context) *TargetingTemplatesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/targetingTemplates")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.targetingTemplates.list" call.
// Exactly one of *TargetingTemplatesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *TargetingTemplatesListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetingTemplatesListCall) Do(opts ...googleapi.CallOption) (*TargetingTemplatesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetingTemplatesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of targeting templates, optionally filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/targetingTemplates",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.targetingTemplates.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Select only targeting templates with this advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only targeting templates with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"template*2015\" will return objects with names like \"template June 2015\", \"template April 2015\", or simply \"template 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"template\" will match objects with name \"my template\", \"template 2015\", or simply \"template\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetingTemplates",
	//   "response": {
	//     "$ref": "TargetingTemplatesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *TargetingTemplatesListCall) Pages(ctx context.Context, f func(*TargetingTemplatesListResponse) 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 "dfareporting.targetingTemplates.patch":

type TargetingTemplatesPatchCall struct {
	s                 *Service
	profileId         int64
	targetingtemplate *TargetingTemplate
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Patch: Updates an existing targeting template. This method supports
// patch semantics.
func (r *TargetingTemplatesService) Patch(profileId int64, targetingtemplate *TargetingTemplate) *TargetingTemplatesPatchCall {
	c := &TargetingTemplatesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.targetingtemplate = targetingtemplate
	return c
}

// Id sets the optional parameter "id": TargetingTemplate ID.
func (c *TargetingTemplatesPatchCall) Id(id int64) *TargetingTemplatesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetingTemplatesPatchCall) Fields(s ...googleapi.Field) *TargetingTemplatesPatchCall {
	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 *TargetingTemplatesPatchCall) Context(ctx context.Context) *TargetingTemplatesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.targetingtemplate)
	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, "userprofiles/{profileId}/targetingTemplates")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.targetingTemplates.patch" call.
// Exactly one of *TargetingTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetingTemplate.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetingTemplatesPatchCall) Do(opts ...googleapi.CallOption) (*TargetingTemplate, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetingTemplate{
		ServerResponse: googleapi.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 targeting template. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/targetingTemplates",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.targetingTemplates.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "TargetingTemplate ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetingTemplates",
	//   "request": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "response": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetingTemplates.update":

type TargetingTemplatesUpdateCall struct {
	s                 *Service
	profileId         int64
	targetingtemplate *TargetingTemplate
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Update: Updates an existing targeting template.
func (r *TargetingTemplatesService) Update(profileId int64, targetingtemplate *TargetingTemplate) *TargetingTemplatesUpdateCall {
	c := &TargetingTemplatesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.targetingtemplate = targetingtemplate
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TargetingTemplatesUpdateCall) Fields(s ...googleapi.Field) *TargetingTemplatesUpdateCall {
	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 *TargetingTemplatesUpdateCall) Context(ctx context.Context) *TargetingTemplatesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.targetingtemplate)
	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, "userprofiles/{profileId}/targetingTemplates")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.targetingTemplates.update" call.
// Exactly one of *TargetingTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetingTemplate.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TargetingTemplatesUpdateCall) Do(opts ...googleapi.CallOption) (*TargetingTemplate, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TargetingTemplate{
		ServerResponse: googleapi.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 targeting template.",
	//   "flatPath": "userprofiles/{profileId}/targetingTemplates",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.targetingTemplates.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetingTemplates",
	//   "request": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "response": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userProfiles.get":

type UserProfilesGetCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one user profile by ID.
func (r *UserProfilesService) Get(profileId int64) *UserProfilesGetCall {
	c := &UserProfilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserProfilesGetCall) Fields(s ...googleapi.Field) *UserProfilesGetCall {
	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 *UserProfilesGetCall) IfNoneMatch(entityTag string) *UserProfilesGetCall {
	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 *UserProfilesGetCall) Context(ctx context.Context) *UserProfilesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserProfilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserProfilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userProfiles.get" call.
// Exactly one of *UserProfile or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *UserProfile.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserProfilesGetCall) Do(opts ...googleapi.CallOption) (*UserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserProfile{
		ServerResponse: googleapi.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 one user profile by ID.",
	//   "flatPath": "userprofiles/{profileId}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userProfiles.get",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}",
	//   "response": {
	//     "$ref": "UserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/ddmconversions",
	//     "https://www.googleapis.com/auth/dfareporting",
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userProfiles.list":

type UserProfilesListCall struct {
	s            *Service
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves list of user profiles for a user.
func (r *UserProfilesService) List() *UserProfilesListCall {
	c := &UserProfilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserProfilesListCall) Fields(s ...googleapi.Field) *UserProfilesListCall {
	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 *UserProfilesListCall) IfNoneMatch(entityTag string) *UserProfilesListCall {
	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 *UserProfilesListCall) Context(ctx context.Context) *UserProfilesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserProfilesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserProfilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles")
	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 "dfareporting.userProfiles.list" call.
// Exactly one of *UserProfileList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *UserProfileList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserProfilesListCall) Do(opts ...googleapi.CallOption) (*UserProfileList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserProfileList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves list of user profiles for a user.",
	//   "flatPath": "userprofiles",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userProfiles.list",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "userprofiles",
	//   "response": {
	//     "$ref": "UserProfileList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/ddmconversions",
	//     "https://www.googleapis.com/auth/dfareporting",
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRolePermissionGroups.get":

type UserRolePermissionGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one user role permission group by ID.
func (r *UserRolePermissionGroupsService) Get(profileId int64, id int64) *UserRolePermissionGroupsGetCall {
	c := &UserRolePermissionGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolePermissionGroupsGetCall) Fields(s ...googleapi.Field) *UserRolePermissionGroupsGetCall {
	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 *UserRolePermissionGroupsGetCall) IfNoneMatch(entityTag string) *UserRolePermissionGroupsGetCall {
	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 *UserRolePermissionGroupsGetCall) Context(ctx context.Context) *UserRolePermissionGroupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolePermissionGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolePermissionGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/userRolePermissionGroups/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRolePermissionGroups.get" call.
// Exactly one of *UserRolePermissionGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UserRolePermissionGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserRolePermissionGroupsGetCall) Do(opts ...googleapi.CallOption) (*UserRolePermissionGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolePermissionGroup{
		ServerResponse: googleapi.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 one user role permission group by ID.",
	//   "flatPath": "userprofiles/{profileId}/userRolePermissionGroups/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRolePermissionGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role permission group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRolePermissionGroups/{id}",
	//   "response": {
	//     "$ref": "UserRolePermissionGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRolePermissionGroups.list":

type UserRolePermissionGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Gets a list of all supported user role permission groups.
func (r *UserRolePermissionGroupsService) List(profileId int64) *UserRolePermissionGroupsListCall {
	c := &UserRolePermissionGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolePermissionGroupsListCall) Fields(s ...googleapi.Field) *UserRolePermissionGroupsListCall {
	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 *UserRolePermissionGroupsListCall) IfNoneMatch(entityTag string) *UserRolePermissionGroupsListCall {
	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 *UserRolePermissionGroupsListCall) Context(ctx context.Context) *UserRolePermissionGroupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolePermissionGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolePermissionGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/userRolePermissionGroups")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRolePermissionGroups.list" call.
// Exactly one of *UserRolePermissionGroupsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *UserRolePermissionGroupsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *UserRolePermissionGroupsListCall) Do(opts ...googleapi.CallOption) (*UserRolePermissionGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolePermissionGroupsListResponse{
		ServerResponse: googleapi.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 list of all supported user role permission groups.",
	//   "flatPath": "userprofiles/{profileId}/userRolePermissionGroups",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRolePermissionGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRolePermissionGroups",
	//   "response": {
	//     "$ref": "UserRolePermissionGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRolePermissions.get":

type UserRolePermissionsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one user role permission by ID.
func (r *UserRolePermissionsService) Get(profileId int64, id int64) *UserRolePermissionsGetCall {
	c := &UserRolePermissionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolePermissionsGetCall) Fields(s ...googleapi.Field) *UserRolePermissionsGetCall {
	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 *UserRolePermissionsGetCall) IfNoneMatch(entityTag string) *UserRolePermissionsGetCall {
	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 *UserRolePermissionsGetCall) Context(ctx context.Context) *UserRolePermissionsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolePermissionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolePermissionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/userRolePermissions/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRolePermissions.get" call.
// Exactly one of *UserRolePermission or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UserRolePermission.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserRolePermissionsGetCall) Do(opts ...googleapi.CallOption) (*UserRolePermission, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolePermission{
		ServerResponse: googleapi.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 one user role permission by ID.",
	//   "flatPath": "userprofiles/{profileId}/userRolePermissions/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRolePermissions.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role permission ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRolePermissions/{id}",
	//   "response": {
	//     "$ref": "UserRolePermission"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRolePermissions.list":

type UserRolePermissionsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Gets a list of user role permissions, possibly filtered.
func (r *UserRolePermissionsService) List(profileId int64) *UserRolePermissionsListCall {
	c := &UserRolePermissionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only user role
// permissions with these IDs.
func (c *UserRolePermissionsListCall) Ids(ids ...int64) *UserRolePermissionsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolePermissionsListCall) Fields(s ...googleapi.Field) *UserRolePermissionsListCall {
	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 *UserRolePermissionsListCall) IfNoneMatch(entityTag string) *UserRolePermissionsListCall {
	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 *UserRolePermissionsListCall) Context(ctx context.Context) *UserRolePermissionsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolePermissionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolePermissionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/userRolePermissions")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRolePermissions.list" call.
// Exactly one of *UserRolePermissionsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *UserRolePermissionsListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserRolePermissionsListCall) Do(opts ...googleapi.CallOption) (*UserRolePermissionsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolePermissionsListResponse{
		ServerResponse: googleapi.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 list of user role permissions, possibly filtered.",
	//   "flatPath": "userprofiles/{profileId}/userRolePermissions",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRolePermissions.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only user role permissions with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRolePermissions",
	//   "response": {
	//     "$ref": "UserRolePermissionsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.delete":

type UserRolesDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing user role.
func (r *UserRolesService) Delete(profileId int64, id int64) *UserRolesDeleteCall {
	c := &UserRolesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesDeleteCall) Fields(s ...googleapi.Field) *UserRolesDeleteCall {
	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 *UserRolesDeleteCall) Context(ctx context.Context) *UserRolesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/userRoles/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.delete" call.
func (c *UserRolesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing user role.",
	//   "flatPath": "userprofiles/{profileId}/userRoles/{id}",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.userRoles.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.get":

type UserRolesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one user role by ID.
func (r *UserRolesService) Get(profileId int64, id int64) *UserRolesGetCall {
	c := &UserRolesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesGetCall) Fields(s ...googleapi.Field) *UserRolesGetCall {
	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 *UserRolesGetCall) IfNoneMatch(entityTag string) *UserRolesGetCall {
	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 *UserRolesGetCall) Context(ctx context.Context) *UserRolesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/userRoles/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.get" call.
// Exactly one of *UserRole or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserRole.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserRolesGetCall) Do(opts ...googleapi.CallOption) (*UserRole, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRole{
		ServerResponse: googleapi.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 one user role by ID.",
	//   "flatPath": "userprofiles/{profileId}/userRoles/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRoles.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles/{id}",
	//   "response": {
	//     "$ref": "UserRole"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.insert":

type UserRolesInsertCall struct {
	s          *Service
	profileId  int64
	userrole   *UserRole
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Inserts a new user role.
func (r *UserRolesService) Insert(profileId int64, userrole *UserRole) *UserRolesInsertCall {
	c := &UserRolesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.userrole = userrole
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesInsertCall) Fields(s ...googleapi.Field) *UserRolesInsertCall {
	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 *UserRolesInsertCall) Context(ctx context.Context) *UserRolesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.userrole)
	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, "userprofiles/{profileId}/userRoles")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.insert" call.
// Exactly one of *UserRole or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserRole.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserRolesInsertCall) Do(opts ...googleapi.CallOption) (*UserRole, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRole{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new user role.",
	//   "flatPath": "userprofiles/{profileId}/userRoles",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.userRoles.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles",
	//   "request": {
	//     "$ref": "UserRole"
	//   },
	//   "response": {
	//     "$ref": "UserRole"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.list":

type UserRolesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of user roles, possibly filtered. This method
// supports paging.
func (r *UserRolesService) List(profileId int64) *UserRolesListCall {
	c := &UserRolesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AccountUserRoleOnly sets the optional parameter
// "accountUserRoleOnly": Select only account level user roles not
// associated with any specific subaccount.
func (c *UserRolesListCall) AccountUserRoleOnly(accountUserRoleOnly bool) *UserRolesListCall {
	c.urlParams_.Set("accountUserRoleOnly", fmt.Sprint(accountUserRoleOnly))
	return c
}

// Ids sets the optional parameter "ids": Select only user roles with
// the specified IDs.
func (c *UserRolesListCall) Ids(ids ...int64) *UserRolesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *UserRolesListCall) MaxResults(maxResults int64) *UserRolesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *UserRolesListCall) PageToken(pageToken string) *UserRolesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "userrole*2015" will return objects with names like
// "userrole June 2015", "userrole April 2015", or simply "userrole
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "userrole" will match objects with name "my userrole", "userrole
// 2015", or simply "userrole".
func (c *UserRolesListCall) SearchString(searchString string) *UserRolesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *UserRolesListCall) SortField(sortField string) *UserRolesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *UserRolesListCall) SortOrder(sortOrder string) *UserRolesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// user roles that belong to this subaccount.
func (c *UserRolesListCall) SubaccountId(subaccountId int64) *UserRolesListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesListCall) Fields(s ...googleapi.Field) *UserRolesListCall {
	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 *UserRolesListCall) IfNoneMatch(entityTag string) *UserRolesListCall {
	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 *UserRolesListCall) Context(ctx context.Context) *UserRolesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/userRoles")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.list" call.
// Exactly one of *UserRolesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UserRolesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserRolesListCall) Do(opts ...googleapi.CallOption) (*UserRolesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of user roles, possibly filtered. This method supports paging.",
	//   "flatPath": "userprofiles/{profileId}/userRoles",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRoles.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "accountUserRoleOnly": {
	//       "description": "Select only account level user roles not associated with any specific subaccount.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only user roles with the specified IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"userrole*2015\" will return objects with names like \"userrole June 2015\", \"userrole April 2015\", or simply \"userrole 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"userrole\" will match objects with name \"my userrole\", \"userrole 2015\", or simply \"userrole\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only user roles that belong to this subaccount.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles",
	//   "response": {
	//     "$ref": "UserRolesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// 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 *UserRolesListCall) Pages(ctx context.Context, f func(*UserRolesListResponse) 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 "dfareporting.userRoles.patch":

type UserRolesPatchCall struct {
	s          *Service
	profileId  int64
	userrole   *UserRole
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates an existing user role. This method supports patch
// semantics.
func (r *UserRolesService) Patch(profileId int64, userrole *UserRole) *UserRolesPatchCall {
	c := &UserRolesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.userrole = userrole
	return c
}

// Id sets the optional parameter "id": UserRole ID.
func (c *UserRolesPatchCall) Id(id int64) *UserRolesPatchCall {
	c.urlParams_.Set("id", fmt.Sprint(id))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesPatchCall) Fields(s ...googleapi.Field) *UserRolesPatchCall {
	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 *UserRolesPatchCall) Context(ctx context.Context) *UserRolesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.userrole)
	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, "userprofiles/{profileId}/userRoles")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.patch" call.
// Exactly one of *UserRole or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserRole.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserRolesPatchCall) Do(opts ...googleapi.CallOption) (*UserRole, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRole{
		ServerResponse: googleapi.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 user role. This method supports patch semantics.",
	//   "flatPath": "userprofiles/{profileId}/userRoles",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.userRoles.patch",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "UserRole ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles",
	//   "request": {
	//     "$ref": "UserRole"
	//   },
	//   "response": {
	//     "$ref": "UserRole"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.update":

type UserRolesUpdateCall struct {
	s          *Service
	profileId  int64
	userrole   *UserRole
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates an existing user role.
func (r *UserRolesService) Update(profileId int64, userrole *UserRole) *UserRolesUpdateCall {
	c := &UserRolesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.userrole = userrole
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesUpdateCall) Fields(s ...googleapi.Field) *UserRolesUpdateCall {
	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 *UserRolesUpdateCall) Context(ctx context.Context) *UserRolesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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.userrole)
	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, "userprofiles/{profileId}/userRoles")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.update" call.
// Exactly one of *UserRole or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserRole.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserRolesUpdateCall) Do(opts ...googleapi.CallOption) (*UserRole, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRole{
		ServerResponse: googleapi.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 user role.",
	//   "flatPath": "userprofiles/{profileId}/userRoles",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.userRoles.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles",
	//   "request": {
	//     "$ref": "UserRole"
	//   },
	//   "response": {
	//     "$ref": "UserRole"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.videoFormats.get":

type VideoFormatsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one video format by ID.
func (r *VideoFormatsService) Get(profileId int64, id int64) *VideoFormatsGetCall {
	c := &VideoFormatsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VideoFormatsGetCall) Fields(s ...googleapi.Field) *VideoFormatsGetCall {
	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 *VideoFormatsGetCall) IfNoneMatch(entityTag string) *VideoFormatsGetCall {
	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 *VideoFormatsGetCall) Context(ctx context.Context) *VideoFormatsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VideoFormatsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideoFormatsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/videoFormats/{id}")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.videoFormats.get" call.
// Exactly one of *VideoFormat or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *VideoFormat.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *VideoFormatsGetCall) Do(opts ...googleapi.CallOption) (*VideoFormat, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VideoFormat{
		ServerResponse: googleapi.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 one video format by ID.",
	//   "flatPath": "userprofiles/{profileId}/videoFormats/{id}",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.videoFormats.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Video format ID.",
	//       "format": "int32",
	//       "location": "path",
	//       "required": true,
	//       "type": "integer"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/videoFormats/{id}",
	//   "response": {
	//     "$ref": "VideoFormat"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.videoFormats.list":

type VideoFormatsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists available video formats.
func (r *VideoFormatsService) List(profileId int64) *VideoFormatsListCall {
	c := &VideoFormatsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VideoFormatsListCall) Fields(s ...googleapi.Field) *VideoFormatsListCall {
	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 *VideoFormatsListCall) IfNoneMatch(entityTag string) *VideoFormatsListCall {
	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 *VideoFormatsListCall) Context(ctx context.Context) *VideoFormatsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VideoFormatsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideoFormatsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200825")
	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, "userprofiles/{profileId}/videoFormats")
	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{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.videoFormats.list" call.
// Exactly one of *VideoFormatsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *VideoFormatsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *VideoFormatsListCall) Do(opts ...googleapi.CallOption) (*VideoFormatsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &VideoFormatsListResponse{
		ServerResponse: googleapi.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 available video formats.",
	//   "flatPath": "userprofiles/{profileId}/videoFormats",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.videoFormats.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/videoFormats",
	//   "response": {
	//     "$ref": "VideoFormatsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}
