// 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 partners provides access to the Google Partners API.
//
// For product documentation, see: https://developers.google.com/partners/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/partners/v2"
//   ...
//   ctx := context.Background()
//   partnersService, err := partners.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
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   partnersService, err := partners.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, ...)
//   partnersService, err := partners.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package partners // import "google.golang.org/api/partners/v2"

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"
	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

const apiId = "partners:v2"
const apiName = "partners"
const apiVersion = "v2"
const basePath = "https://partners.googleapis.com/"

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	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.Analytics = NewAnalyticsService(s)
	s.ClientMessages = NewClientMessagesService(s)
	s.Companies = NewCompaniesService(s)
	s.Leads = NewLeadsService(s)
	s.Offers = NewOffersService(s)
	s.UserEvents = NewUserEventsService(s)
	s.UserStates = NewUserStatesService(s)
	s.Users = NewUsersService(s)
	s.V2 = NewV2Service(s)
	return s, nil
}

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

	Analytics *AnalyticsService

	ClientMessages *ClientMessagesService

	Companies *CompaniesService

	Leads *LeadsService

	Offers *OffersService

	UserEvents *UserEventsService

	UserStates *UserStatesService

	Users *UsersService

	V2 *V2Service
}

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

func NewAnalyticsService(s *Service) *AnalyticsService {
	rs := &AnalyticsService{s: s}
	return rs
}

type AnalyticsService struct {
	s *Service
}

func NewClientMessagesService(s *Service) *ClientMessagesService {
	rs := &ClientMessagesService{s: s}
	return rs
}

type ClientMessagesService struct {
	s *Service
}

func NewCompaniesService(s *Service) *CompaniesService {
	rs := &CompaniesService{s: s}
	rs.Leads = NewCompaniesLeadsService(s)
	return rs
}

type CompaniesService struct {
	s *Service

	Leads *CompaniesLeadsService
}

func NewCompaniesLeadsService(s *Service) *CompaniesLeadsService {
	rs := &CompaniesLeadsService{s: s}
	return rs
}

type CompaniesLeadsService struct {
	s *Service
}

func NewLeadsService(s *Service) *LeadsService {
	rs := &LeadsService{s: s}
	return rs
}

type LeadsService struct {
	s *Service
}

func NewOffersService(s *Service) *OffersService {
	rs := &OffersService{s: s}
	rs.History = NewOffersHistoryService(s)
	return rs
}

type OffersService struct {
	s *Service

	History *OffersHistoryService
}

func NewOffersHistoryService(s *Service) *OffersHistoryService {
	rs := &OffersHistoryService{s: s}
	return rs
}

type OffersHistoryService struct {
	s *Service
}

func NewUserEventsService(s *Service) *UserEventsService {
	rs := &UserEventsService{s: s}
	return rs
}

type UserEventsService struct {
	s *Service
}

func NewUserStatesService(s *Service) *UserStatesService {
	rs := &UserStatesService{s: s}
	return rs
}

type UserStatesService struct {
	s *Service
}

func NewUsersService(s *Service) *UsersService {
	rs := &UsersService{s: s}
	return rs
}

type UsersService struct {
	s *Service
}

func NewV2Service(s *Service) *V2Service {
	rs := &V2Service{s: s}
	return rs
}

type V2Service struct {
	s *Service
}

// AdWordsManagerAccountInfo: Information about a particular AdWords
// Manager Account.
// Read more at https://support.google.com/adwords/answer/6139186
type AdWordsManagerAccountInfo struct {
	// CustomerName: Name of the customer this account represents.
	CustomerName string `json:"customerName,omitempty"`

	// Id: The AdWords Manager Account id.
	Id int64 `json:"id,omitempty,string"`

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

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

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

// Analytics: Analytics data for a `Company` within a single day.
type Analytics struct {
	// Contacts: Instances of users contacting the `Company`
	// on the specified date.
	Contacts *AnalyticsDataPoint `json:"contacts,omitempty"`

	// EventDate: Date on which these events occurred.
	EventDate *Date `json:"eventDate,omitempty"`

	// ProfileViews: Instances of users viewing the `Company` profile
	// on the specified date.
	ProfileViews *AnalyticsDataPoint `json:"profileViews,omitempty"`

	// SearchViews: Instances of users seeing the `Company` in Google
	// Partners Search results
	// on the specified date.
	SearchViews *AnalyticsDataPoint `json:"searchViews,omitempty"`

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

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

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

// AnalyticsDataPoint: Details of the analytics events for a `Company`
// within a single day.
type AnalyticsDataPoint struct {
	// EventCount: Number of times the type of event occurred.
	// Meaning depends on context (e.g. profile views, contacts, etc.).
	EventCount int64 `json:"eventCount,omitempty"`

	// EventLocations: Location information of where these events occurred.
	EventLocations []*LatLng `json:"eventLocations,omitempty"`

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

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

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

// AnalyticsSummary: Analytics aggregated data for a `Company` for a
// given date range.
type AnalyticsSummary struct {
	// ContactsCount: Aggregated number of times users contacted the
	// `Company`
	// for given date range.
	ContactsCount int64 `json:"contactsCount,omitempty"`

	// ProfileViewsCount: Aggregated number of profile views for the
	// `Company` for given date range.
	ProfileViewsCount int64 `json:"profileViewsCount,omitempty"`

	// SearchViewsCount: Aggregated number of times users saw the
	// `Company`
	// in Google Partners Search results for given date range.
	SearchViewsCount int64 `json:"searchViewsCount,omitempty"`

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

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

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

// AvailableOffer: Available Offers to be distributed.
type AvailableOffer struct {
	// Available: The number of codes for this offer that are available for
	// distribution.
	Available int64 `json:"available,omitempty"`

	// CountryOfferInfos: Offer info by country.
	CountryOfferInfos []*CountryOfferInfo `json:"countryOfferInfos,omitempty"`

	// Description: Description of the offer.
	Description string `json:"description,omitempty"`

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

	// MaxAccountAge: The maximum age of an account [in days] to be
	// eligible.
	MaxAccountAge int64 `json:"maxAccountAge,omitempty"`

	// Name: Name of the offer.
	Name string `json:"name,omitempty"`

	// OfferLevel: Level of this offer.
	//
	// Possible values:
	//   "OFFER_LEVEL_UNSPECIFIED" - Unset.
	//   "OFFER_LEVEL_DENY_PROBLEM" - Users/Agencies that have no offers
	// because of a problem.
	//   "OFFER_LEVEL_DENY_CONTRACT" - Users/Agencies that have no offers
	// due to contractural agreements.
	//   "OFFER_LEVEL_MANUAL" - Users/Agencies that have a
	// manually-configured limit.
	//   "OFFER_LEVEL_LIMIT_0" - Some Agencies don't get any offers.
	//   "OFFER_LEVEL_LIMIT_5" - Basic level gets 5 per month.
	//   "OFFER_LEVEL_LIMIT_15" - Agencies with adequate AHI and spend get
	// 15/month.
	//   "OFFER_LEVEL_LIMIT_50" - Badged partners (even in grace) get 50 per
	// month.
	OfferLevel string `json:"offerLevel,omitempty"`

	// OfferType: Type of offer.
	//
	// Possible values:
	//   "OFFER_TYPE_UNSPECIFIED" - Unset.
	//   "OFFER_TYPE_SPEND_X_GET_Y" - AdWords spend X get Y.
	//   "OFFER_TYPE_VIDEO" - Youtube video.
	//   "OFFER_TYPE_SPEND_MATCH" - Spend Match up to Y.
	OfferType string `json:"offerType,omitempty"`

	// QualifiedCustomer: Customers who qualify for this offer.
	QualifiedCustomer []*OfferCustomer `json:"qualifiedCustomer,omitempty"`

	// QualifiedCustomersComplete: Whether or not the list of qualified
	// customers is definitely complete.
	QualifiedCustomersComplete bool `json:"qualifiedCustomersComplete,omitempty"`

	// ShowSpecialOfferCopy: Should special text be shown on the offers
	// page.
	ShowSpecialOfferCopy bool `json:"showSpecialOfferCopy,omitempty"`

	// Terms: Terms of the offer.
	Terms string `json:"terms,omitempty"`

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

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

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

// Certification: A user's information on a specific certification.
type Certification struct {
	// Achieved: Whether this certification has been achieved.
	Achieved bool `json:"achieved,omitempty"`

	// CertificationType: The type of certification, the area of expertise.
	//
	// Possible values:
	//   "CERTIFICATION_TYPE_UNSPECIFIED" - Unchosen.
	//   "CT_ADWORDS" - AdWords certified.
	//   "CT_YOUTUBE" - YouTube certified.
	//   "CT_VIDEOADS" - VideoAds certified.
	//   "CT_ANALYTICS" - Analytics certified.
	//   "CT_DOUBLECLICK" - DoubleClick certified.
	//   "CT_SHOPPING" - Shopping certified.
	//   "CT_MOBILE" - Mobile certified.
	//   "CT_DIGITAL_SALES" - Digital sales certified.
	//   "CT_ADWORDS_SEARCH" - AdWords Search certified.
	//   "CT_ADWORDS_DISPLAY" - AdWords Display certified.
	//   "CT_MOBILE_SITES" - Mobile Sites certified.
	CertificationType string `json:"certificationType,omitempty"`

	// Expiration: Date this certification is due to expire.
	Expiration string `json:"expiration,omitempty"`

	// LastAchieved: The date the user last achieved certification.
	LastAchieved string `json:"lastAchieved,omitempty"`

	// Warning: Whether this certification is in the state of warning.
	Warning bool `json:"warning,omitempty"`

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

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

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

// CertificationExamStatus: Status for a Google Partners certification
// exam.
type CertificationExamStatus struct {
	// NumberUsersPass: The number of people who have passed the
	// certification exam.
	NumberUsersPass int64 `json:"numberUsersPass,omitempty"`

	// Type: The type of certification exam.
	//
	// Possible values:
	//   "CERTIFICATION_EXAM_TYPE_UNSPECIFIED" - Unchosen.
	//   "CET_ADWORDS_FUNDAMENTALS" - Adwords Fundamentals exam.
	//   "CET_ADWORDS_ADVANCED_SEARCH" - AdWords advanced search exam.
	//   "CET_ADWORDS_ADVANCED_DISPLAY" - AdWords advanced display exam.
	//   "CET_VIDEO_ADS" - VideoAds exam.
	//   "CET_DOUBLECLICK" - DoubleClick exam.
	//   "CET_ANALYTICS" - Analytics exam.
	//   "CET_SHOPPING" - Shopping exam.
	//   "CET_MOBILE" - Mobile exam.
	//   "CET_DIGITAL_SALES" - Digital Sales exam.
	//   "CET_MOBILE_SITES" - Mobile Sites exam.
	Type string `json:"type,omitempty"`

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

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

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

// CertificationStatus: Google Partners certification status.
type CertificationStatus struct {
	// ExamStatuses: List of certification exam statuses.
	ExamStatuses []*CertificationExamStatus `json:"examStatuses,omitempty"`

	// IsCertified: Whether certification is passing.
	IsCertified bool `json:"isCertified,omitempty"`

	// Type: The type of the certification.
	//
	// Possible values:
	//   "CERTIFICATION_TYPE_UNSPECIFIED" - Unchosen.
	//   "CT_ADWORDS" - AdWords certified.
	//   "CT_YOUTUBE" - YouTube certified.
	//   "CT_VIDEOADS" - VideoAds certified.
	//   "CT_ANALYTICS" - Analytics certified.
	//   "CT_DOUBLECLICK" - DoubleClick certified.
	//   "CT_SHOPPING" - Shopping certified.
	//   "CT_MOBILE" - Mobile certified.
	//   "CT_DIGITAL_SALES" - Digital sales certified.
	//   "CT_ADWORDS_SEARCH" - AdWords Search certified.
	//   "CT_ADWORDS_DISPLAY" - AdWords Display certified.
	//   "CT_MOBILE_SITES" - Mobile Sites certified.
	Type string `json:"type,omitempty"`

	// UserCount: Number of people who are certified,
	UserCount int64 `json:"userCount,omitempty"`

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

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

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

// Company: A company resource in the Google Partners API. Once
// certified, it qualifies
// for being searched by advertisers.
type Company struct {
	// AdditionalWebsites: URL of the company's additional websites used to
	// verify the dynamic badges.
	// These are stored as full URLs as entered by the user, but only the
	// TLD will
	// be used for the actual verification.
	AdditionalWebsites []string `json:"additionalWebsites,omitempty"`

	// AutoApprovalEmailDomains: Email domains that allow users with a
	// matching email address to get
	// auto-approved for associating with this company.
	AutoApprovalEmailDomains []string `json:"autoApprovalEmailDomains,omitempty"`

	// BadgeAuthorityInAwn: Whether the company's badge authority is in AWN
	BadgeAuthorityInAwn bool `json:"badgeAuthorityInAwn,omitempty"`

	// BadgeTier: Partner badge tier
	//
	// Possible values:
	//   "BADGE_TIER_NONE" - Tier badge is not set.
	//   "BADGE_TIER_REGULAR" - Agency has regular partner badge.
	//   "BADGE_TIER_PREMIER" - Agency has premier badge.
	BadgeTier string `json:"badgeTier,omitempty"`

	// CertificationStatuses: The list of Google Partners certification
	// statuses for the company.
	CertificationStatuses []*CertificationStatus `json:"certificationStatuses,omitempty"`

	// CompanyTypes: Company type labels listed on the company's profile.
	//
	// Possible values:
	//   "COMPANY_TYPE_UNSPECIFIED" - Unchosen.
	//   "FULL_SERVICE_AGENCY" - Handles all aspects of the advertising
	// process.
	//   "MEDIA_AGENCY" - Focuses solely on an advertiser's media placement.
	//   "CREATIVE_AGENCY" - Plans/executes advertising campaigns.
	//   "CDIGITAL_AGENCY" - Like a
	// FULL_SERVICE_AGENCY,
	// but specializing in digital.
	//   "SEM_SEO" - Increases visibility in search engine result pages.
	//   "PERFORMANCE_MARKETING" - Drives promotional efforts for immediate
	// impact.
	//   "ADVERTISING_TOOL_DEVELOPMENT" - Focuses on bid management,
	// conversion, reporting.
	//   "PR" - Establishes favorable relationship with public through
	// low/no-cost
	// communications.
	//   "SELF_MANAGED" - Does not manage other company's accounts, manages
	// own marketing programs.
	//   "RESELLER" - Full-service AdWords account management for local
	// businesses.
	CompanyTypes []string `json:"companyTypes,omitempty"`

	// ConvertedMinMonthlyBudget: The minimum monthly budget that the
	// company accepts for partner business,
	// converted to the requested currency code.
	ConvertedMinMonthlyBudget *Money `json:"convertedMinMonthlyBudget,omitempty"`

	// Id: The ID of the company.
	Id string `json:"id,omitempty"`

	// Industries: Industries the company can help with.
	//
	// Possible values:
	//   "INDUSTRY_UNSPECIFIED" - Unchosen.
	//   "I_AUTOMOTIVE" - The automotive industry.
	//   "I_BUSINESS_TO_BUSINESS" - The business-to-business industry.
	//   "I_CONSUMER_PACKAGED_GOODS" - The consumer packaged goods industry.
	//   "I_EDUCATION" - The education industry.
	//   "I_FINANCE" - The finance industry.
	//   "I_HEALTHCARE" - The healthcare industry.
	//   "I_MEDIA_AND_ENTERTAINMENT" - The media and entertainment industry.
	//   "I_RETAIL" - The retail industry.
	//   "I_TECHNOLOGY" - The technology industry.
	//   "I_TRAVEL" - The travel industry.
	Industries []string `json:"industries,omitempty"`

	// LocalizedInfos: The list of localized info for the company.
	LocalizedInfos []*LocalizedCompanyInfo `json:"localizedInfos,omitempty"`

	// Locations: The list of all company locations.
	// If set, must include the
	// primary_location
	// in the list.
	Locations []*Location `json:"locations,omitempty"`

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

	// OriginalMinMonthlyBudget: The unconverted minimum monthly budget that
	// the company accepts for partner
	// business.
	OriginalMinMonthlyBudget *Money `json:"originalMinMonthlyBudget,omitempty"`

	// PrimaryAdwordsManagerAccountId: The Primary AdWords Manager Account
	// id.
	PrimaryAdwordsManagerAccountId int64 `json:"primaryAdwordsManagerAccountId,omitempty,string"`

	// PrimaryLanguageCode: The primary language code of the company, as
	// defined by
	// <a href="https://tools.ietf.org/html/bcp47">BCP 47</a>
	// (IETF BCP 47, "Tags for Identifying Languages").
	PrimaryLanguageCode string `json:"primaryLanguageCode,omitempty"`

	// PrimaryLocation: The primary location of the company.
	PrimaryLocation *Location `json:"primaryLocation,omitempty"`

	// ProfileStatus: The public viewability status of the company's
	// profile.
	//
	// Possible values:
	//   "COMPANY_PROFILE_STATUS_UNSPECIFIED" - Unchosen.
	//   "HIDDEN" - Company profile does not show up publicly.
	//   "PUBLISHED" - Company profile can only be viewed by the profile's
	// URL
	// and not by Google Partner Search.
	//   "SEARCHABLE" - Company profile can be viewed by the profile's
	// URL
	// and by Google Partner Search.
	ProfileStatus string `json:"profileStatus,omitempty"`

	// PublicProfile: Basic information from the company's public profile.
	PublicProfile *PublicProfile `json:"publicProfile,omitempty"`

	// Ranks: Information related to the ranking of the company within the
	// list of
	// companies.
	Ranks []*Rank `json:"ranks,omitempty"`

	// Services: Services the company can help with.
	//
	// Possible values:
	//   "SERVICE_UNSPECIFIED" - Unchosen.
	//   "S_ADVANCED_ADWORDS_SUPPORT" - Help with advanced AdWords support.
	//   "S_ADVERTISING_ON_GOOGLE" - Help with advertising on Google.
	//   "S_AN_ENHANCED_WEBSITE" - Help with an enhanced website.
	//   "S_AN_ONLINE_MARKETING_PLAN" - Help with an online marketing plan.
	//   "S_MOBILE_AND_VIDEO_ADS" - Help with mobile and video ads.
	//   "S_MOBILE_WEBSITE_SERVICES" - Help with mobile websites.
	Services []string `json:"services,omitempty"`

	// SpecializationStatus: The list of Google Partners specialization
	// statuses for the company.
	SpecializationStatus []*SpecializationStatus `json:"specializationStatus,omitempty"`

	// WebsiteUrl: URL of the company's website.
	WebsiteUrl string `json:"websiteUrl,omitempty"`

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

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

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

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

// CompanyRelation: A CompanyRelation resource representing information
// about a user's
// affiliation and standing with a company in Partners.
type CompanyRelation struct {
	// Address: The primary address for this company.
	Address string `json:"address,omitempty"`

	// BadgeTier: Whether the company is a Partner.
	//
	// Possible values:
	//   "BADGE_TIER_NONE" - Tier badge is not set.
	//   "BADGE_TIER_REGULAR" - Agency has regular partner badge.
	//   "BADGE_TIER_PREMIER" - Agency has premier badge.
	BadgeTier string `json:"badgeTier,omitempty"`

	// CompanyAdmin: Indicates if the user is an admin for this company.
	CompanyAdmin bool `json:"companyAdmin,omitempty"`

	// CompanyId: The ID of the company. There may be no id if this is
	// a
	// pending company.5
	CompanyId string `json:"companyId,omitempty"`

	// CreationTime: The timestamp of when affiliation was
	// requested.
	// @OutputOnly
	CreationTime string `json:"creationTime,omitempty"`

	// InternalCompanyId: The internal company ID.
	// Only available for a whitelisted set of api clients.
	InternalCompanyId string `json:"internalCompanyId,omitempty"`

	// IsPending: The flag that indicates if the company is pending
	// verification.
	IsPending bool `json:"isPending,omitempty"`

	// LogoUrl: A URL to a profile photo, e.g. a G+ profile photo.
	LogoUrl string `json:"logoUrl,omitempty"`

	// ManagerAccount: The AdWords manager account # associated this
	// company.
	ManagerAccount int64 `json:"managerAccount,omitempty,string"`

	// Name: The name (in the company's primary language) for the company.
	Name string `json:"name,omitempty"`

	// PhoneNumber: The phone number for the company's primary address.
	PhoneNumber string `json:"phoneNumber,omitempty"`

	// PrimaryAddress: The primary location of the company.
	PrimaryAddress *Location `json:"primaryAddress,omitempty"`

	// PrimaryCountryCode: The primary country code of the company.
	PrimaryCountryCode string `json:"primaryCountryCode,omitempty"`

	// PrimaryLanguageCode: The primary language code of the company.
	PrimaryLanguageCode string `json:"primaryLanguageCode,omitempty"`

	// ResolvedTimestamp: The timestamp when the user was
	// approved.
	// @OutputOnly
	ResolvedTimestamp string `json:"resolvedTimestamp,omitempty"`

	// Segment: The segment the company is classified as.
	//
	// Possible values:
	//   "COMPANY_SEGMENT_UNKNOWN" - Default segment indicates an unknown.
	//   "COMPANY_SEGMENT_NAL" - Segment representing a selected group of
	// Partners
	//   "COMPANY_SEGMENT_PSP" - Segment representing Premier SMB Partners,
	// an AdWords partnership program.
	//   "COMPANY_SEGMENT_PPSP" - A segment of Premier SMB Partners that
	// have relationship with Google.
	Segment []string `json:"segment,omitempty"`

	// SpecializationStatus: The list of Google Partners specialization
	// statuses for the company.
	SpecializationStatus []*SpecializationStatus `json:"specializationStatus,omitempty"`

	// State: The state of relationship, in terms of approvals.
	//
	// Possible values:
	//   "USER_COMPANY_REATION_STATE_NONE_SPECIFIED" - Default unspecified
	// value.
	//   "USER_COMPANY_RELATION_STATE_AWAIT_EMAIL" - User has filled in a
	// request to be associated with an company.
	// Now waiting email confirmation.
	//   "USER_COMPANY_RELATION_STATE_AWAIT_ADMIN" - Pending approval from
	// company.
	// Email confirmation will not approve this one.
	//   "USER_COMPANY_RELATION_STATE_APPROVED" - Approved by company.
	State string `json:"state,omitempty"`

	// Website: The website URL for this company.
	Website string `json:"website,omitempty"`

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

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

// CountryOfferInfo: Offer info by country.
type CountryOfferInfo struct {
	// GetYAmount: (localized) Get Y amount for that country's offer.
	GetYAmount string `json:"getYAmount,omitempty"`

	// OfferCountryCode: Country code for which offer codes may be
	// requested.
	OfferCountryCode string `json:"offerCountryCode,omitempty"`

	// OfferType: Type of offer country is eligible for.
	//
	// Possible values:
	//   "OFFER_TYPE_UNSPECIFIED" - Unset.
	//   "OFFER_TYPE_SPEND_X_GET_Y" - AdWords spend X get Y.
	//   "OFFER_TYPE_VIDEO" - Youtube video.
	//   "OFFER_TYPE_SPEND_MATCH" - Spend Match up to Y.
	OfferType string `json:"offerType,omitempty"`

	// SpendXAmount: (localized) Spend X amount for that country's offer.
	SpendXAmount string `json:"spendXAmount,omitempty"`

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

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

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

// CreateLeadRequest: Request message for CreateLead.
type CreateLeadRequest struct {
	// Lead: The lead resource. The `LeadType` must not be
	// `LEAD_TYPE_UNSPECIFIED`
	// and either `email` or `phone_number` must be provided.
	Lead *Lead `json:"lead,omitempty"`

	// RecaptchaChallenge: <a
	// href="https://www.google.com/recaptcha/">reCaptcha</a> challenge
	// info.
	RecaptchaChallenge *RecaptchaChallenge `json:"recaptchaChallenge,omitempty"`

	// RequestMetadata: Current request metadata.
	RequestMetadata *RequestMetadata `json:"requestMetadata,omitempty"`

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

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

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

// CreateLeadResponse: Response message for CreateLead.
type CreateLeadResponse struct {
	// Lead: Lead that was created depending on the outcome of
	// <a href="https://www.google.com/recaptcha/">reCaptcha</a> validation.
	Lead *Lead `json:"lead,omitempty"`

	// RecaptchaStatus: The outcome of <a
	// href="https://www.google.com/recaptcha/">reCaptcha</a>
	// validation.
	//
	// Possible values:
	//   "RECAPTCHA_STATUS_UNSPECIFIED" - Unchosen.
	//   "RS_NOT_NEEDED" - No reCaptcha validation needed.
	//   "RS_PASSED" - reCaptcha challenge passed.
	//   "RS_FAILED" - reCaptcha challenge failed.
	RecaptchaStatus string `json:"recaptchaStatus,omitempty"`

	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

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

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

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

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

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

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

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

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

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

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

// DebugInfo: Debug information about this request.
type DebugInfo struct {
	// ServerInfo: Info about the server that serviced this request.
	ServerInfo string `json:"serverInfo,omitempty"`

	// ServerTraceInfo: Server-side debug stack trace.
	ServerTraceInfo string `json:"serverTraceInfo,omitempty"`

	// ServiceUrl: URL of the service that handled this request.
	ServiceUrl string `json:"serviceUrl,omitempty"`

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

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

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

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

// EventData: Key value data pair for an event.
type EventData struct {
	// Key: Data type.
	//
	// Possible values:
	//   "EVENT_DATA_TYPE_UNSPECIFIED" - Unchosen.
	//   "ACTION" - Action data.
	//   "AGENCY_ID" - Agency ID data.
	//   "AGENCY_NAME" - Agency name data.
	//   "AGENCY_PHONE_NUMBER" - Agency phone number data.
	//   "AGENCY_WEBSITE" - Agency website data.
	//   "BUDGET" - Budget data.
	//   "CENTER_POINT" - Center-point data.
	//   "CERTIFICATION" - Certification data.
	//   "COMMENT" - Comment data.
	//   "COUNTRY" - Country data.
	//   "CURRENCY" - Currency data.
	//   "CURRENTLY_VIEWED_AGENCY_ID" - Currently viewed agency ID data.
	//   "DISTANCE" - Distance data.
	//   "DISTANCE_TYPE" - Distance type data.
	//   "EXAM" - Exam data.
	//   "HISTORY_TOKEN" - History token data.
	//   "ID" - Identifier data.
	//   "INDUSTRY" - Industry data.
	//   "INSIGHT_TAG" - Insight tag data.
	//   "LANGUAGE" - Language data.
	//   "LOCATION" - Location  data.
	//   "MARKETING_OPT_IN" - Marketing opt-in data.
	//   "QUERY" - Query data.
	//   "SEARCH_START_INDEX" - Search start index data.
	//   "SERVICE" - Service data.
	//   "SHOW_VOW" - Show vow data.
	//   "SOLUTION" - Solution data.
	//   "TRAFFIC_SOURCE_ID" - Traffic source ID data.
	//   "TRAFFIC_SUB_ID" - Traffic sub ID data.
	//   "VIEW_PORT" - Viewport data.
	//   "WEBSITE" - Website data.
	//   "DETAILS" - Details data.
	//   "EXPERIMENT_ID" - Experiment ID data.
	//   "GPS_MOTIVATION" - Google Partner Search motivation data.
	//   "URL" - URL data.
	//   "ELEMENT_FOCUS" - Element we wanted user to focus on.
	//   "PROGRESS" - Progress when viewing an item \[0-100\].
	Key string `json:"key,omitempty"`

	// Values: Data values.
	Values []string `json:"values,omitempty"`

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

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

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

// ExamStatus: A user's information on a specific exam.
type ExamStatus struct {
	// ExamType: The type of the exam.
	//
	// Possible values:
	//   "CERTIFICATION_EXAM_TYPE_UNSPECIFIED" - Unchosen.
	//   "CET_ADWORDS_FUNDAMENTALS" - Adwords Fundamentals exam.
	//   "CET_ADWORDS_ADVANCED_SEARCH" - AdWords advanced search exam.
	//   "CET_ADWORDS_ADVANCED_DISPLAY" - AdWords advanced display exam.
	//   "CET_VIDEO_ADS" - VideoAds exam.
	//   "CET_DOUBLECLICK" - DoubleClick exam.
	//   "CET_ANALYTICS" - Analytics exam.
	//   "CET_SHOPPING" - Shopping exam.
	//   "CET_MOBILE" - Mobile exam.
	//   "CET_DIGITAL_SALES" - Digital Sales exam.
	//   "CET_MOBILE_SITES" - Mobile Sites exam.
	ExamType string `json:"examType,omitempty"`

	// Expiration: Date this exam is due to expire.
	Expiration string `json:"expiration,omitempty"`

	// LastPassed: The date the user last passed this exam.
	LastPassed string `json:"lastPassed,omitempty"`

	// Passed: Whether this exam has been passed and not expired.
	Passed bool `json:"passed,omitempty"`

	// Taken: The date the user last taken this exam.
	Taken string `json:"taken,omitempty"`

	// Warning: Whether this exam is in the state of warning.
	Warning bool `json:"warning,omitempty"`

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

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

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

// GetCompanyResponse: Response message for GetCompany.
type GetCompanyResponse struct {
	// Company: The company.
	Company *Company `json:"company,omitempty"`

	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

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

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

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

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

// GetPartnersStatusResponse: Response message for
// GetPartnersStatus.
type GetPartnersStatusResponse struct {
	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

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

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

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

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

// HistoricalOffer: Historical information about a Google Partners
// Offer.
type HistoricalOffer struct {
	// AdwordsUrl: Client's AdWords page URL.
	AdwordsUrl string `json:"adwordsUrl,omitempty"`

	// ClientEmail: Email address for client.
	ClientEmail string `json:"clientEmail,omitempty"`

	// ClientId: ID of client.
	ClientId int64 `json:"clientId,omitempty,string"`

	// ClientName: Name of the client.
	ClientName string `json:"clientName,omitempty"`

	// CreationTime: Time offer was first created.
	CreationTime string `json:"creationTime,omitempty"`

	// ExpirationTime: Time this offer expires.
	ExpirationTime string `json:"expirationTime,omitempty"`

	// LastModifiedTime: Time last action was taken.
	LastModifiedTime string `json:"lastModifiedTime,omitempty"`

	// OfferCode: Offer code.
	OfferCode string `json:"offerCode,omitempty"`

	// OfferCountryCode: Country Code for the offer country.
	OfferCountryCode string `json:"offerCountryCode,omitempty"`

	// OfferType: Type of offer.
	//
	// Possible values:
	//   "OFFER_TYPE_UNSPECIFIED" - Unset.
	//   "OFFER_TYPE_SPEND_X_GET_Y" - AdWords spend X get Y.
	//   "OFFER_TYPE_VIDEO" - Youtube video.
	//   "OFFER_TYPE_SPEND_MATCH" - Spend Match up to Y.
	OfferType string `json:"offerType,omitempty"`

	// SenderName: Name (First + Last) of the partners user to whom the
	// incentive is allocated.
	SenderName string `json:"senderName,omitempty"`

	// Status: Status of the offer.
	//
	// Possible values:
	//   "OFFER_STATUS_UNSPECIFIED" - Unset.
	//   "OFFER_STATUS_DISTRIBUTED" - Offer distributed.
	//   "OFFER_STATUS_REDEEMED" - Offer redeemed.
	//   "OFFER_STATUS_AWARDED" - Offer awarded.
	//   "OFFER_STATUS_EXPIRED" - Offer expired.
	Status string `json:"status,omitempty"`

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

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

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

// LatLng: An object representing a latitude/longitude pair. This is
// expressed as a pair
// of doubles representing degrees latitude and degrees longitude.
// Unless
// specified otherwise, this must conform to the
// <a
// href="http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf">WGS84
// st
// andard</a>. Values must be within normalized ranges.
type LatLng struct {
	// Latitude: The latitude in degrees. It must be in the range [-90.0,
	// +90.0].
	Latitude float64 `json:"latitude,omitempty"`

	// Longitude: The longitude in degrees. It must be in the range [-180.0,
	// +180.0].
	Longitude float64 `json:"longitude,omitempty"`

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

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

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

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

// Lead: A lead resource that represents an advertiser contact for a
// `Company`. These
// are usually generated via Google Partner Search (the advertiser
// portal).
type Lead struct {
	// AdwordsCustomerId: The AdWords Customer ID of the lead.
	AdwordsCustomerId int64 `json:"adwordsCustomerId,omitempty,string"`

	// Comments: Comments lead source gave.
	Comments string `json:"comments,omitempty"`

	// CreateTime: Timestamp of when this lead was created.
	CreateTime string `json:"createTime,omitempty"`

	// Email: Email address of lead source.
	Email string `json:"email,omitempty"`

	// FamilyName: Last name of lead source.
	FamilyName string `json:"familyName,omitempty"`

	// GivenName: First name of lead source.
	GivenName string `json:"givenName,omitempty"`

	// GpsMotivations: List of reasons for using Google Partner Search and
	// creating a lead.
	//
	// Possible values:
	//   "GPS_MOTIVATION_UNSPECIFIED" - Unchosen.
	//   "GPSM_HELP_WITH_ADVERTISING" - Advertiser needs help with their
	// advertising.
	//   "GPSM_HELP_WITH_WEBSITE" - Advertiser needs help with their
	// website.
	//   "GPSM_NO_WEBSITE" - Advertiser does not have a website.
	GpsMotivations []string `json:"gpsMotivations,omitempty"`

	// Id: ID of the lead.
	Id string `json:"id,omitempty"`

	// LanguageCode: Language code of the lead's language preference, as
	// defined by
	// <a href="https://tools.ietf.org/html/bcp47">BCP 47</a>
	// (IETF BCP 47, "Tags for Identifying Languages").
	LanguageCode string `json:"languageCode,omitempty"`

	// MarketingOptIn: Whether or not the lead signed up for marketing
	// emails
	MarketingOptIn bool `json:"marketingOptIn,omitempty"`

	// MinMonthlyBudget: The minimum monthly budget lead source is willing
	// to spend.
	MinMonthlyBudget *Money `json:"minMonthlyBudget,omitempty"`

	// PhoneNumber: Phone number of lead source.
	PhoneNumber string `json:"phoneNumber,omitempty"`

	// State: The lead's state in relation to the company.
	//
	// Possible values:
	//   "LEAD_STATE_UNSPECIFIED" - Unchosen.
	//   "LEAD" - Lead not yet contacted.
	//   "CONTACTED" - Lead has been contacted.
	//   "CLIENT" - Lead has become a client.
	//   "OTHER" - Lead in a state not covered by other options.
	State string `json:"state,omitempty"`

	// Type: Type of lead.
	//
	// Possible values:
	//   "LEAD_TYPE_UNSPECIFIED" - Unchosen.
	//   "LT_GPS" - Google Partner Search.
	Type string `json:"type,omitempty"`

	// WebsiteUrl: Website URL of lead source.
	WebsiteUrl string `json:"websiteUrl,omitempty"`

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

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

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

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

// ListAnalyticsResponse: Response message for
// ListAnalytics.
type ListAnalyticsResponse struct {
	// Analytics: The list of analytics.
	// Sorted in ascending order of
	// Analytics.event_date.
	Analytics []*Analytics `json:"analytics,omitempty"`

	// AnalyticsSummary: Aggregated information across the
	// response's
	// analytics.
	AnalyticsSummary *AnalyticsSummary `json:"analyticsSummary,omitempty"`

	// NextPageToken: A token to retrieve next page of results.
	// Pass this value in the `ListAnalyticsRequest.page_token` field in
	// the
	// subsequent call to
	// ListAnalytics to retrieve the
	// next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

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

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

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

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

// ListCompaniesResponse: Response message for
// ListCompanies.
type ListCompaniesResponse struct {
	// Companies: The list of companies.
	Companies []*Company `json:"companies,omitempty"`

	// NextPageToken: A token to retrieve next page of results.
	// Pass this value in the `ListCompaniesRequest.page_token` field in
	// the
	// subsequent call to
	// ListCompanies to retrieve the
	// next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

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

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

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

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

// ListLeadsResponse: Response message for ListLeads.
type ListLeadsResponse struct {
	// Leads: The list of leads.
	Leads []*Lead `json:"leads,omitempty"`

	// NextPageToken: A token to retrieve next page of results.
	// Pass this value in the `ListLeadsRequest.page_token` field in
	// the
	// subsequent call to
	// ListLeads to retrieve the
	// next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

	// TotalSize: The total count of leads for the given company.
	TotalSize int64 `json:"totalSize,omitempty"`

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

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

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

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

// ListOffersHistoryResponse: Response for ListOfferHistory.
type ListOffersHistoryResponse struct {
	// CanShowEntireCompany: True if the user has the option to show entire
	// company history.
	CanShowEntireCompany bool `json:"canShowEntireCompany,omitempty"`

	// NextPageToken: Supply this token in a ListOffersHistoryRequest to
	// retrieve the next page.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Offers: Historical offers meeting request.
	Offers []*HistoricalOffer `json:"offers,omitempty"`

	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

	// ShowingEntireCompany: True if this response is showing entire company
	// history.
	ShowingEntireCompany bool `json:"showingEntireCompany,omitempty"`

	// TotalResults: Number of results across all pages.
	TotalResults int64 `json:"totalResults,omitempty"`

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

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

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

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

// ListOffersResponse: Response for ListOffer.
type ListOffersResponse struct {
	// AvailableOffers: Available Offers to be distributed.
	AvailableOffers []*AvailableOffer `json:"availableOffers,omitempty"`

	// NoOfferReason: Reason why no Offers are available.
	//
	// Possible values:
	//   "NO_OFFER_REASON_UNSPECIFIED" - Unset.
	//   "NO_OFFER_REASON_NO_MCC" - Not an MCC.
	//   "NO_OFFER_REASON_LIMIT_REACHED" - Offer limit has been reached.
	//   "NO_OFFER_REASON_INELIGIBLE" - Ineligible for offers.
	NoOfferReason string `json:"noOfferReason,omitempty"`

	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

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

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

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

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

// ListUserStatesResponse: Response message for
// ListUserStates.
type ListUserStatesResponse struct {
	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

	// UserStates: User's states.
	//
	// Possible values:
	//   "USER_STATE_UNSPECIFIED" - Unchosen.
	//   "US_REQUIRES_RECAPTCHA_FOR_GPS_CONTACT" - User must pass <a
	// href="https://www.google.com/recaptcha/">reCaptcha</a> to
	// contact a Partner via Google Partner Search.
	UserStates []string `json:"userStates,omitempty"`

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

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

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

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

// LocalizedCompanyInfo: The localized company information.
type LocalizedCompanyInfo struct {
	// CountryCodes: List of country codes for the localized company info.
	CountryCodes []string `json:"countryCodes,omitempty"`

	// DisplayName: Localized display name.
	DisplayName string `json:"displayName,omitempty"`

	// LanguageCode: Language code of the localized company info, as defined
	// by
	// <a href="https://tools.ietf.org/html/bcp47">BCP 47</a>
	// (IETF BCP 47, "Tags for Identifying Languages").
	LanguageCode string `json:"languageCode,omitempty"`

	// Overview: Localized brief description that the company uses to
	// advertise themselves.
	Overview string `json:"overview,omitempty"`

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

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

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

// Location: A location with address and geographic coordinates. May
// optionally contain a
// detailed (multi-field) version of the address.
type Location struct {
	// Address: The single string version of the address.
	Address string `json:"address,omitempty"`

	// AddressLine: The following address lines represent the most specific
	// part of any
	// address.
	AddressLine []string `json:"addressLine,omitempty"`

	// AdministrativeArea: Top-level administrative subdivision of this
	// country.
	AdministrativeArea string `json:"administrativeArea,omitempty"`

	// DependentLocality: Dependent locality or sublocality. Used for UK
	// dependent localities, or
	// neighborhoods or boroughs in other locations.
	DependentLocality string `json:"dependentLocality,omitempty"`

	// LanguageCode: Language code of the address. Should be in BCP 47
	// format.
	LanguageCode string `json:"languageCode,omitempty"`

	// LatLng: The latitude and longitude of the location, in degrees.
	LatLng *LatLng `json:"latLng,omitempty"`

	// Locality: Generally refers to the city/town portion of an address.
	Locality string `json:"locality,omitempty"`

	// PostalCode: Values are frequently alphanumeric.
	PostalCode string `json:"postalCode,omitempty"`

	// RegionCode: CLDR (Common Locale Data Repository) region code .
	RegionCode string `json:"regionCode,omitempty"`

	// SortingCode: Use of this code is very country-specific, but will
	// refer to a secondary
	// classification code for sorting mail.
	SortingCode string `json:"sortingCode,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 *Location) MarshalJSON() ([]byte, error) {
	type NoMethod Location
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LogMessageRequest: Request message for
// LogClientMessage.
type LogMessageRequest struct {
	// ClientInfo: Map of client info, such as URL, browser navigator,
	// browser platform, etc.
	ClientInfo map[string]string `json:"clientInfo,omitempty"`

	// Details: Details about the client message.
	Details string `json:"details,omitempty"`

	// Level: Message level of client message.
	//
	// Possible values:
	//   "MESSAGE_LEVEL_UNSPECIFIED" - Unchosen.
	//   "ML_FINE" - Message level for tracing information.
	//   "ML_INFO" - Message level for informational messages.
	//   "ML_WARNING" - Message level for potential problems.
	//   "ML_SEVERE" - Message level for serious failures.
	Level string `json:"level,omitempty"`

	// RequestMetadata: Current request metadata.
	RequestMetadata *RequestMetadata `json:"requestMetadata,omitempty"`

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

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

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

// LogMessageResponse: Response message for
// LogClientMessage.
type LogMessageResponse struct {
	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

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

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

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

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

// LogUserEventRequest: Request message for
// LogUserEvent.
type LogUserEventRequest struct {
	// EventAction: The action that occurred.
	//
	// Possible values:
	//   "EVENT_ACTION_UNSPECIFIED" - Unchosen.
	//   "SMB_CLICKED_FIND_A_PARTNER_BUTTON_BOTTOM" - Advertiser clicked
	// `Find a partner` bottom button.
	//   "SMB_CLICKED_FIND_A_PARTNER_BUTTON_TOP" - Advertiser clicked `Find
	// a partner` top button.
	//   "AGENCY_CLICKED_JOIN_NOW_BUTTON_BOTTOM" - Agency clicked `Join now`
	// bottom button.
	//   "AGENCY_CLICKED_JOIN_NOW_BUTTON_TOP" - Agency clicked `Join now`
	// top button.
	//   "SMB_CANCELED_PARTNER_CONTACT_FORM" - Advertiser canceled partner
	// contact form.
	//   "SMB_CLICKED_CONTACT_A_PARTNER" - Advertiser started partner
	// contact form.
	//   "SMB_COMPLETED_PARTNER_CONTACT_FORM" - Advertiser completed partner
	// contact form.
	//   "SMB_ENTERED_EMAIL_IN_CONTACT_PARTNER_FORM" - Advertiser entered
	// email in contact form.
	//   "SMB_ENTERED_NAME_IN_CONTACT_PARTNER_FORM" - Advertiser entered
	// name in contact form.
	//   "SMB_ENTERED_PHONE_IN_CONTACT_PARTNER_FORM" - Advertiser entered
	// phone in contact form.
	//   "SMB_FAILED_RECAPTCHA_IN_CONTACT_PARTNER_FORM" - Advertiser failed
	// <a href="https://www.google.com/recaptcha/">reCaptcha</a>
	// in contact form.
	//   "PARTNER_VIEWED_BY_SMB" - Company viewed by advertiser.
	//   "SMB_CANCELED_PARTNER_CONTACT_FORM_ON_GPS" - Advertiser canceled
	// partner contact form on Google Partner Search.
	//   "SMB_CHANGED_A_SEARCH_PARAMETER_TOP" - Advertiser changed a top
	// search parameter.
	//   "SMB_CLICKED_CONTACT_A_PARTNER_ON_GPS" - Advertiser started partner
	// contact form on Google Partner Search.
	//   "SMB_CLICKED_SHOW_MORE_PARTNERS_BUTTON_BOTTOM" - Advertiser clicked
	// `Show more partners` bottom button.
	//   "SMB_COMPLETED_PARTNER_CONTACT_FORM_ON_GPS" - Advertiser completed
	// partner contact form on Google Partner Search.
	//   "SMB_NO_PARTNERS_AVAILABLE_WITH_SEARCH_CRITERIA" - Advertiser saw
	// no partners available with search criteria.
	//   "SMB_PERFORMED_SEARCH_ON_GPS" - Advertiser performed search on
	// Google Partner Search.
	//   "SMB_VIEWED_A_PARTNER_ON_GPS" - Advertiser viewed a partner on
	// Google Partner Search.
	//   "SMB_CANCELED_PARTNER_CONTACT_FORM_ON_PROFILE_PAGE" - Advertiser
	// canceled partner contact form on profile page.
	//   "SMB_CLICKED_CONTACT_A_PARTNER_ON_PROFILE_PAGE" - Advertiser
	// started partner contact form on profile page.
	//   "SMB_CLICKED_PARTNER_WEBSITE" - Advertiser clicked partner website.
	//   "SMB_COMPLETED_PARTNER_CONTACT_FORM_ON_PROFILE_PAGE" - Advertiser
	// completed contact form on profile page.
	//   "SMB_VIEWED_A_PARTNER_PROFILE" - Advertiser viewed a partner
	// profile.
	//   "AGENCY_CLICKED_ACCEPT_TOS_BUTTON" - Agency clicked `accept Terms
	// Of Service` button.
	//   "AGENCY_CHANGED_TOS_COUNTRY" - Agency changed Terms Of Service
	// country.
	//   "AGENCY_ADDED_ADDRESS_IN_MY_PROFILE_PORTAL" - Agency added address
	// in profile portal.
	//   "AGENCY_ADDED_PHONE_NUMBER_IN_MY_PROFILE_PORTAL" - Agency added
	// phone number in profile portal.
	//   "AGENCY_CHANGED_PRIMARY_ACCOUNT_ASSOCIATION" - Agency changed
	// primary account association.
	//   "AGENCY_CHANGED_PRIMARY_COUNTRY_ASSOCIATION" - Agency changed
	// primary country association.
	//   "AGENCY_CLICKED_AFFILIATE_BUTTON_IN_MY_PROFILE_IN_PORTAL" - Agency
	// clicked `affiliate` button in profile portal.
	//   "AGENCY_CLICKED_GIVE_EDIT_ACCESS_IN_MY_PROFILE_PORTAL" - Agency
	// clicked `give edit access` in profile portal.
	//   "AGENCY_CLICKED_LOG_OUT_IN_MY_PROFILE_PORTAL" - Agency clicked `log
	// out` in profile portal.
	//   "AGENCY_CLICKED_MY_PROFILE_LEFT_NAV_IN_PORTAL" - Agency clicked
	// profile portal left nav.
	//   "AGENCY_CLICKED_SAVE_AND_CONTINUE_AT_BOT_OF_COMPLETE_PROFILE" -
	// Agency clicked `save and continue` at bottom of complete profile.
	//   "AGENCY_CLICKED_UNAFFILIATE_IN_MY_PROFILE_PORTAL" - Agency clicked
	// `unaffiliate` in profile portal.
	//   "AGENCY_FILLED_OUT_COMP_AFFILIATION_IN_MY_PROFILE_PORTAL" - Agency
	// filled out company affiliation in profile portal.
	//   "AGENCY_SUCCESSFULLY_CONNECTED_WITH_COMPANY_IN_MY_PROFILE" - Agency
	// successfully connected with company in profile portal.
	//   "AGENCY_CLICKED_CREATE_MCC_IN_MY_PROFILE_PORTAL" - Agency clicked
	// create MCC in profile portal.
	//   "AGENCY_DIDNT_HAVE_AN_MCC_ASSOCIATED_ON_COMPLETE_PROFILE" - Agency
	// did not have an MCC associated on profile portal.
	//   "AGENCY_HAD_AN_MCC_ASSOCIATED_ON_COMPLETE_PROFILE" - Agency had an
	// MCC associated on profile portal.
	//   "AGENCY_ADDED_JOB_FUNCTION_IN_MY_PROFILE_PORTAL" - Agency added job
	// function in profile portal.
	//   "AGENCY_LOOKED_AT_JOB_FUNCTION_DROP_DOWN" - Agency looked at job
	// function drop-down.
	//   "AGENCY_SELECTED_ACCOUNT_MANAGER_AS_JOB_FUNCTION" - Agency selected
	// `account manage` as job function.
	//   "AGENCY_SELECTED_ACCOUNT_PLANNER_AS_JOB_FUNCTION" - Agency selected
	// `account planner` as job function.
	//   "AGENCY_SELECTED_ANALYTICS_AS_JOB_FUNCTION" - Agency selected
	// `Analytics` as job function.
	//   "AGENCY_SELECTED_CREATIVE_AS_JOB_FUNCTION" - Agency selected
	// `creative` as job function.
	//   "AGENCY_SELECTED_MEDIA_BUYER_AS_JOB_FUNCTION" - Agency selected
	// `media buyer` as job function.
	//   "AGENCY_SELECTED_MEDIA_PLANNER_AS_JOB_FUNCTION" - Agency selected
	// `media planner` as job function.
	//   "AGENCY_SELECTED_OTHER_AS_JOB_FUNCTION" - Agency selected `other`
	// as job function.
	//   "AGENCY_SELECTED_PRODUCTION_AS_JOB_FUNCTION" - Agency selected
	// `production` as job function.
	//   "AGENCY_SELECTED_SEO_AS_JOB_FUNCTION" - Agency selected `SEO` as
	// job function.
	//   "AGENCY_SELECTED_SALES_REP_AS_JOB_FUNCTION" - Agency selected
	// `sales rep` as job function.
	//   "AGENCY_SELECTED_SEARCH_SPECIALIST_AS_JOB_FUNCTION" - Agency
	// selected `search specialist` as job function.
	//   "AGENCY_ADDED_CHANNELS_IN_MY_PROFILE_PORTAL" - Agency added
	// channels in profile portal.
	//   "AGENCY_LOOKED_AT_ADD_CHANNEL_DROP_DOWN" - Agency looked at `add
	// channel` drop-down.
	//   "AGENCY_SELECTED_CROSS_CHANNEL_FROM_ADD_CHANNEL" - Agency selected
	// `cross channel` from add channel drop-down.
	//   "AGENCY_SELECTED_DISPLAY_FROM_ADD_CHANNEL" - Agency selected
	// `display` from add channel drop-down.
	//   "AGENCY_SELECTED_MOBILE_FROM_ADD_CHANNEL" - Agency selected
	// `mobile` from add channel drop-down.
	//   "AGENCY_SELECTED_SEARCH_FROM_ADD_CHANNEL" - Agency selected
	// `search` from add channel drop-down.
	//   "AGENCY_SELECTED_SOCIAL_FROM_ADD_CHANNEL" - Agency selected
	// `social` from add channel drop-down.
	//   "AGENCY_SELECTED_TOOLS_FROM_ADD_CHANNEL" - Agency selected `tools`
	// from add channel drop-down.
	//   "AGENCY_SELECTED_YOUTUBE_FROM_ADD_CHANNEL" - Agency selected
	// `YouTube` from add channel drop-down.
	//   "AGENCY_ADDED_INDUSTRIES_IN_MY_PROFILE_PORTAL" - Agency added
	// industries in profile portal.
	//   "AGENCY_CHANGED_ADD_INDUSTRIES_DROP_DOWN" - Agency changed `add
	// industries` drop-down.
	//   "AGENCY_ADDED_MARKETS_IN_MY_PROFILE_PORTAL" - Agency added markets
	// in profile portal.
	//   "AGENCY_CHANGED_ADD_MARKETS_DROP_DOWN" - Agency changed `add
	// markets` drop-down.
	//   "AGENCY_CHECKED_RECIEVE_MAIL_PROMOTIONS_MYPROFILE" - Agency checked
	// `recieve mail promotions` in profile portal.
	//   "AGENCY_CHECKED_RECIEVE_MAIL_PROMOTIONS_SIGNUP" - Agency checked
	// `recieve mail promotions` in sign-up.
	//   "AGENCY_SELECTED_OPT_IN_BETA_TESTS_AND_MKT_RESEARCH" - Agency
	// selected `opt-in beta tests and market research`.
	//   "AGENCY_SELECTED_OPT_IN_BETA_TESTS_IN_MY_PROFILE_PORTAL" - Agency
	// selected `opt-in beta tests` in profile portal.
	//   "AGENCY_SELECTED_OPT_IN_NEWS_IN_MY_PROFILE_PORTAL" - Agency
	// selected `opt-in news` in profile portal.
	//   "AGENCY_SELECTED_OPT_IN_NEWS_INVITATIONS_AND_PROMOS" - Agency
	// selected `opt-in news invitations and promotions`.
	//   "AGENCY_SELECTED_OPT_IN_PERFORMANCE_SUG_IN_MY_PROFILE_PORTAL" -
	// Agency selected `opt-in performance SUG` in profile portal.
	//   "AGENCY_SELECTED_OPT_IN_PERFORMANCE_SUGGESTIONS" - Agency selected
	// `opt-in performance suggestions`.
	//   "AGENCY_SELECTED_OPT_IN_SELECT_ALL_EMAIL_NOTIFICATIONS" - Agency
	// selected `opt-in select all email notifications`.
	//   "AGENCY_SELECTED_SELECT_ALL_OPT_INS_IN_MY_PROFILE_PORTAL" - Agency
	// selected `select all opt-ins` in profile portal.
	//   "AGENCY_CLICKED_BACK_BUTTON_ON_CONNECT_WITH_COMPANY" - Agency
	// clicked back button on `connect with company`.
	//   "AGENCY_CLICKED_CONTINUE_TO_OVERVIEW_ON_CONNECT_WITH_COMPANY" -
	// Agency clicked continue to overview on `connect with company`.
	//   "AGECNY_CLICKED_CREATE_MCC_CONNECT_WITH_COMPANY_NOT_FOUND" - Agency
	// clicked `create MCC connect with company not found`.
	//   "AGECNY_CLICKED_GIVE_EDIT_ACCESS_CONNECT_WITH_COMPANY_NOT_FOUND" -
	// Agency clicked `give edit access connect with company not found`.
	//   "AGECNY_CLICKED_LOG_OUT_CONNECT_WITH_COMPANY_NOT_FOUND" - Agency
	// clicked `log out connect with company not found`.
	//   "AGENCY_CLICKED_SKIP_FOR_NOW_ON_CONNECT_WITH_COMPANY_PAGE" - Agency
	// clicked `skip for now on connect with company page`.
	//   "AGENCY_CLOSED_CONNECTED_TO_COMPANY_X_BUTTON_WRONG_COMPANY" -
	// Agency closed connection to company.
	//   "AGENCY_COMPLETED_FIELD_CONNECT_WITH_COMPANY" - Agency completed
	// field connect with company.
	//   "AGECNY_FOUND_COMPANY_TO_CONNECT_WITH" - Agency found company to
	// connect with.
	//   "AGENCY_SUCCESSFULLY_CREATED_COMPANY" - Agency successfully created
	// company.
	//   "AGENCY_ADDED_NEW_COMPANY_LOCATION" - Agency added new company
	// location.
	//   "AGENCY_CLICKED_COMMUNITY_JOIN_NOW_LINK_IN_PORTAL_NOTIFICATIONS" -
	// Agency clicked community `join now link` in portal notifications.
	//   "AGENCY_CLICKED_CONNECT_TO_COMPANY_LINK_IN_PORTAL_NOTIFICATIONS" -
	// Agency clicked `connect to company` link in portal notifications.
	//   "AGENCY_CLICKED_GET_CERTIFIED_LINK_IN_PORTAL_NOTIFICATIONS" -
	// Agency cliecked `get certified` link in portal notifications.
	//
	// "AGENCY_CLICKED_GET_VIDEO_ADS_CERTIFIED_LINK_IN_PORTAL_NOTIFICATIONS"
	// - Agency clicked `get VideoAds certified` link in portal
	// notifications.
	//   "AGENCY_CLICKED_LINK_TO_MCC_LINK_IN_PORTAL_NOTIFICATIONS" - Agency
	// clicked `link to MCC` link in portal notifications.
	//   "AGENCY_CLICKED_INSIGHT_CONTENT_IN_PORTAL" - Agency clicked
	// `insight content` in portal.
	//   "AGENCY_CLICKED_INSIGHTS_VIEW_NOW_PITCH_DECKS_IN_PORTAL" - Agency
	// clicked `insights view now pitch decks` in portal.
	//   "AGENCY_CLICKED_INSIGHTS_LEFT_NAV_IN_PORTAL" - Agency clicked
	// `insights` left nav in portal.
	//   "AGENCY_CLICKED_INSIGHTS_UPLOAD_CONTENT" - Agency clicked `insights
	// upload content`.
	//   "AGENCY_CLICKED_INSIGHTS_VIEWED_DEPRECATED" - Agency clicked
	// `insights viewed deprecated`.
	//   "AGENCY_CLICKED_COMMUNITY_LEFT_NAV_IN_PORTAL" - Agency clicked
	// `community` left nav in portal.
	//   "AGENCY_CLICKED_JOIN_COMMUNITY_BUTTON_COMMUNITY_PORTAL" - Agency
	// clicked `join community` button in community portal.
	//   "AGENCY_CLICKED_CERTIFICATIONS_LEFT_NAV_IN_PORTAL" - Agency clicked
	// `certifications` left nav in portal.
	//   "AGENCY_CLICKED_CERTIFICATIONS_PRODUCT_LEFT_NAV_IN_PORTAL" - Agency
	// clicked `certifications product` left nav in portal.
	//   "AGENCY_CLICKED_PARTNER_STATUS_LEFT_NAV_IN_PORTAL" - Agency clicked
	// `partner status` left nav in portal.
	//   "AGENCY_CLICKED_PARTNER_STATUS_PRODUCT_LEFT_NAV_IN_PORTAL" - Agency
	// clicked `partner status product` left nav in portal.
	//   "AGENCY_CLICKED_OFFERS_LEFT_NAV_IN_PORTAL" - Agency clicked
	// `offers` left nav in portal.
	//   "AGENCY_CLICKED_SEND_BUTTON_ON_OFFERS_PAGE" - Agency clicked `send`
	// button on offers page.
	//   "AGENCY_CLICKED_EXAM_DETAILS_ON_CERT_ADWORDS_PAGE" - Agency clicked
	// `exam details` on certifications AdWords page.
	//   "AGENCY_CLICKED_SEE_EXAMS_CERTIFICATION_MAIN_PAGE" - Agency clicked
	// `see exams` certifications main page.
	//   "AGENCY_CLICKED_TAKE_EXAM_ON_CERT_EXAM_PAGE" - Agency clicked `take
	// exam` on certifications exam page.
	//   "AGENCY_OPENED_LAST_ADMIN_DIALOG" - Agency opened `last admin`
	// dialog.
	//   "AGENCY_OPENED_DIALOG_WITH_NO_USERS" - Agency opened dialog with no
	// users.
	//   "AGENCY_PROMOTED_USER_TO_ADMIN" - Agency promoted user to admin.
	//   "AGENCY_UNAFFILIATED" - Agency unaffiliated.
	//   "AGENCY_CHANGED_ROLES" - Agency changed roles.
	//   "SMB_CLICKED_COMPANY_NAME_LINK_TO_PROFILE" - Advertiser clicked
	// `company name` link to profile.
	//   "SMB_VIEWED_ADWORDS_CERTIFICATE" - Advertiser viewed AdWords
	// certificate.
	//   "SMB_VIEWED_ADWORDS_SEARCH_CERTIFICATE" - Advertiser viewed AdWords
	// Search certificate.
	//   "SMB_VIEWED_ADWORDS_DISPLAY_CERTIFICATE" - Advertiser viewed
	// AdWords Display certificate.
	//   "SMB_CLICKED_ADWORDS_CERTIFICATE_HELP_ICON" - Advertiser clicked
	// AdWords certificate help icon.
	//   "SMB_VIEWED_ANALYTICS_CERTIFICATE" - Advertiser viewed Analytics
	// certificate.
	//   "SMB_VIEWED_DOUBLECLICK_CERTIFICATE" - Advertiser viewed
	// DoubleClick certificate.
	//   "SMB_VIEWED_MOBILE_SITES_CERTIFICATE" - Advertiser viewed Mobile
	// Sites certificate.
	//   "SMB_VIEWED_VIDEO_ADS_CERTIFICATE" - Advertiser viewed VideoAds
	// certificate.
	//   "SMB_VIEWED_SHOPPING_CERTIFICATE" - Advertiser clicked Shopping
	// certificate help icon.
	//   "SMB_CLICKED_VIDEO_ADS_CERTIFICATE_HELP_ICON" - Advertiser clicked
	// VideoAds certificate help icon.
	//   "SMB_VIEWED_DIGITAL_SALES_CERTIFICATE" - Advertiser viewed Digital
	// Sales certificate.
	//   "CLICKED_HELP_AT_BOTTOM" - Clicked `help` at bottom.
	//   "CLICKED_HELP_AT_TOP" - Clicked `help` at top.
	//   "CLIENT_ERROR" - Client error occurred.
	//   "AGENCY_CLICKED_LEFT_NAV_STORIES" - Agency clicked left nav
	// `stories`.
	//   "CLICKED" - Click occured.
	//   "SMB_VIEWED_MOBILE_CERTIFICATE" - Advertiser clicked Mobile
	// certificate help icon.
	//   "AGENCY_FAILED_COMPANY_VERIFICATION" - Agency failed the company
	// verification.
	//   "VISITED_LANDING" - User visited the landing portion of Google
	// Partners.
	//   "VISITED_GPS" - User visited the Google Partner Search portion of
	// Google Partners.
	//   "VISITED_AGENCY_PORTAL" - User visited the agency portal portion of
	// Google Partners.
	//   "CANCELLED_INDIVIDUAL_SIGN_UP" - User cancelled signing up.
	//   "CANCELLED_COMPANY_SIGN_UP" - User cancelled signing up their
	// company.
	//   "AGENCY_CLICKED_SIGN_IN_BUTTON_TOP" - Agency clicked `Sign in` top
	// button.
	//   "AGENCY_CLICKED_SAVE_AND_CONTINUE_AT_BOT_OF_INCOMPLETE_PROFILE" -
	// Agency clicked `save and continue` at bottom of incomplete profile.
	//   "AGENCY_UNSELECTED_OPT_IN_NEWS_INVITATIONS_AND_PROMOS" - Agency
	// unselected `opt-in news invitations and promotions`.
	//   "AGENCY_UNSELECTED_OPT_IN_BETA_TESTS_AND_MKT_RESEARCH" - Agency
	// unselected `opt-in beta tests and market research`.
	//   "AGENCY_UNSELECTED_OPT_IN_PERFORMANCE_SUGGESTIONS" - Agency
	// unselected `opt-in performance suggestions`.
	//   "AGENCY_SELECTED_OPT_OUT_UNSELECT_ALL_EMAIL_NOTIFICATIONS" - Agency
	// selected `opt-out unselect all email notifications`.
	//   "AGENCY_LINKED_INDIVIDUAL_MCC" - Agency linked their individual
	// MCC.
	//   "AGENCY_SUGGESTED_TO_USER" - Agency was suggested to user for
	// affiliation.
	//   "AGENCY_IGNORED_SUGGESTED_AGENCIES_AND_SEARCHED" - Agency ignored
	// suggested agencies and begin searching.
	//   "AGENCY_PICKED_SUGGESTED_AGENCY" - Agency picked a suggested
	// agency.
	//   "AGENCY_SEARCHED_FOR_AGENCIES" - Agency searched for agencies.
	//   "AGENCY_PICKED_SEARCHED_AGENCY" - Agency picked a searched agency.
	//   "AGENCY_DISMISSED_AFFILIATION_WIDGET" - Agency dismissed
	// affiliation widget.
	//   "AGENCY_CLICKED_INSIGHTS_DOWNLOAD_CONTENT" - Agency clicked on the
	// download link for downloading content.
	//   "AGENCY_PROGRESS_INSIGHTS_VIEW_CONTENT" - Agency user is maklingg
	// progress viewing a content item.
	//   "AGENCY_CLICKED_CANCEL_ACCEPT_TOS_BUTTON" - Agency clicked `cancel
	// Terms Of Service` button.
	//   "SMB_ENTERED_WEBSITE_IN_CONTACT_PARTNER_FORM" - Advertiser entered
	// website in contact form.
	//   "AGENCY_SELECTED_OPT_IN_AFA_MIGRATION" - Agency opted in for
	// migrating their exams to Academy for Ads.
	//   "AGENCY_SELECTED_OPT_OUT_AFA_MIGRATION" - Agency opted out for
	// migrating their exams to Academy for Ads.
	EventAction string `json:"eventAction,omitempty"`

	// EventCategory: The category the action belongs to.
	//
	// Possible values:
	//   "EVENT_CATEGORY_UNSPECIFIED" - Unchosen.
	//   "GOOGLE_PARTNER_SEARCH" - Google Partner Search category.
	//   "GOOGLE_PARTNER_SIGNUP_FLOW" - Google Partner sign-up flow
	// category.
	//   "GOOGLE_PARTNER_PORTAL" - Google Partner portal category.
	//   "GOOGLE_PARTNER_PORTAL_MY_PROFILE" - Google Partner portal
	// my-profile category.
	//   "GOOGLE_PARTNER_PORTAL_CERTIFICATIONS" - Google Partner portal
	// certifications category.
	//   "GOOGLE_PARTNER_PORTAL_COMMUNITY" - Google Partner portal community
	// category.
	//   "GOOGLE_PARTNER_PORTAL_INSIGHTS" - Google Partner portal insights
	// category.
	//   "GOOGLE_PARTNER_PORTAL_CLIENTS" - Google Partner portal clients
	// category.
	//   "GOOGLE_PARTNER_PUBLIC_USER_PROFILE" - Google Partner portal public
	// user profile category.
	//   "GOOGLE_PARTNER_PANEL" - Google Partner panel category.
	//   "GOOGLE_PARTNER_PORTAL_LAST_ADMIN_DIALOG" - Google Partner portal
	// last admin dialog category.
	//   "GOOGLE_PARTNER_CLIENT" - Google Partner client category.
	//   "GOOGLE_PARTNER_PORTAL_COMPANY_PROFILE" - Google Partner portal
	// company profile category.
	//   "EXTERNAL_LINKS" - External links category.
	//   "GOOGLE_PARTNER_LANDING" - Google Partner landing category.
	EventCategory string `json:"eventCategory,omitempty"`

	// EventDatas: List of event data for the event.
	EventDatas []*EventData `json:"eventDatas,omitempty"`

	// EventScope: The scope of the event.
	//
	// Possible values:
	//   "EVENT_SCOPE_UNSPECIFIED" - Unchosen.
	//   "VISITOR" - Based on visitor.
	//   "SESSION" - Based on session.
	//   "PAGE" - Based on page visit.
	EventScope string `json:"eventScope,omitempty"`

	// Lead: Advertiser lead information.
	Lead *Lead `json:"lead,omitempty"`

	// RequestMetadata: Current request metadata.
	RequestMetadata *RequestMetadata `json:"requestMetadata,omitempty"`

	// Url: The URL where the event occurred.
	Url string `json:"url,omitempty"`

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

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

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

// LogUserEventResponse: Response message for
// LogUserEvent.
type LogUserEventResponse struct {
	// ResponseMetadata: Current response metadata.
	ResponseMetadata *ResponseMetadata `json:"responseMetadata,omitempty"`

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

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

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

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

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

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

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

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

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

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

// OfferCustomer: Customers qualified for an offer.
type OfferCustomer struct {
	// AdwordsUrl: URL to the customer's AdWords page.
	AdwordsUrl string `json:"adwordsUrl,omitempty"`

	// CountryCode: Country code of the customer.
	CountryCode string `json:"countryCode,omitempty"`

	// CreationTime: Time the customer was created.
	CreationTime string `json:"creationTime,omitempty"`

	// EligibilityDaysLeft: Days the customer is still eligible.
	EligibilityDaysLeft int64 `json:"eligibilityDaysLeft,omitempty"`

	// ExternalCid: External CID for the customer.
	ExternalCid int64 `json:"externalCid,omitempty,string"`

	// GetYAmount: Formatted Get Y amount with currency code.
	GetYAmount string `json:"getYAmount,omitempty"`

	// Name: Name of the customer.
	Name string `json:"name,omitempty"`

	// OfferType: Type of the offer
	//
	// Possible values:
	//   "OFFER_TYPE_UNSPECIFIED" - Unset.
	//   "OFFER_TYPE_SPEND_X_GET_Y" - AdWords spend X get Y.
	//   "OFFER_TYPE_VIDEO" - Youtube video.
	//   "OFFER_TYPE_SPEND_MATCH" - Spend Match up to Y.
	OfferType string `json:"offerType,omitempty"`

	// SpendXAmount: Formatted Spend X amount with currency code.
	SpendXAmount string `json:"spendXAmount,omitempty"`

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

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

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

// OptIns: A set of opt-ins for a user.
type OptIns struct {
	// MarketComm: An opt-in about receiving email from Partners marketing
	// teams. Includes
	// member-only events and special promotional offers for Google
	// products.
	MarketComm bool `json:"marketComm,omitempty"`

	// PerformanceSuggestions: An opt-in about receiving email with
	// customized AdWords campaign management
	// tips.
	PerformanceSuggestions bool `json:"performanceSuggestions,omitempty"`

	// PhoneContact: An opt-in to allow recieivng phone calls about their
	// Partners account.
	PhoneContact bool `json:"phoneContact,omitempty"`

	// PhysicalMail: An opt-in to receive special promotional gifts and
	// material in the mail.
	PhysicalMail bool `json:"physicalMail,omitempty"`

	// SpecialOffers: An opt-in about receiving email regarding new features
	// and products.
	SpecialOffers bool `json:"specialOffers,omitempty"`

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

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

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

// PublicProfile: Basic information from a public profile.
type PublicProfile struct {
	// DisplayImageUrl: The URL to the main display image of the public
	// profile. Being deprecated.
	DisplayImageUrl string `json:"displayImageUrl,omitempty"`

	// DisplayName: The display name of the public profile.
	DisplayName string `json:"displayName,omitempty"`

	// Id: The ID which can be used to retrieve more details about the
	// public profile.
	Id string `json:"id,omitempty"`

	// ProfileImage: The URL to the main profile image of the public
	// profile.
	ProfileImage string `json:"profileImage,omitempty"`

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

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

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

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

// Rank: Information related to ranking of results.
type Rank struct {
	// Type: The type of rank.
	//
	// Possible values:
	//   "RANK_TYPE_UNSPECIFIED" - Unchosen.
	//   "RT_FINAL_SCORE" - Total final score.
	Type string `json:"type,omitempty"`

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

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

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

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

func (s *Rank) UnmarshalJSON(data []byte) error {
	type NoMethod Rank
	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
}

// RecaptchaChallenge: <a
// href="https://www.google.com/recaptcha/">reCaptcha</a> challenge
// info.
type RecaptchaChallenge struct {
	// Id: The ID of the reCaptcha challenge.
	Id string `json:"id,omitempty"`

	// Response: The response to the reCaptcha challenge.
	Response string `json:"response,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 *RecaptchaChallenge) MarshalJSON() ([]byte, error) {
	type NoMethod RecaptchaChallenge
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RequestMetadata: Common data that is in each API request.
type RequestMetadata struct {
	// ExperimentIds: Experiment IDs the current request belongs to.
	ExperimentIds []string `json:"experimentIds,omitempty"`

	// Locale: Locale to use for the current request.
	Locale string `json:"locale,omitempty"`

	// PartnersSessionId: Google Partners session ID.
	PartnersSessionId string `json:"partnersSessionId,omitempty"`

	// TrafficSource: Source of traffic for the current request.
	TrafficSource *TrafficSource `json:"trafficSource,omitempty"`

	// UserOverrides: Values to use instead of the user's respective
	// defaults for the current
	// request. These are only honored by whitelisted products.
	UserOverrides *UserOverrides `json:"userOverrides,omitempty"`

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

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

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

// ResponseMetadata: Common data that is in each API response.
type ResponseMetadata struct {
	// DebugInfo: Debug information about this request.
	DebugInfo *DebugInfo `json:"debugInfo,omitempty"`

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

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

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

// SpecializationStatus: Agency specialization status
type SpecializationStatus struct {
	// BadgeSpecialization: The specialization this status is for.
	//
	// Possible values:
	//   "BADGE_SPECIALIZATION_UNKNOWN" - Unknown specialization
	//   "BADGE_SPECIALIZATION_ADWORDS_SEARCH" - AdWords Search
	// specialization
	//   "BADGE_SPECIALIZATION_ADWORDS_DISPLAY" - AdWords Display
	// specialization
	//   "BADGE_SPECIALIZATION_ADWORDS_MOBILE" - AdWords Mobile
	// specialization
	//   "BADGE_SPECIALIZATION_ADWORDS_VIDEO" - AdWords Video specialization
	//   "BADGE_SPECIALIZATION_ADWORDS_SHOPPING" - AdWords Shopping
	// specialization
	BadgeSpecialization string `json:"badgeSpecialization,omitempty"`

	// BadgeSpecializationState: State of agency specialization.
	//
	// Possible values:
	//   "BADGE_SPECIALIZATION_STATE_UNKNOWN" - Unknown state
	//   "BADGE_SPECIALIZATION_STATE_PASSED" - Specialization passed
	//   "BADGE_SPECIALIZATION_STATE_NOT_PASSED" - Specialization not passed
	//   "BADGE_SPECIALIZATION_STATE_IN_GRACE" - Specialization in grace
	BadgeSpecializationState string `json:"badgeSpecializationState,omitempty"`

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

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

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

// TrafficSource: Source of traffic for the current request.
type TrafficSource struct {
	// TrafficSourceId: Identifier to indicate where the traffic comes
	// from.
	// An identifier has multiple letters created by a team which redirected
	// the
	// traffic to us.
	TrafficSourceId string `json:"trafficSourceId,omitempty"`

	// TrafficSubId: Second level identifier to indicate where the traffic
	// comes from.
	// An identifier has multiple letters created by a team which redirected
	// the
	// traffic to us.
	TrafficSubId string `json:"trafficSubId,omitempty"`

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

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

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

// User: A resource representing a user of the Partners platform.
type User struct {
	// AfaInfoShared: Whether or not the user has opted to share their
	// Academy for Ads info with
	// Google Partners.
	AfaInfoShared bool `json:"afaInfoShared,omitempty"`

	// AvailableAdwordsManagerAccounts: This is the list of AdWords Manager
	// Accounts the user has edit access to.
	// If the user has edit access to multiple accounts, the user can choose
	// the
	// preferred account and we use this when a personal account is needed.
	// Can
	// be empty meaning the user has access to no accounts.
	// @OutputOnly
	AvailableAdwordsManagerAccounts []*AdWordsManagerAccountInfo `json:"availableAdwordsManagerAccounts,omitempty"`

	// CertificationStatus: The list of achieved certifications. These are
	// calculated based on exam
	// results and other requirements.
	// @OutputOnly
	CertificationStatus []*Certification `json:"certificationStatus,omitempty"`

	// Company: The company that the user is associated with.
	// If not present, the user is not associated with any company.
	Company *CompanyRelation `json:"company,omitempty"`

	// CompanyVerificationEmail: The email address used by the user used for
	// company verification.
	// @OutputOnly
	CompanyVerificationEmail string `json:"companyVerificationEmail,omitempty"`

	// ExamStatus: The list of exams the user ever taken. For each type of
	// exam, only one
	// entry is listed.
	ExamStatus []*ExamStatus `json:"examStatus,omitempty"`

	// Id: The ID of the user.
	Id string `json:"id,omitempty"`

	// InternalId: The internal user ID.
	// Only available for a whitelisted set of api clients.
	InternalId string `json:"internalId,omitempty"`

	// LastAccessTime: The most recent time the user interacted with the
	// Partners site.
	// @OutputOnly
	LastAccessTime string `json:"lastAccessTime,omitempty"`

	// PrimaryEmails: The list of emails the user has access to/can select
	// as primary.
	// @OutputOnly
	PrimaryEmails []string `json:"primaryEmails,omitempty"`

	// Profile: The profile information of a Partners user, contains all the
	// directly
	// editable user information.
	Profile *UserProfile `json:"profile,omitempty"`

	// PublicProfile: Information about a user's external public profile
	// outside Google Partners.
	PublicProfile *PublicProfile `json:"publicProfile,omitempty"`

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

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

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

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

// UserOverrides: Values to use instead of the user's respective
// defaults. These are only
// honored by whitelisted products.
type UserOverrides struct {
	// IpAddress: IP address to use instead of the user's geo-located IP
	// address.
	IpAddress string `json:"ipAddress,omitempty"`

	// UserId: Logged-in user ID to impersonate instead of the user's ID.
	UserId string `json:"userId,omitempty"`

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

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

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

// UserProfile: The profile information of a Partners user.
type UserProfile struct {
	// Address: The user's mailing address, contains multiple fields.
	Address *Location `json:"address,omitempty"`

	// AdwordsManagerAccount: If the user has edit access to multiple
	// accounts, the user can choose the
	// preferred account and it is used when a personal account is needed.
	// Can
	// be empty.
	AdwordsManagerAccount int64 `json:"adwordsManagerAccount,omitempty,string"`

	// Channels: A list of ids representing which channels the user selected
	// they were in.
	Channels []string `json:"channels,omitempty"`

	// EmailAddress: The email address the user has selected on the Partners
	// site as primary.
	EmailAddress string `json:"emailAddress,omitempty"`

	// EmailOptIns: The list of opt-ins for the user, related to
	// communication preferences.
	EmailOptIns *OptIns `json:"emailOptIns,omitempty"`

	// FamilyName: The user's family name.
	FamilyName string `json:"familyName,omitempty"`

	// GivenName: The user's given name.
	GivenName string `json:"givenName,omitempty"`

	// Industries: A list of ids representing which industries the user
	// selected.
	Industries []string `json:"industries,omitempty"`

	// JobFunctions: A list of ids represnting which job categories the user
	// selected.
	JobFunctions []string `json:"jobFunctions,omitempty"`

	// Languages: The list of languages this user understands.
	Languages []string `json:"languages,omitempty"`

	// Markets: A list of ids representing which markets the user was
	// interested in.
	Markets []string `json:"markets,omitempty"`

	// MigrateToAfa: Whether or not to migrate the user's exam data to
	// Academy for Ads.
	MigrateToAfa bool `json:"migrateToAfa,omitempty"`

	// PhoneNumber: The user's phone number.
	PhoneNumber string `json:"phoneNumber,omitempty"`

	// PrimaryCountryCode: The user's primary country, an ISO 2-character
	// code.
	PrimaryCountryCode string `json:"primaryCountryCode,omitempty"`

	// ProfilePublic: Whether the user's public profile is visible to anyone
	// with the URL.
	ProfilePublic bool `json:"profilePublic,omitempty"`

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

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

// method id "partners.analytics.list":

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

// List: Lists analytics data for a user's associated company.
// Should only be called within the context of an authorized logged in
// user.
func (r *AnalyticsService) List() *AnalyticsListCall {
	c := &AnalyticsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Server may return fewer analytics than requested.
// If unspecified or set to 0, default value is 30.
// Specifies the number of days in the date range when querying
// analytics.
// The `page_token` represents the end date of the date range
// and the start date is calculated using the `page_size` as the
// number
// of days BEFORE the end date.
// Must be a non-negative integer.
func (c *AnalyticsListCall) PageSize(pageSize int64) *AnalyticsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results that the server returns.
// Typically, this is the value of
// `ListAnalyticsResponse.next_page_token`
// returned from the previous call to
// ListAnalytics.
// Will be a date string in `YYYY-MM-DD` format representing the end
// date
// of the date range of results to return.
// If unspecified or set to "", default value is the current date.
func (c *AnalyticsListCall) PageToken(pageToken string) *AnalyticsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *AnalyticsListCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *AnalyticsListCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *AnalyticsListCall) RequestMetadataLocale(requestMetadataLocale string) *AnalyticsListCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *AnalyticsListCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *AnalyticsListCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *AnalyticsListCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *AnalyticsListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *AnalyticsListCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *AnalyticsListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *AnalyticsListCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *AnalyticsListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *AnalyticsListCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *AnalyticsListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AnalyticsListCall) Fields(s ...googleapi.Field) *AnalyticsListCall {
	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 *AnalyticsListCall) IfNoneMatch(entityTag string) *AnalyticsListCall {
	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 *AnalyticsListCall) Context(ctx context.Context) *AnalyticsListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *AnalyticsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/analytics")
	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 "partners.analytics.list" call.
// Exactly one of *ListAnalyticsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListAnalyticsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AnalyticsListCall) Do(opts ...googleapi.CallOption) (*ListAnalyticsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListAnalyticsResponse{
		ServerResponse: googleapi.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 analytics data for a user's associated company.\nShould only be called within the context of an authorized logged in user.",
	//   "flatPath": "v2/analytics",
	//   "httpMethod": "GET",
	//   "id": "partners.analytics.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Requested page size. Server may return fewer analytics than requested.\nIf unspecified or set to 0, default value is 30.\nSpecifies the number of days in the date range when querying analytics.\nThe `page_token` represents the end date of the date range\nand the start date is calculated using the `page_size` as the number\nof days BEFORE the end date.\nMust be a non-negative integer.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results that the server returns.\nTypically, this is the value of `ListAnalyticsResponse.next_page_token`\nreturned from the previous call to\nListAnalytics.\nWill be a date string in `YYYY-MM-DD` format representing the end date\nof the date range of results to return.\nIf unspecified or set to \"\", default value is the current date.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/analytics",
	//   "response": {
	//     "$ref": "ListAnalyticsResponse"
	//   }
	// }

}

// 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 *AnalyticsListCall) Pages(ctx context.Context, f func(*ListAnalyticsResponse) 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 "partners.clientMessages.log":

type ClientMessagesLogCall struct {
	s                 *Service
	logmessagerequest *LogMessageRequest
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Log: Logs a generic message from the client, such as
// `Failed to render component`, `Profile page is running slow`,
// `More than 500 users have accessed this result.`, etc.
func (r *ClientMessagesService) Log(logmessagerequest *LogMessageRequest) *ClientMessagesLogCall {
	c := &ClientMessagesLogCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.logmessagerequest = logmessagerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ClientMessagesLogCall) Fields(s ...googleapi.Field) *ClientMessagesLogCall {
	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 *ClientMessagesLogCall) Context(ctx context.Context) *ClientMessagesLogCall {
	c.ctx_ = ctx
	return c
}

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

func (c *ClientMessagesLogCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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.logmessagerequest)
	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, "v2/clientMessages:log")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.clientMessages.log" call.
// Exactly one of *LogMessageResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LogMessageResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ClientMessagesLogCall) Do(opts ...googleapi.CallOption) (*LogMessageResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LogMessageResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Logs a generic message from the client, such as\n`Failed to render component`, `Profile page is running slow`,\n`More than 500 users have accessed this result.`, etc.",
	//   "flatPath": "v2/clientMessages:log",
	//   "httpMethod": "POST",
	//   "id": "partners.clientMessages.log",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v2/clientMessages:log",
	//   "request": {
	//     "$ref": "LogMessageRequest"
	//   },
	//   "response": {
	//     "$ref": "LogMessageResponse"
	//   }
	// }

}

// method id "partners.companies.get":

type CompaniesGetCall struct {
	s            *Service
	companyId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a company.
func (r *CompaniesService) Get(companyId string) *CompaniesGetCall {
	c := &CompaniesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.companyId = companyId
	return c
}

// Address sets the optional parameter "address": The address to use for
// sorting the company's addresses by proximity.
// If not given, the geo-located address of the request is used.
// Used when order_by is set.
func (c *CompaniesGetCall) Address(address string) *CompaniesGetCall {
	c.urlParams_.Set("address", address)
	return c
}

// CurrencyCode sets the optional parameter "currencyCode": If the
// company's budget is in a different currency code than this one,
// then
// the converted budget is converted to this currency code.
func (c *CompaniesGetCall) CurrencyCode(currencyCode string) *CompaniesGetCall {
	c.urlParams_.Set("currencyCode", currencyCode)
	return c
}

// OrderBy sets the optional parameter "orderBy": How to order addresses
// within the returned company. Currently, only
// `address` and `address desc` is supported which will sorted by
// closest to
// farthest in distance from given address and farthest to closest
// distance
// from given address respectively.
func (c *CompaniesGetCall) OrderBy(orderBy string) *CompaniesGetCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *CompaniesGetCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *CompaniesGetCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *CompaniesGetCall) RequestMetadataLocale(requestMetadataLocale string) *CompaniesGetCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *CompaniesGetCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *CompaniesGetCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *CompaniesGetCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *CompaniesGetCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *CompaniesGetCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *CompaniesGetCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *CompaniesGetCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *CompaniesGetCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *CompaniesGetCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *CompaniesGetCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// View sets the optional parameter "view": The view of `Company`
// resource to be returned. This must not be
// `COMPANY_VIEW_UNSPECIFIED`.
//
// Possible values:
//   "COMPANY_VIEW_UNSPECIFIED"
//   "CV_GOOGLE_PARTNER_SEARCH"
func (c *CompaniesGetCall) View(view string) *CompaniesGetCall {
	c.urlParams_.Set("view", view)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CompaniesGetCall) Fields(s ...googleapi.Field) *CompaniesGetCall {
	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 *CompaniesGetCall) IfNoneMatch(entityTag string) *CompaniesGetCall {
	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 *CompaniesGetCall) Context(ctx context.Context) *CompaniesGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *CompaniesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/companies/{companyId}")
	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{
		"companyId": c.companyId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.companies.get" call.
// Exactly one of *GetCompanyResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GetCompanyResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CompaniesGetCall) Do(opts ...googleapi.CallOption) (*GetCompanyResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetCompanyResponse{
		ServerResponse: googleapi.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 company.",
	//   "flatPath": "v2/companies/{companyId}",
	//   "httpMethod": "GET",
	//   "id": "partners.companies.get",
	//   "parameterOrder": [
	//     "companyId"
	//   ],
	//   "parameters": {
	//     "address": {
	//       "description": "The address to use for sorting the company's addresses by proximity.\nIf not given, the geo-located address of the request is used.\nUsed when order_by is set.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "companyId": {
	//       "description": "The ID of the company to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "currencyCode": {
	//       "description": "If the company's budget is in a different currency code than this one, then\nthe converted budget is converted to this currency code.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "How to order addresses within the returned company. Currently, only\n`address` and `address desc` is supported which will sorted by closest to\nfarthest in distance from given address and farthest to closest distance\nfrom given address respectively.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "The view of `Company` resource to be returned. This must not be\n`COMPANY_VIEW_UNSPECIFIED`.",
	//       "enum": [
	//         "COMPANY_VIEW_UNSPECIFIED",
	//         "CV_GOOGLE_PARTNER_SEARCH"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/companies/{companyId}",
	//   "response": {
	//     "$ref": "GetCompanyResponse"
	//   }
	// }

}

// method id "partners.companies.list":

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

// List: Lists companies.
func (r *CompaniesService) List() *CompaniesListCall {
	c := &CompaniesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Address sets the optional parameter "address": The address to use
// when searching for companies.
// If not given, the geo-located address of the request is used.
func (c *CompaniesListCall) Address(address string) *CompaniesListCall {
	c.urlParams_.Set("address", address)
	return c
}

// CompanyName sets the optional parameter "companyName": Company name
// to search for.
func (c *CompaniesListCall) CompanyName(companyName string) *CompaniesListCall {
	c.urlParams_.Set("companyName", companyName)
	return c
}

// GpsMotivations sets the optional parameter "gpsMotivations": List of
// reasons for using Google Partner Search to get companies.
//
// Possible values:
//   "GPS_MOTIVATION_UNSPECIFIED"
//   "GPSM_HELP_WITH_ADVERTISING"
//   "GPSM_HELP_WITH_WEBSITE"
//   "GPSM_NO_WEBSITE"
func (c *CompaniesListCall) GpsMotivations(gpsMotivations ...string) *CompaniesListCall {
	c.urlParams_.SetMulti("gpsMotivations", append([]string{}, gpsMotivations...))
	return c
}

// Industries sets the optional parameter "industries": List of
// industries the company can help with.
//
// Possible values:
//   "INDUSTRY_UNSPECIFIED"
//   "I_AUTOMOTIVE"
//   "I_BUSINESS_TO_BUSINESS"
//   "I_CONSUMER_PACKAGED_GOODS"
//   "I_EDUCATION"
//   "I_FINANCE"
//   "I_HEALTHCARE"
//   "I_MEDIA_AND_ENTERTAINMENT"
//   "I_RETAIL"
//   "I_TECHNOLOGY"
//   "I_TRAVEL"
func (c *CompaniesListCall) Industries(industries ...string) *CompaniesListCall {
	c.urlParams_.SetMulti("industries", append([]string{}, industries...))
	return c
}

// LanguageCodes sets the optional parameter "languageCodes": List of
// language codes that company can support. Only primary
// language
// subtags are accepted as defined by
// <a href="https://tools.ietf.org/html/bcp47">BCP 47</a>
// (IETF BCP 47, "Tags for Identifying Languages").
func (c *CompaniesListCall) LanguageCodes(languageCodes ...string) *CompaniesListCall {
	c.urlParams_.SetMulti("languageCodes", append([]string{}, languageCodes...))
	return c
}

// MaxMonthlyBudgetCurrencyCode sets the optional parameter
// "maxMonthlyBudget.currencyCode": The 3-letter currency code defined
// in ISO 4217.
func (c *CompaniesListCall) MaxMonthlyBudgetCurrencyCode(maxMonthlyBudgetCurrencyCode string) *CompaniesListCall {
	c.urlParams_.Set("maxMonthlyBudget.currencyCode", maxMonthlyBudgetCurrencyCode)
	return c
}

// MaxMonthlyBudgetNanos sets the optional parameter
// "maxMonthlyBudget.nanos": Number of nano (10^-9) units of the
// amount.
// The value must be between -999,999,999 and +999,999,999 inclusive.
// If `units` is positive, `nanos` must be positive or zero.
// If `units` is zero, `nanos` can be positive, zero, or negative.
// If `units` is negative, `nanos` must be negative or zero.
// For example $-1.75 is represented as `units`=-1 and
// `nanos`=-750,000,000.
func (c *CompaniesListCall) MaxMonthlyBudgetNanos(maxMonthlyBudgetNanos int64) *CompaniesListCall {
	c.urlParams_.Set("maxMonthlyBudget.nanos", fmt.Sprint(maxMonthlyBudgetNanos))
	return c
}

// MaxMonthlyBudgetUnits sets the optional parameter
// "maxMonthlyBudget.units": The whole units of the amount.
// For example if `currencyCode` is "USD", then 1 unit is one US
// dollar.
func (c *CompaniesListCall) MaxMonthlyBudgetUnits(maxMonthlyBudgetUnits int64) *CompaniesListCall {
	c.urlParams_.Set("maxMonthlyBudget.units", fmt.Sprint(maxMonthlyBudgetUnits))
	return c
}

// MinMonthlyBudgetCurrencyCode sets the optional parameter
// "minMonthlyBudget.currencyCode": The 3-letter currency code defined
// in ISO 4217.
func (c *CompaniesListCall) MinMonthlyBudgetCurrencyCode(minMonthlyBudgetCurrencyCode string) *CompaniesListCall {
	c.urlParams_.Set("minMonthlyBudget.currencyCode", minMonthlyBudgetCurrencyCode)
	return c
}

// MinMonthlyBudgetNanos sets the optional parameter
// "minMonthlyBudget.nanos": Number of nano (10^-9) units of the
// amount.
// The value must be between -999,999,999 and +999,999,999 inclusive.
// If `units` is positive, `nanos` must be positive or zero.
// If `units` is zero, `nanos` can be positive, zero, or negative.
// If `units` is negative, `nanos` must be negative or zero.
// For example $-1.75 is represented as `units`=-1 and
// `nanos`=-750,000,000.
func (c *CompaniesListCall) MinMonthlyBudgetNanos(minMonthlyBudgetNanos int64) *CompaniesListCall {
	c.urlParams_.Set("minMonthlyBudget.nanos", fmt.Sprint(minMonthlyBudgetNanos))
	return c
}

// MinMonthlyBudgetUnits sets the optional parameter
// "minMonthlyBudget.units": The whole units of the amount.
// For example if `currencyCode` is "USD", then 1 unit is one US
// dollar.
func (c *CompaniesListCall) MinMonthlyBudgetUnits(minMonthlyBudgetUnits int64) *CompaniesListCall {
	c.urlParams_.Set("minMonthlyBudget.units", fmt.Sprint(minMonthlyBudgetUnits))
	return c
}

// OrderBy sets the optional parameter "orderBy": How to order addresses
// within the returned companies. Currently, only
// `address` and `address desc` is supported which will sorted by
// closest to
// farthest in distance from given address and farthest to closest
// distance
// from given address respectively.
func (c *CompaniesListCall) OrderBy(orderBy string) *CompaniesListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Server may return fewer companies than requested.
// If unspecified, server picks an appropriate default.
func (c *CompaniesListCall) PageSize(pageSize int64) *CompaniesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results that the server returns.
// Typically, this is the value of
// `ListCompaniesResponse.next_page_token`
// returned from the previous call to
// ListCompanies.
func (c *CompaniesListCall) PageToken(pageToken string) *CompaniesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *CompaniesListCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *CompaniesListCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *CompaniesListCall) RequestMetadataLocale(requestMetadataLocale string) *CompaniesListCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *CompaniesListCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *CompaniesListCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *CompaniesListCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *CompaniesListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *CompaniesListCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *CompaniesListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *CompaniesListCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *CompaniesListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *CompaniesListCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *CompaniesListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Services sets the optional parameter "services": List of services
// that the returned agencies should provide. If this is
// not empty, any returned agency must have at least one of these
// services,
// or one of the specializations in the "specializations" field.
//
// Possible values:
//   "SERVICE_UNSPECIFIED"
//   "S_ADVANCED_ADWORDS_SUPPORT"
//   "S_ADVERTISING_ON_GOOGLE"
//   "S_AN_ENHANCED_WEBSITE"
//   "S_AN_ONLINE_MARKETING_PLAN"
//   "S_MOBILE_AND_VIDEO_ADS"
//   "S_MOBILE_WEBSITE_SERVICES"
func (c *CompaniesListCall) Services(services ...string) *CompaniesListCall {
	c.urlParams_.SetMulti("services", append([]string{}, services...))
	return c
}

// Specializations sets the optional parameter "specializations": List
// of specializations that the returned agencies should provide. If
// this
// is not empty, any returned agency must have at least one of
// these
// specializations, or one of the services in the "services" field.
//
// Possible values:
//   "BADGE_SPECIALIZATION_UNKNOWN"
//   "BADGE_SPECIALIZATION_ADWORDS_SEARCH"
//   "BADGE_SPECIALIZATION_ADWORDS_DISPLAY"
//   "BADGE_SPECIALIZATION_ADWORDS_MOBILE"
//   "BADGE_SPECIALIZATION_ADWORDS_VIDEO"
//   "BADGE_SPECIALIZATION_ADWORDS_SHOPPING"
func (c *CompaniesListCall) Specializations(specializations ...string) *CompaniesListCall {
	c.urlParams_.SetMulti("specializations", append([]string{}, specializations...))
	return c
}

// View sets the optional parameter "view": The view of the `Company`
// resource to be returned. This must not be
// `COMPANY_VIEW_UNSPECIFIED`.
//
// Possible values:
//   "COMPANY_VIEW_UNSPECIFIED"
//   "CV_GOOGLE_PARTNER_SEARCH"
func (c *CompaniesListCall) View(view string) *CompaniesListCall {
	c.urlParams_.Set("view", view)
	return c
}

// WebsiteUrl sets the optional parameter "websiteUrl": Website URL that
// will help to find a better matched company.
// .
func (c *CompaniesListCall) WebsiteUrl(websiteUrl string) *CompaniesListCall {
	c.urlParams_.Set("websiteUrl", websiteUrl)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CompaniesListCall) Fields(s ...googleapi.Field) *CompaniesListCall {
	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 *CompaniesListCall) IfNoneMatch(entityTag string) *CompaniesListCall {
	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 *CompaniesListCall) Context(ctx context.Context) *CompaniesListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *CompaniesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/companies")
	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 "partners.companies.list" call.
// Exactly one of *ListCompaniesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListCompaniesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CompaniesListCall) Do(opts ...googleapi.CallOption) (*ListCompaniesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListCompaniesResponse{
		ServerResponse: googleapi.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 companies.",
	//   "flatPath": "v2/companies",
	//   "httpMethod": "GET",
	//   "id": "partners.companies.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "address": {
	//       "description": "The address to use when searching for companies.\nIf not given, the geo-located address of the request is used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "companyName": {
	//       "description": "Company name to search for.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "gpsMotivations": {
	//       "description": "List of reasons for using Google Partner Search to get companies.",
	//       "enum": [
	//         "GPS_MOTIVATION_UNSPECIFIED",
	//         "GPSM_HELP_WITH_ADVERTISING",
	//         "GPSM_HELP_WITH_WEBSITE",
	//         "GPSM_NO_WEBSITE"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "industries": {
	//       "description": "List of industries the company can help with.",
	//       "enum": [
	//         "INDUSTRY_UNSPECIFIED",
	//         "I_AUTOMOTIVE",
	//         "I_BUSINESS_TO_BUSINESS",
	//         "I_CONSUMER_PACKAGED_GOODS",
	//         "I_EDUCATION",
	//         "I_FINANCE",
	//         "I_HEALTHCARE",
	//         "I_MEDIA_AND_ENTERTAINMENT",
	//         "I_RETAIL",
	//         "I_TECHNOLOGY",
	//         "I_TRAVEL"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "languageCodes": {
	//       "description": "List of language codes that company can support. Only primary language\nsubtags are accepted as defined by\n\u003ca href=\"https://tools.ietf.org/html/bcp47\"\u003eBCP 47\u003c/a\u003e\n(IETF BCP 47, \"Tags for Identifying Languages\").",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxMonthlyBudget.currencyCode": {
	//       "description": "The 3-letter currency code defined in ISO 4217.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxMonthlyBudget.nanos": {
	//       "description": "Number of nano (10^-9) units of the amount.\nThe value must be between -999,999,999 and +999,999,999 inclusive.\nIf `units` is positive, `nanos` must be positive or zero.\nIf `units` is zero, `nanos` can be positive, zero, or negative.\nIf `units` is negative, `nanos` must be negative or zero.\nFor example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "maxMonthlyBudget.units": {
	//       "description": "The whole units of the amount.\nFor example if `currencyCode` is `\"USD\"`, then 1 unit is one US dollar.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minMonthlyBudget.currencyCode": {
	//       "description": "The 3-letter currency code defined in ISO 4217.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minMonthlyBudget.nanos": {
	//       "description": "Number of nano (10^-9) units of the amount.\nThe value must be between -999,999,999 and +999,999,999 inclusive.\nIf `units` is positive, `nanos` must be positive or zero.\nIf `units` is zero, `nanos` can be positive, zero, or negative.\nIf `units` is negative, `nanos` must be negative or zero.\nFor example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "minMonthlyBudget.units": {
	//       "description": "The whole units of the amount.\nFor example if `currencyCode` is `\"USD\"`, then 1 unit is one US dollar.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "orderBy": {
	//       "description": "How to order addresses within the returned companies. Currently, only\n`address` and `address desc` is supported which will sorted by closest to\nfarthest in distance from given address and farthest to closest distance\nfrom given address respectively.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Server may return fewer companies than requested.\nIf unspecified, server picks an appropriate default.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results that the server returns.\nTypically, this is the value of `ListCompaniesResponse.next_page_token`\nreturned from the previous call to\nListCompanies.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "services": {
	//       "description": "List of services that the returned agencies should provide. If this is\nnot empty, any returned agency must have at least one of these services,\nor one of the specializations in the \"specializations\" field.",
	//       "enum": [
	//         "SERVICE_UNSPECIFIED",
	//         "S_ADVANCED_ADWORDS_SUPPORT",
	//         "S_ADVERTISING_ON_GOOGLE",
	//         "S_AN_ENHANCED_WEBSITE",
	//         "S_AN_ONLINE_MARKETING_PLAN",
	//         "S_MOBILE_AND_VIDEO_ADS",
	//         "S_MOBILE_WEBSITE_SERVICES"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "specializations": {
	//       "description": "List of specializations that the returned agencies should provide. If this\nis not empty, any returned agency must have at least one of these\nspecializations, or one of the services in the \"services\" field.",
	//       "enum": [
	//         "BADGE_SPECIALIZATION_UNKNOWN",
	//         "BADGE_SPECIALIZATION_ADWORDS_SEARCH",
	//         "BADGE_SPECIALIZATION_ADWORDS_DISPLAY",
	//         "BADGE_SPECIALIZATION_ADWORDS_MOBILE",
	//         "BADGE_SPECIALIZATION_ADWORDS_VIDEO",
	//         "BADGE_SPECIALIZATION_ADWORDS_SHOPPING"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "view": {
	//       "description": "The view of the `Company` resource to be returned. This must not be\n`COMPANY_VIEW_UNSPECIFIED`.",
	//       "enum": [
	//         "COMPANY_VIEW_UNSPECIFIED",
	//         "CV_GOOGLE_PARTNER_SEARCH"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "websiteUrl": {
	//       "description": "Website URL that will help to find a better matched company.\n.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/companies",
	//   "response": {
	//     "$ref": "ListCompaniesResponse"
	//   }
	// }

}

// 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 *CompaniesListCall) Pages(ctx context.Context, f func(*ListCompaniesResponse) 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 "partners.companies.leads.create":

type CompaniesLeadsCreateCall struct {
	s                 *Service
	companyId         string
	createleadrequest *CreateLeadRequest
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Creates an advertiser lead for the given company ID.
func (r *CompaniesLeadsService) Create(companyId string, createleadrequest *CreateLeadRequest) *CompaniesLeadsCreateCall {
	c := &CompaniesLeadsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.companyId = companyId
	c.createleadrequest = createleadrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CompaniesLeadsCreateCall) Fields(s ...googleapi.Field) *CompaniesLeadsCreateCall {
	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 *CompaniesLeadsCreateCall) Context(ctx context.Context) *CompaniesLeadsCreateCall {
	c.ctx_ = ctx
	return c
}

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

func (c *CompaniesLeadsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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.createleadrequest)
	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, "v2/companies/{companyId}/leads")
	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{
		"companyId": c.companyId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.companies.leads.create" call.
// Exactly one of *CreateLeadResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreateLeadResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CompaniesLeadsCreateCall) Do(opts ...googleapi.CallOption) (*CreateLeadResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreateLeadResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an advertiser lead for the given company ID.",
	//   "flatPath": "v2/companies/{companyId}/leads",
	//   "httpMethod": "POST",
	//   "id": "partners.companies.leads.create",
	//   "parameterOrder": [
	//     "companyId"
	//   ],
	//   "parameters": {
	//     "companyId": {
	//       "description": "The ID of the company to contact.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/companies/{companyId}/leads",
	//   "request": {
	//     "$ref": "CreateLeadRequest"
	//   },
	//   "response": {
	//     "$ref": "CreateLeadResponse"
	//   }
	// }

}

// method id "partners.leads.list":

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

// List: Lists advertiser leads for a user's associated company.
// Should only be called within the context of an authorized logged in
// user.
func (r *LeadsService) List() *LeadsListCall {
	c := &LeadsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// OrderBy sets the optional parameter "orderBy": How to order Leads.
// Currently, only `create_time`
// and `create_time desc` are supported
func (c *LeadsListCall) OrderBy(orderBy string) *LeadsListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Server may return fewer leads than requested.
// If unspecified, server picks an appropriate default.
func (c *LeadsListCall) PageSize(pageSize int64) *LeadsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A token
// identifying a page of results that the server returns.
// Typically, this is the value of
// `ListLeadsResponse.next_page_token`
// returned from the previous call to
// ListLeads.
func (c *LeadsListCall) PageToken(pageToken string) *LeadsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *LeadsListCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *LeadsListCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *LeadsListCall) RequestMetadataLocale(requestMetadataLocale string) *LeadsListCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *LeadsListCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *LeadsListCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *LeadsListCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *LeadsListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *LeadsListCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *LeadsListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *LeadsListCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *LeadsListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *LeadsListCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *LeadsListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LeadsListCall) Fields(s ...googleapi.Field) *LeadsListCall {
	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 *LeadsListCall) IfNoneMatch(entityTag string) *LeadsListCall {
	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 *LeadsListCall) Context(ctx context.Context) *LeadsListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *LeadsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/leads")
	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 "partners.leads.list" call.
// Exactly one of *ListLeadsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListLeadsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LeadsListCall) Do(opts ...googleapi.CallOption) (*ListLeadsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListLeadsResponse{
		ServerResponse: googleapi.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 advertiser leads for a user's associated company.\nShould only be called within the context of an authorized logged in user.",
	//   "flatPath": "v2/leads",
	//   "httpMethod": "GET",
	//   "id": "partners.leads.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "orderBy": {
	//       "description": "How to order Leads. Currently, only `create_time`\nand `create_time desc` are supported",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Server may return fewer leads than requested.\nIf unspecified, server picks an appropriate default.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "A token identifying a page of results that the server returns.\nTypically, this is the value of `ListLeadsResponse.next_page_token`\nreturned from the previous call to\nListLeads.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/leads",
	//   "response": {
	//     "$ref": "ListLeadsResponse"
	//   }
	// }

}

// 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 *LeadsListCall) Pages(ctx context.Context, f func(*ListLeadsResponse) 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 "partners.offers.list":

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

// List: Lists the Offers available for the current user
func (r *OffersService) List() *OffersListCall {
	c := &OffersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *OffersListCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *OffersListCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *OffersListCall) RequestMetadataLocale(requestMetadataLocale string) *OffersListCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *OffersListCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *OffersListCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *OffersListCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *OffersListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *OffersListCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *OffersListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *OffersListCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *OffersListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *OffersListCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *OffersListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OffersListCall) Fields(s ...googleapi.Field) *OffersListCall {
	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 *OffersListCall) IfNoneMatch(entityTag string) *OffersListCall {
	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 *OffersListCall) Context(ctx context.Context) *OffersListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *OffersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/offers")
	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 "partners.offers.list" call.
// Exactly one of *ListOffersResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOffersResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OffersListCall) Do(opts ...googleapi.CallOption) (*ListOffersResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListOffersResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists the Offers available for the current user",
	//   "flatPath": "v2/offers",
	//   "httpMethod": "GET",
	//   "id": "partners.offers.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/offers",
	//   "response": {
	//     "$ref": "ListOffersResponse"
	//   }
	// }

}

// method id "partners.offers.history.list":

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

// List: Lists the Historical Offers for the current user (or user's
// entire company)
func (r *OffersHistoryService) List() *OffersHistoryListCall {
	c := &OffersHistoryListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// EntireCompany sets the optional parameter "entireCompany": if true,
// show history for the entire company.  Requires user to be admin.
func (c *OffersHistoryListCall) EntireCompany(entireCompany bool) *OffersHistoryListCall {
	c.urlParams_.Set("entireCompany", fmt.Sprint(entireCompany))
	return c
}

// OrderBy sets the optional parameter "orderBy": Comma-separated list
// of fields to order by, e.g.: "foo,bar,baz".
// Use "foo desc" to sort descending.
// List of valid field names is: name, offer_code, expiration_time,
// status,
//     last_modified_time, sender_name, creation_time, country_code,
//     offer_type.
func (c *OffersHistoryListCall) OrderBy(orderBy string) *OffersHistoryListCall {
	c.urlParams_.Set("orderBy", orderBy)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// rows to return per page.
func (c *OffersHistoryListCall) PageSize(pageSize int64) *OffersHistoryListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to retrieve
// a specific page.
func (c *OffersHistoryListCall) PageToken(pageToken string) *OffersHistoryListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *OffersHistoryListCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *OffersHistoryListCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *OffersHistoryListCall) RequestMetadataLocale(requestMetadataLocale string) *OffersHistoryListCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *OffersHistoryListCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *OffersHistoryListCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *OffersHistoryListCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *OffersHistoryListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *OffersHistoryListCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *OffersHistoryListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *OffersHistoryListCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *OffersHistoryListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *OffersHistoryListCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *OffersHistoryListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OffersHistoryListCall) Fields(s ...googleapi.Field) *OffersHistoryListCall {
	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 *OffersHistoryListCall) IfNoneMatch(entityTag string) *OffersHistoryListCall {
	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 *OffersHistoryListCall) Context(ctx context.Context) *OffersHistoryListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *OffersHistoryListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/offers/history")
	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 "partners.offers.history.list" call.
// Exactly one of *ListOffersHistoryResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListOffersHistoryResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OffersHistoryListCall) Do(opts ...googleapi.CallOption) (*ListOffersHistoryResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListOffersHistoryResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists the Historical Offers for the current user (or user's entire company)",
	//   "flatPath": "v2/offers/history",
	//   "httpMethod": "GET",
	//   "id": "partners.offers.history.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "entireCompany": {
	//       "description": "if true, show history for the entire company.  Requires user to be admin.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "orderBy": {
	//       "description": "Comma-separated list of fields to order by, e.g.: \"foo,bar,baz\".\nUse \"foo desc\" to sort descending.\nList of valid field names is: name, offer_code, expiration_time, status,\n    last_modified_time, sender_name, creation_time, country_code,\n    offer_type.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of rows to return per page.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Token to retrieve a specific page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/offers/history",
	//   "response": {
	//     "$ref": "ListOffersHistoryResponse"
	//   }
	// }

}

// 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 *OffersHistoryListCall) Pages(ctx context.Context, f func(*ListOffersHistoryResponse) 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 "partners.userEvents.log":

type UserEventsLogCall struct {
	s                   *Service
	logusereventrequest *LogUserEventRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// Log: Logs a user event.
func (r *UserEventsService) Log(logusereventrequest *LogUserEventRequest) *UserEventsLogCall {
	c := &UserEventsLogCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.logusereventrequest = logusereventrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserEventsLogCall) Fields(s ...googleapi.Field) *UserEventsLogCall {
	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 *UserEventsLogCall) Context(ctx context.Context) *UserEventsLogCall {
	c.ctx_ = ctx
	return c
}

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

func (c *UserEventsLogCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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.logusereventrequest)
	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, "v2/userEvents:log")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.userEvents.log" call.
// Exactly one of *LogUserEventResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LogUserEventResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserEventsLogCall) Do(opts ...googleapi.CallOption) (*LogUserEventResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LogUserEventResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Logs a user event.",
	//   "flatPath": "v2/userEvents:log",
	//   "httpMethod": "POST",
	//   "id": "partners.userEvents.log",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v2/userEvents:log",
	//   "request": {
	//     "$ref": "LogUserEventRequest"
	//   },
	//   "response": {
	//     "$ref": "LogUserEventResponse"
	//   }
	// }

}

// method id "partners.userStates.list":

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

// List: Lists states for current user.
func (r *UserStatesService) List() *UserStatesListCall {
	c := &UserStatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *UserStatesListCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *UserStatesListCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *UserStatesListCall) RequestMetadataLocale(requestMetadataLocale string) *UserStatesListCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *UserStatesListCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *UserStatesListCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UserStatesListCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *UserStatesListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UserStatesListCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *UserStatesListCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *UserStatesListCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *UserStatesListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *UserStatesListCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *UserStatesListCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserStatesListCall) Fields(s ...googleapi.Field) *UserStatesListCall {
	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 *UserStatesListCall) IfNoneMatch(entityTag string) *UserStatesListCall {
	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 *UserStatesListCall) Context(ctx context.Context) *UserStatesListCall {
	c.ctx_ = ctx
	return c
}

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

func (c *UserStatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/userStates")
	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 "partners.userStates.list" call.
// Exactly one of *ListUserStatesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListUserStatesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserStatesListCall) Do(opts ...googleapi.CallOption) (*ListUserStatesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListUserStatesResponse{
		ServerResponse: googleapi.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 states for current user.",
	//   "flatPath": "v2/userStates",
	//   "httpMethod": "GET",
	//   "id": "partners.userStates.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/userStates",
	//   "response": {
	//     "$ref": "ListUserStatesResponse"
	//   }
	// }

}

// method id "partners.users.createCompanyRelation":

type UsersCreateCompanyRelationCall struct {
	s               *Service
	userId          string
	companyrelation *CompanyRelation
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// CreateCompanyRelation: Creates a user's company relation. Affiliates
// the user to a company.
func (r *UsersService) CreateCompanyRelation(userId string, companyrelation *CompanyRelation) *UsersCreateCompanyRelationCall {
	c := &UsersCreateCompanyRelationCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.userId = userId
	c.companyrelation = companyrelation
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *UsersCreateCompanyRelationCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *UsersCreateCompanyRelationCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *UsersCreateCompanyRelationCall) RequestMetadataLocale(requestMetadataLocale string) *UsersCreateCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *UsersCreateCompanyRelationCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *UsersCreateCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UsersCreateCompanyRelationCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *UsersCreateCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UsersCreateCompanyRelationCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *UsersCreateCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *UsersCreateCompanyRelationCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *UsersCreateCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *UsersCreateCompanyRelationCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *UsersCreateCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UsersCreateCompanyRelationCall) Fields(s ...googleapi.Field) *UsersCreateCompanyRelationCall {
	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 *UsersCreateCompanyRelationCall) Context(ctx context.Context) *UsersCreateCompanyRelationCall {
	c.ctx_ = ctx
	return c
}

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

func (c *UsersCreateCompanyRelationCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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.companyrelation)
	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, "v2/users/{userId}/companyRelation")
	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{
		"userId": c.userId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.users.createCompanyRelation" call.
// Exactly one of *CompanyRelation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CompanyRelation.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UsersCreateCompanyRelationCall) Do(opts ...googleapi.CallOption) (*CompanyRelation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CompanyRelation{
		ServerResponse: googleapi.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 user's company relation. Affiliates the user to a company.",
	//   "flatPath": "v2/users/{userId}/companyRelation",
	//   "httpMethod": "PUT",
	//   "id": "partners.users.createCompanyRelation",
	//   "parameterOrder": [
	//     "userId"
	//   ],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userId": {
	//       "description": "The ID of the user. Can be set to \u003ccode\u003eme\u003c/code\u003e to mean\nthe currently authenticated user.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/users/{userId}/companyRelation",
	//   "request": {
	//     "$ref": "CompanyRelation"
	//   },
	//   "response": {
	//     "$ref": "CompanyRelation"
	//   }
	// }

}

// method id "partners.users.deleteCompanyRelation":

type UsersDeleteCompanyRelationCall struct {
	s          *Service
	userId     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DeleteCompanyRelation: Deletes a user's company relation.
// Unaffiliaites the user from a company.
func (r *UsersService) DeleteCompanyRelation(userId string) *UsersDeleteCompanyRelationCall {
	c := &UsersDeleteCompanyRelationCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.userId = userId
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *UsersDeleteCompanyRelationCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *UsersDeleteCompanyRelationCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *UsersDeleteCompanyRelationCall) RequestMetadataLocale(requestMetadataLocale string) *UsersDeleteCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *UsersDeleteCompanyRelationCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *UsersDeleteCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UsersDeleteCompanyRelationCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *UsersDeleteCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UsersDeleteCompanyRelationCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *UsersDeleteCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *UsersDeleteCompanyRelationCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *UsersDeleteCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *UsersDeleteCompanyRelationCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *UsersDeleteCompanyRelationCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UsersDeleteCompanyRelationCall) Fields(s ...googleapi.Field) *UsersDeleteCompanyRelationCall {
	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 *UsersDeleteCompanyRelationCall) Context(ctx context.Context) *UsersDeleteCompanyRelationCall {
	c.ctx_ = ctx
	return c
}

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

func (c *UsersDeleteCompanyRelationCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/users/{userId}/companyRelation")
	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{
		"userId": c.userId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.users.deleteCompanyRelation" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *UsersDeleteCompanyRelationCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a user's company relation. Unaffiliaites the user from a company.",
	//   "flatPath": "v2/users/{userId}/companyRelation",
	//   "httpMethod": "DELETE",
	//   "id": "partners.users.deleteCompanyRelation",
	//   "parameterOrder": [
	//     "userId"
	//   ],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userId": {
	//       "description": "The ID of the user. Can be set to \u003ccode\u003eme\u003c/code\u003e to mean\nthe currently authenticated user.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/users/{userId}/companyRelation",
	//   "response": {
	//     "$ref": "Empty"
	//   }
	// }

}

// method id "partners.users.get":

type UsersGetCall struct {
	s            *Service
	userId       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets a user.
func (r *UsersService) Get(userId string) *UsersGetCall {
	c := &UsersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.userId = userId
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *UsersGetCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *UsersGetCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *UsersGetCall) RequestMetadataLocale(requestMetadataLocale string) *UsersGetCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *UsersGetCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *UsersGetCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UsersGetCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *UsersGetCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UsersGetCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *UsersGetCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *UsersGetCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *UsersGetCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *UsersGetCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *UsersGetCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// UserView sets the optional parameter "userView": Specifies what parts
// of the user information to return.
//
// Possible values:
//   "BASIC"
//   "PROFILE"
//   "PUBLIC_PROFILE"
func (c *UsersGetCall) UserView(userView string) *UsersGetCall {
	c.urlParams_.Set("userView", userView)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UsersGetCall) Fields(s ...googleapi.Field) *UsersGetCall {
	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 *UsersGetCall) IfNoneMatch(entityTag string) *UsersGetCall {
	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 *UsersGetCall) Context(ctx context.Context) *UsersGetCall {
	c.ctx_ = ctx
	return c
}

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

func (c *UsersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/users/{userId}")
	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{
		"userId": c.userId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.users.get" call.
// Exactly one of *User or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *User.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *UsersGetCall) Do(opts ...googleapi.CallOption) (*User, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &User{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a user.",
	//   "flatPath": "v2/users/{userId}",
	//   "httpMethod": "GET",
	//   "id": "partners.users.get",
	//   "parameterOrder": [
	//     "userId"
	//   ],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userId": {
	//       "description": "Identifier of the user. Can be set to \u003ccode\u003eme\u003c/code\u003e to mean the currently\nauthenticated user.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "userView": {
	//       "description": "Specifies what parts of the user information to return.",
	//       "enum": [
	//         "BASIC",
	//         "PROFILE",
	//         "PUBLIC_PROFILE"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/users/{userId}",
	//   "response": {
	//     "$ref": "User"
	//   }
	// }

}

// method id "partners.users.updateProfile":

type UsersUpdateProfileCall struct {
	s           *Service
	userprofile *UserProfile
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// UpdateProfile: Updates a user's profile. A user can only update their
// own profile and
// should only be called within the context of a logged in user.
func (r *UsersService) UpdateProfile(userprofile *UserProfile) *UsersUpdateProfileCall {
	c := &UsersUpdateProfileCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.userprofile = userprofile
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *UsersUpdateProfileCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *UsersUpdateProfileCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *UsersUpdateProfileCall) RequestMetadataLocale(requestMetadataLocale string) *UsersUpdateProfileCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *UsersUpdateProfileCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *UsersUpdateProfileCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UsersUpdateProfileCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *UsersUpdateProfileCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *UsersUpdateProfileCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *UsersUpdateProfileCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *UsersUpdateProfileCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *UsersUpdateProfileCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *UsersUpdateProfileCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *UsersUpdateProfileCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UsersUpdateProfileCall) Fields(s ...googleapi.Field) *UsersUpdateProfileCall {
	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 *UsersUpdateProfileCall) Context(ctx context.Context) *UsersUpdateProfileCall {
	c.ctx_ = ctx
	return c
}

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

func (c *UsersUpdateProfileCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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.userprofile)
	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, "v2/users/profile")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.users.updateProfile" 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 *UsersUpdateProfileCall) 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": "Updates a user's profile. A user can only update their own profile and\nshould only be called within the context of a logged in user.",
	//   "flatPath": "v2/users/profile",
	//   "httpMethod": "PATCH",
	//   "id": "partners.users.updateProfile",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/users/profile",
	//   "request": {
	//     "$ref": "UserProfile"
	//   },
	//   "response": {
	//     "$ref": "UserProfile"
	//   }
	// }

}

// method id "partners.getPartnersstatus":

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

// GetPartnersstatus: Gets Partners Status of the logged in user's
// agency.
// Should only be called if the logged in user is the admin of the
// agency.
func (r *V2Service) GetPartnersstatus() *V2GetPartnersstatusCall {
	c := &V2GetPartnersstatusCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *V2GetPartnersstatusCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *V2GetPartnersstatusCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *V2GetPartnersstatusCall) RequestMetadataLocale(requestMetadataLocale string) *V2GetPartnersstatusCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *V2GetPartnersstatusCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *V2GetPartnersstatusCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *V2GetPartnersstatusCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *V2GetPartnersstatusCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *V2GetPartnersstatusCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *V2GetPartnersstatusCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *V2GetPartnersstatusCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *V2GetPartnersstatusCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *V2GetPartnersstatusCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *V2GetPartnersstatusCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *V2GetPartnersstatusCall) Fields(s ...googleapi.Field) *V2GetPartnersstatusCall {
	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 *V2GetPartnersstatusCall) IfNoneMatch(entityTag string) *V2GetPartnersstatusCall {
	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 *V2GetPartnersstatusCall) Context(ctx context.Context) *V2GetPartnersstatusCall {
	c.ctx_ = ctx
	return c
}

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

func (c *V2GetPartnersstatusCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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, "v2/partnersstatus")
	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 "partners.getPartnersstatus" call.
// Exactly one of *GetPartnersStatusResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GetPartnersStatusResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *V2GetPartnersstatusCall) Do(opts ...googleapi.CallOption) (*GetPartnersStatusResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetPartnersStatusResponse{
		ServerResponse: googleapi.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 Partners Status of the logged in user's agency.\nShould only be called if the logged in user is the admin of the agency.",
	//   "flatPath": "v2/partnersstatus",
	//   "httpMethod": "GET",
	//   "id": "partners.getPartnersstatus",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/partnersstatus",
	//   "response": {
	//     "$ref": "GetPartnersStatusResponse"
	//   }
	// }

}

// method id "partners.updateCompanies":

type V2UpdateCompaniesCall struct {
	s          *Service
	company    *Company
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// UpdateCompanies: Update company.
// Should only be called within the context of an authorized logged in
// user.
func (r *V2Service) UpdateCompanies(company *Company) *V2UpdateCompaniesCall {
	c := &V2UpdateCompaniesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.company = company
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *V2UpdateCompaniesCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *V2UpdateCompaniesCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *V2UpdateCompaniesCall) RequestMetadataLocale(requestMetadataLocale string) *V2UpdateCompaniesCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *V2UpdateCompaniesCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *V2UpdateCompaniesCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *V2UpdateCompaniesCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *V2UpdateCompaniesCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *V2UpdateCompaniesCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *V2UpdateCompaniesCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *V2UpdateCompaniesCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *V2UpdateCompaniesCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *V2UpdateCompaniesCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *V2UpdateCompaniesCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// UpdateMask sets the optional parameter "updateMask": Standard field
// mask for the set of fields to be updated.
// Required with at least 1 value in FieldMask's paths.
func (c *V2UpdateCompaniesCall) UpdateMask(updateMask string) *V2UpdateCompaniesCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *V2UpdateCompaniesCall) Fields(s ...googleapi.Field) *V2UpdateCompaniesCall {
	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 *V2UpdateCompaniesCall) Context(ctx context.Context) *V2UpdateCompaniesCall {
	c.ctx_ = ctx
	return c
}

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

func (c *V2UpdateCompaniesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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.company)
	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, "v2/companies")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.updateCompanies" call.
// Exactly one of *Company or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Company.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *V2UpdateCompaniesCall) Do(opts ...googleapi.CallOption) (*Company, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Company{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Update company.\nShould only be called within the context of an authorized logged in user.",
	//   "flatPath": "v2/companies",
	//   "httpMethod": "PATCH",
	//   "id": "partners.updateCompanies",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Standard field mask for the set of fields to be updated.\nRequired with at least 1 value in FieldMask's paths.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/companies",
	//   "request": {
	//     "$ref": "Company"
	//   },
	//   "response": {
	//     "$ref": "Company"
	//   }
	// }

}

// method id "partners.updateLeads":

type V2UpdateLeadsCall struct {
	s          *Service
	lead       *Lead
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// UpdateLeads: Updates the specified lead.
func (r *V2Service) UpdateLeads(lead *Lead) *V2UpdateLeadsCall {
	c := &V2UpdateLeadsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.lead = lead
	return c
}

// RequestMetadataExperimentIds sets the optional parameter
// "requestMetadata.experimentIds": Experiment IDs the current request
// belongs to.
func (c *V2UpdateLeadsCall) RequestMetadataExperimentIds(requestMetadataExperimentIds ...string) *V2UpdateLeadsCall {
	c.urlParams_.SetMulti("requestMetadata.experimentIds", append([]string{}, requestMetadataExperimentIds...))
	return c
}

// RequestMetadataLocale sets the optional parameter
// "requestMetadata.locale": Locale to use for the current request.
func (c *V2UpdateLeadsCall) RequestMetadataLocale(requestMetadataLocale string) *V2UpdateLeadsCall {
	c.urlParams_.Set("requestMetadata.locale", requestMetadataLocale)
	return c
}

// RequestMetadataPartnersSessionId sets the optional parameter
// "requestMetadata.partnersSessionId": Google Partners session ID.
func (c *V2UpdateLeadsCall) RequestMetadataPartnersSessionId(requestMetadataPartnersSessionId string) *V2UpdateLeadsCall {
	c.urlParams_.Set("requestMetadata.partnersSessionId", requestMetadataPartnersSessionId)
	return c
}

// RequestMetadataTrafficSourceTrafficSourceId sets the optional
// parameter "requestMetadata.trafficSource.trafficSourceId": Identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *V2UpdateLeadsCall) RequestMetadataTrafficSourceTrafficSourceId(requestMetadataTrafficSourceTrafficSourceId string) *V2UpdateLeadsCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSourceId", requestMetadataTrafficSourceTrafficSourceId)
	return c
}

// RequestMetadataTrafficSourceTrafficSubId sets the optional parameter
// "requestMetadata.trafficSource.trafficSubId": Second level identifier
// to indicate where the traffic comes from.
// An identifier has multiple letters created by a team which redirected
// the
// traffic to us.
func (c *V2UpdateLeadsCall) RequestMetadataTrafficSourceTrafficSubId(requestMetadataTrafficSourceTrafficSubId string) *V2UpdateLeadsCall {
	c.urlParams_.Set("requestMetadata.trafficSource.trafficSubId", requestMetadataTrafficSourceTrafficSubId)
	return c
}

// RequestMetadataUserOverridesIpAddress sets the optional parameter
// "requestMetadata.userOverrides.ipAddress": IP address to use instead
// of the user's geo-located IP address.
func (c *V2UpdateLeadsCall) RequestMetadataUserOverridesIpAddress(requestMetadataUserOverridesIpAddress string) *V2UpdateLeadsCall {
	c.urlParams_.Set("requestMetadata.userOverrides.ipAddress", requestMetadataUserOverridesIpAddress)
	return c
}

// RequestMetadataUserOverridesUserId sets the optional parameter
// "requestMetadata.userOverrides.userId": Logged-in user ID to
// impersonate instead of the user's ID.
func (c *V2UpdateLeadsCall) RequestMetadataUserOverridesUserId(requestMetadataUserOverridesUserId string) *V2UpdateLeadsCall {
	c.urlParams_.Set("requestMetadata.userOverrides.userId", requestMetadataUserOverridesUserId)
	return c
}

// UpdateMask sets the optional parameter "updateMask": Standard field
// mask for the set of fields to be updated.
// Required with at least 1 value in FieldMask's paths.
// Only `state` and `adwords_customer_id` are currently supported.
func (c *V2UpdateLeadsCall) UpdateMask(updateMask string) *V2UpdateLeadsCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *V2UpdateLeadsCall) Fields(s ...googleapi.Field) *V2UpdateLeadsCall {
	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 *V2UpdateLeadsCall) Context(ctx context.Context) *V2UpdateLeadsCall {
	c.ctx_ = ctx
	return c
}

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

func (c *V2UpdateLeadsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	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.lead)
	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, "v2/leads")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "partners.updateLeads" call.
// Exactly one of *Lead or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Lead.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *V2UpdateLeadsCall) Do(opts ...googleapi.CallOption) (*Lead, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Lead{
		ServerResponse: googleapi.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 the specified lead.",
	//   "flatPath": "v2/leads",
	//   "httpMethod": "PATCH",
	//   "id": "partners.updateLeads",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "requestMetadata.experimentIds": {
	//       "description": "Experiment IDs the current request belongs to.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "requestMetadata.locale": {
	//       "description": "Locale to use for the current request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.partnersSessionId": {
	//       "description": "Google Partners session ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSourceId": {
	//       "description": "Identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.trafficSource.trafficSubId": {
	//       "description": "Second level identifier to indicate where the traffic comes from.\nAn identifier has multiple letters created by a team which redirected the\ntraffic to us.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.ipAddress": {
	//       "description": "IP address to use instead of the user's geo-located IP address.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestMetadata.userOverrides.userId": {
	//       "description": "Logged-in user ID to impersonate instead of the user's ID.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Standard field mask for the set of fields to be updated.\nRequired with at least 1 value in FieldMask's paths.\nOnly `state` and `adwords_customer_id` are currently supported.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/leads",
	//   "request": {
	//     "$ref": "Lead"
	//   },
	//   "response": {
	//     "$ref": "Lead"
	//   }
	// }

}
