// 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 cloudsearch provides access to the Cloud Search API.
//
// For product documentation, see: https://developers.google.com/cloud-search/docs/guides/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/cloudsearch/v1"
//   ...
//   ctx := context.Background()
//   cloudsearchService, err := cloudsearch.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   cloudsearchService, err := cloudsearch.NewService(ctx, option.WithScopes(cloudsearch.CloudSearchStatsIndexingScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   cloudsearchService, err := cloudsearch.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, ...)
//   cloudsearchService, err := cloudsearch.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package cloudsearch // import "google.golang.org/api/cloudsearch/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint

const apiId = "cloudsearch:v1"
const apiName = "cloudsearch"
const apiVersion = "v1"
const basePath = "https://cloudsearch.googleapis.com/"
const mtlsBasePath = "https://cloudsearch.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// Index and serve your organization's data with Cloud Search
	CloudSearchScope = "https://www.googleapis.com/auth/cloud_search"

	// Index and serve your organization's data with Cloud Search
	CloudSearchDebugScope = "https://www.googleapis.com/auth/cloud_search.debug"

	// Index and serve your organization's data with Cloud Search
	CloudSearchIndexingScope = "https://www.googleapis.com/auth/cloud_search.indexing"

	// Search your organization's data in the Cloud Search index
	CloudSearchQueryScope = "https://www.googleapis.com/auth/cloud_search.query"

	// Index and serve your organization's data with Cloud Search
	CloudSearchSettingsScope = "https://www.googleapis.com/auth/cloud_search.settings"

	// Index and serve your organization's data with Cloud Search
	CloudSearchSettingsIndexingScope = "https://www.googleapis.com/auth/cloud_search.settings.indexing"

	// Index and serve your organization's data with Cloud Search
	CloudSearchSettingsQueryScope = "https://www.googleapis.com/auth/cloud_search.settings.query"

	// Index and serve your organization's data with Cloud Search
	CloudSearchStatsScope = "https://www.googleapis.com/auth/cloud_search.stats"

	// Index and serve your organization's data with Cloud Search
	CloudSearchStatsIndexingScope = "https://www.googleapis.com/auth/cloud_search.stats.indexing"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud_search",
		"https://www.googleapis.com/auth/cloud_search.debug",
		"https://www.googleapis.com/auth/cloud_search.indexing",
		"https://www.googleapis.com/auth/cloud_search.query",
		"https://www.googleapis.com/auth/cloud_search.settings",
		"https://www.googleapis.com/auth/cloud_search.settings.indexing",
		"https://www.googleapis.com/auth/cloud_search.settings.query",
		"https://www.googleapis.com/auth/cloud_search.stats",
		"https://www.googleapis.com/auth/cloud_search.stats.indexing",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Debug = NewDebugService(s)
	s.Indexing = NewIndexingService(s)
	s.Media = NewMediaService(s)
	s.Operations = NewOperationsService(s)
	s.Query = NewQueryService(s)
	s.Settings = NewSettingsService(s)
	s.Stats = NewStatsService(s)
	return s, nil
}

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

	Debug *DebugService

	Indexing *IndexingService

	Media *MediaService

	Operations *OperationsService

	Query *QueryService

	Settings *SettingsService

	Stats *StatsService
}

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

func NewDebugService(s *Service) *DebugService {
	rs := &DebugService{s: s}
	rs.Datasources = NewDebugDatasourcesService(s)
	rs.Identitysources = NewDebugIdentitysourcesService(s)
	return rs
}

type DebugService struct {
	s *Service

	Datasources *DebugDatasourcesService

	Identitysources *DebugIdentitysourcesService
}

func NewDebugDatasourcesService(s *Service) *DebugDatasourcesService {
	rs := &DebugDatasourcesService{s: s}
	rs.Items = NewDebugDatasourcesItemsService(s)
	return rs
}

type DebugDatasourcesService struct {
	s *Service

	Items *DebugDatasourcesItemsService
}

func NewDebugDatasourcesItemsService(s *Service) *DebugDatasourcesItemsService {
	rs := &DebugDatasourcesItemsService{s: s}
	rs.Unmappedids = NewDebugDatasourcesItemsUnmappedidsService(s)
	return rs
}

type DebugDatasourcesItemsService struct {
	s *Service

	Unmappedids *DebugDatasourcesItemsUnmappedidsService
}

func NewDebugDatasourcesItemsUnmappedidsService(s *Service) *DebugDatasourcesItemsUnmappedidsService {
	rs := &DebugDatasourcesItemsUnmappedidsService{s: s}
	return rs
}

type DebugDatasourcesItemsUnmappedidsService struct {
	s *Service
}

func NewDebugIdentitysourcesService(s *Service) *DebugIdentitysourcesService {
	rs := &DebugIdentitysourcesService{s: s}
	rs.Items = NewDebugIdentitysourcesItemsService(s)
	rs.Unmappedids = NewDebugIdentitysourcesUnmappedidsService(s)
	return rs
}

type DebugIdentitysourcesService struct {
	s *Service

	Items *DebugIdentitysourcesItemsService

	Unmappedids *DebugIdentitysourcesUnmappedidsService
}

func NewDebugIdentitysourcesItemsService(s *Service) *DebugIdentitysourcesItemsService {
	rs := &DebugIdentitysourcesItemsService{s: s}
	return rs
}

type DebugIdentitysourcesItemsService struct {
	s *Service
}

func NewDebugIdentitysourcesUnmappedidsService(s *Service) *DebugIdentitysourcesUnmappedidsService {
	rs := &DebugIdentitysourcesUnmappedidsService{s: s}
	return rs
}

type DebugIdentitysourcesUnmappedidsService struct {
	s *Service
}

func NewIndexingService(s *Service) *IndexingService {
	rs := &IndexingService{s: s}
	rs.Datasources = NewIndexingDatasourcesService(s)
	return rs
}

type IndexingService struct {
	s *Service

	Datasources *IndexingDatasourcesService
}

func NewIndexingDatasourcesService(s *Service) *IndexingDatasourcesService {
	rs := &IndexingDatasourcesService{s: s}
	rs.Items = NewIndexingDatasourcesItemsService(s)
	return rs
}

type IndexingDatasourcesService struct {
	s *Service

	Items *IndexingDatasourcesItemsService
}

func NewIndexingDatasourcesItemsService(s *Service) *IndexingDatasourcesItemsService {
	rs := &IndexingDatasourcesItemsService{s: s}
	return rs
}

type IndexingDatasourcesItemsService struct {
	s *Service
}

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

type MediaService struct {
	s *Service
}

func NewOperationsService(s *Service) *OperationsService {
	rs := &OperationsService{s: s}
	return rs
}

type OperationsService struct {
	s *Service
}

func NewQueryService(s *Service) *QueryService {
	rs := &QueryService{s: s}
	rs.Sources = NewQuerySourcesService(s)
	return rs
}

type QueryService struct {
	s *Service

	Sources *QuerySourcesService
}

func NewQuerySourcesService(s *Service) *QuerySourcesService {
	rs := &QuerySourcesService{s: s}
	return rs
}

type QuerySourcesService struct {
	s *Service
}

func NewSettingsService(s *Service) *SettingsService {
	rs := &SettingsService{s: s}
	rs.Datasources = NewSettingsDatasourcesService(s)
	rs.Searchapplications = NewSettingsSearchapplicationsService(s)
	return rs
}

type SettingsService struct {
	s *Service

	Datasources *SettingsDatasourcesService

	Searchapplications *SettingsSearchapplicationsService
}

func NewSettingsDatasourcesService(s *Service) *SettingsDatasourcesService {
	rs := &SettingsDatasourcesService{s: s}
	return rs
}

type SettingsDatasourcesService struct {
	s *Service
}

func NewSettingsSearchapplicationsService(s *Service) *SettingsSearchapplicationsService {
	rs := &SettingsSearchapplicationsService{s: s}
	return rs
}

type SettingsSearchapplicationsService struct {
	s *Service
}

func NewStatsService(s *Service) *StatsService {
	rs := &StatsService{s: s}
	rs.Index = NewStatsIndexService(s)
	rs.Query = NewStatsQueryService(s)
	rs.Session = NewStatsSessionService(s)
	rs.User = NewStatsUserService(s)
	return rs
}

type StatsService struct {
	s *Service

	Index *StatsIndexService

	Query *StatsQueryService

	Session *StatsSessionService

	User *StatsUserService
}

func NewStatsIndexService(s *Service) *StatsIndexService {
	rs := &StatsIndexService{s: s}
	rs.Datasources = NewStatsIndexDatasourcesService(s)
	return rs
}

type StatsIndexService struct {
	s *Service

	Datasources *StatsIndexDatasourcesService
}

func NewStatsIndexDatasourcesService(s *Service) *StatsIndexDatasourcesService {
	rs := &StatsIndexDatasourcesService{s: s}
	return rs
}

type StatsIndexDatasourcesService struct {
	s *Service
}

func NewStatsQueryService(s *Service) *StatsQueryService {
	rs := &StatsQueryService{s: s}
	rs.Searchapplications = NewStatsQuerySearchapplicationsService(s)
	return rs
}

type StatsQueryService struct {
	s *Service

	Searchapplications *StatsQuerySearchapplicationsService
}

func NewStatsQuerySearchapplicationsService(s *Service) *StatsQuerySearchapplicationsService {
	rs := &StatsQuerySearchapplicationsService{s: s}
	return rs
}

type StatsQuerySearchapplicationsService struct {
	s *Service
}

func NewStatsSessionService(s *Service) *StatsSessionService {
	rs := &StatsSessionService{s: s}
	rs.Searchapplications = NewStatsSessionSearchapplicationsService(s)
	return rs
}

type StatsSessionService struct {
	s *Service

	Searchapplications *StatsSessionSearchapplicationsService
}

func NewStatsSessionSearchapplicationsService(s *Service) *StatsSessionSearchapplicationsService {
	rs := &StatsSessionSearchapplicationsService{s: s}
	return rs
}

type StatsSessionSearchapplicationsService struct {
	s *Service
}

func NewStatsUserService(s *Service) *StatsUserService {
	rs := &StatsUserService{s: s}
	rs.Searchapplications = NewStatsUserSearchapplicationsService(s)
	return rs
}

type StatsUserService struct {
	s *Service

	Searchapplications *StatsUserSearchapplicationsService
}

func NewStatsUserSearchapplicationsService(s *Service) *StatsUserSearchapplicationsService {
	rs := &StatsUserSearchapplicationsService{s: s}
	return rs
}

type StatsUserSearchapplicationsService struct {
	s *Service
}

// BooleanOperatorOptions: Used to provide a search operator for boolean
// properties. This is optional. Search operators let users restrict the
// query to specific fields relevant to the type of item being searched.
type BooleanOperatorOptions struct {
	// OperatorName: Indicates the operator name required in the query in
	// order to isolate the boolean property. For example, if operatorName
	// is *closed* and the property's name is *isClosed*, then queries like
	// *closed:<value>* show results only where the value of the property
	// named *isClosed* matches *<value>*. By contrast, a search that uses
	// the same *<value>* without an operator returns all items where
	// *<value>* matches the value of any String properties or text within
	// the content field for the item. The operator name can only contain
	// lowercase letters (a-z). The maximum length is 32 characters.
	OperatorName string `json:"operatorName,omitempty"`

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

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

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

// BooleanPropertyOptions: Options for boolean properties.
type BooleanPropertyOptions struct {
	// OperatorOptions: If set, describes how the boolean should be used as
	// a search operator.
	OperatorOptions *BooleanOperatorOptions `json:"operatorOptions,omitempty"`

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

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

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

type CheckAccessResponse struct {
	// HasAccess: Returns true if principal has access. Returns false
	// otherwise.
	HasAccess bool `json:"hasAccess,omitempty"`

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

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

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

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

type CompositeFilter struct {
	// LogicOperator: The logic operator of the sub filter.
	//
	// Possible values:
	//   "AND" - Logical operators, which can only be applied to sub
	// filters.
	//   "OR"
	//   "NOT" - NOT can only be applied on a single sub filter.
	LogicOperator string `json:"logicOperator,omitempty"`

	// SubFilters: Sub filters.
	SubFilters []*Filter `json:"subFilters,omitempty"`

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

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

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

// CustomerIndexStats: Aggregation of items by status code as of the
// specified date.
type CustomerIndexStats struct {
	// Date: Date for which statistics were calculated.
	Date *Date `json:"date,omitempty"`

	// ItemCountByStatus: Number of items aggregrated by status code.
	ItemCountByStatus []*ItemCountByStatus `json:"itemCountByStatus,omitempty"`

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

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

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

type CustomerQueryStats struct {
	// Date: Date for which query stats were calculated. Stats calculated on
	// the next day close to midnight are returned.
	Date *Date `json:"date,omitempty"`

	QueryCountByStatus []*QueryCountByStatus `json:"queryCountByStatus,omitempty"`

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

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

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

type CustomerSessionStats struct {
	// Date: Date for which session stats were calculated. Stats calculated
	// on the next day close to midnight are returned.
	Date *Date `json:"date,omitempty"`

	// SearchSessionsCount: The count of search sessions on the day
	SearchSessionsCount int64 `json:"searchSessionsCount,omitempty,string"`

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

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

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

type CustomerUserStats struct {
	// Date: Date for which session stats were calculated. Stats calculated
	// on the next day close to midnight are returned.
	Date *Date `json:"date,omitempty"`

	// OneDayActiveUsersCount: The count of unique active users in the past
	// one day
	OneDayActiveUsersCount int64 `json:"oneDayActiveUsersCount,omitempty,string"`

	// SevenDaysActiveUsersCount: The count of unique active users in the
	// past seven days
	SevenDaysActiveUsersCount int64 `json:"sevenDaysActiveUsersCount,omitempty,string"`

	// ThirtyDaysActiveUsersCount: The count of unique active users in the
	// past thirty days
	ThirtyDaysActiveUsersCount int64 `json:"thirtyDaysActiveUsersCount,omitempty,string"`

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

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

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

// DataSource: Datasource is a logical namespace for items to be
// indexed. All items must belong to a datasource. This is the
// prerequisite before items can be indexed into Cloud Search.
type DataSource struct {
	// DisableModifications: If true, Indexing API rejects any modification
	// calls to this datasource such as create, update, and delete.
	// Disabling this does not imply halting process of previously accepted
	// data.
	DisableModifications bool `json:"disableModifications,omitempty"`

	// DisableServing: Disable serving any search or assist results.
	DisableServing bool `json:"disableServing,omitempty"`

	// DisplayName: Required. Display name of the datasource The maximum
	// length is 300 characters.
	DisplayName string `json:"displayName,omitempty"`

	// IndexingServiceAccounts: List of service accounts that have indexing
	// access.
	IndexingServiceAccounts []string `json:"indexingServiceAccounts,omitempty"`

	// ItemsVisibility: This field restricts visibility to items at the
	// datasource level. Items within the datasource are restricted to the
	// union of users and groups included in this field. Note that, this
	// does not ensure access to a specific item, as users need to have ACL
	// permissions on the contained items. This ensures a high level access
	// on the entire datasource, and that the individual items are not
	// shared outside this visibility.
	ItemsVisibility []*GSuitePrincipal `json:"itemsVisibility,omitempty"`

	// Name: Name of the datasource resource. Format:
	// datasources/{source_id}. The name is ignored when creating a
	// datasource.
	Name string `json:"name,omitempty"`

	// OperationIds: IDs of the Long Running Operations (LROs) currently
	// running for this schema.
	OperationIds []string `json:"operationIds,omitempty"`

	// ShortName: A short name or alias for the source. This value will be
	// used to match the 'source' operator. For example, if the short name
	// is *<value>* then queries like *source:<value>* will only return
	// results for this source. The value must be unique across all
	// datasources. The value must only contain alphanumeric characters
	// (a-zA-Z0-9). The value cannot start with 'google' and cannot be one
	// of the following: mail, gmail, docs, drive, groups, sites, calendar,
	// hangouts, gplus, keep, people, teams. Its maximum length is 32
	// characters.
	ShortName string `json:"shortName,omitempty"`

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

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

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

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

// DataSourceIndexStats: Aggregation of items by status code as of the
// specified date.
type DataSourceIndexStats struct {
	// Date: Date for which index stats were calculated. If the date of
	// request is not the current date then stats calculated on the next day
	// are returned. Stats are calculated close to mid night in this case.
	// If date of request is current date, then real time stats are
	// returned.
	Date *Date `json:"date,omitempty"`

	// ItemCountByStatus: Number of items aggregrated by status code.
	ItemCountByStatus []*ItemCountByStatus `json:"itemCountByStatus,omitempty"`

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

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

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

// DataSourceRestriction: Restriction on Datasource.
type DataSourceRestriction struct {
	// FilterOptions: Filter options restricting the results. If multiple
	// filters are present, they are grouped by object type before joining.
	// Filters with the same object type are joined conjunctively, then the
	// resulting expressions are joined disjunctively. The maximum number of
	// elements is 20. NOTE: Suggest API supports only few filters at the
	// moment: "objecttype", "type" and "mimetype". For now, schema specific
	// filters cannot be used to filter suggestions.
	FilterOptions []*FilterOptions `json:"filterOptions,omitempty"`

	// Source: The source of restriction.
	Source *Source `json:"source,omitempty"`

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

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

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

// Date: Represents a whole calendar date, for example a date of birth.
// The time of day and time zone are either specified elsewhere or are
// not significant. The date is relative to the [Proleptic Gregorian
// Calendar](https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar).
//  The date must be a valid calendar date between the year 1 and 9999.
type Date struct {
	// Day: Day of month. Must be from 1 to 31 and valid for the year and
	// month.
	Day int64 `json:"day,omitempty"`

	// Month: Month of date. Must be from 1 to 12.
	Month int64 `json:"month,omitempty"`

	// Year: Year of date. Must be from 1 to 9999.
	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)
}

// DateOperatorOptions: Optional. Provides a search operator for date
// properties. Search operators let users restrict the query to specific
// fields relevant to the type of item being searched.
type DateOperatorOptions struct {
	// GreaterThanOperatorName: Indicates the operator name required in the
	// query in order to isolate the date property using the greater-than
	// operator. For example, if greaterThanOperatorName is *closedafter*
	// and the property's name is *closeDate*, then queries like
	// *closedafter:<value>* show results only where the value of the
	// property named *closeDate* is later than *<value>*. The operator name
	// can only contain lowercase letters (a-z). The maximum length is 32
	// characters.
	GreaterThanOperatorName string `json:"greaterThanOperatorName,omitempty"`

	// LessThanOperatorName: Indicates the operator name required in the
	// query in order to isolate the date property using the less-than
	// operator. For example, if lessThanOperatorName is *closedbefore* and
	// the property's name is *closeDate*, then queries like
	// *closedbefore:<value>* show results only where the value of the
	// property named *closeDate* is earlier than *<value>*. The operator
	// name can only contain lowercase letters (a-z). The maximum length is
	// 32 characters.
	LessThanOperatorName string `json:"lessThanOperatorName,omitempty"`

	// OperatorName: Indicates the actual string required in the query in
	// order to isolate the date property. For example, suppose an issue
	// tracking schema object has a property named *closeDate* that
	// specifies an operator with an operatorName of *closedon*. For
	// searches on that data, queries like *closedon:<value>* show results
	// only where the value of the *closeDate* property matches *<value>*.
	// By contrast, a search that uses the same *<value>* without an
	// operator returns all items where *<value>* matches the value of any
	// String properties or text within the content field for the indexed
	// datasource. The operator name can only contain lowercase letters
	// (a-z). The maximum length is 32 characters.
	OperatorName string `json:"operatorName,omitempty"`

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

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

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

// DatePropertyOptions: Options for date properties.
type DatePropertyOptions struct {
	// OperatorOptions: If set, describes how the date should be used as a
	// search operator.
	OperatorOptions *DateOperatorOptions `json:"operatorOptions,omitempty"`

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

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

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

// DateValues: List of date values.
type DateValues struct {
	Values []*Date `json:"values,omitempty"`

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

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

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

// DebugOptions: Shared request debug options for all cloudsearch RPC
// methods.
type DebugOptions struct {
	// EnableDebugging: If you are asked by Google to help with debugging,
	// set this field. Otherwise, ignore this field.
	EnableDebugging bool `json:"enableDebugging,omitempty"`

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

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

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

type DeleteQueueItemsRequest struct {
	// ConnectorName: Name of connector making this call. Format:
	// datasources/{source_id}/connectors/{ID}
	ConnectorName string `json:"connectorName,omitempty"`

	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	// Queue: Name of a queue to delete items from.
	Queue string `json:"queue,omitempty"`

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

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

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

// DisplayedProperty: A reference to a top-level property within the
// object that should be displayed in search results. The values of the
// chosen properties is displayed in the search results along with the
// display label for that property if one is specified. If a display
// label is not specified, only the values is shown.
type DisplayedProperty struct {
	// PropertyName: The name of the top-level property as defined in a
	// property definition for the object. If the name is not a defined
	// property in the schema, an error is given when attempting to update
	// the schema.
	PropertyName string `json:"propertyName,omitempty"`

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

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

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

// DoubleOperatorOptions: Used to provide a search operator for double
// properties. This is optional. Search operators let users restrict the
// query to specific fields relevant to the type of item being searched.
type DoubleOperatorOptions struct {
	// OperatorName: Indicates the operator name required in the query in
	// order to use the double property in sorting or as a facet. The
	// operator name can only contain lowercase letters (a-z). The maximum
	// length is 32 characters.
	OperatorName string `json:"operatorName,omitempty"`

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

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

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

// DoublePropertyOptions: Options for double properties.
type DoublePropertyOptions struct {
	// OperatorOptions: If set, describes how the double should be used as a
	// search operator.
	OperatorOptions *DoubleOperatorOptions `json:"operatorOptions,omitempty"`

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

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

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

// DoubleValues: List of double values.
type DoubleValues struct {
	Values []float64 `json:"values,omitempty"`

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

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

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

// DriveFollowUpRestrict: Drive follow-up search restricts (e.g.
// "followup:suggestions").
type DriveFollowUpRestrict struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "FOLLOWUP_SUGGESTIONS"
	//   "FOLLOWUP_ACTION_ITEMS"
	Type string `json:"type,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 *DriveFollowUpRestrict) MarshalJSON() ([]byte, error) {
	type NoMethod DriveFollowUpRestrict
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DriveLocationRestrict: Drive location search restricts (e.g.
// "is:starred").
type DriveLocationRestrict struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "TRASHED"
	//   "STARRED"
	Type string `json:"type,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 *DriveLocationRestrict) MarshalJSON() ([]byte, error) {
	type NoMethod DriveLocationRestrict
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DriveMimeTypeRestrict: Drive mime-type search restricts (e.g.
// "type:pdf").
type DriveMimeTypeRestrict struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "PDF"
	//   "DOCUMENT"
	//   "PRESENTATION"
	//   "SPREADSHEET"
	//   "FORM"
	//   "DRAWING"
	//   "SCRIPT"
	//   "MAP"
	//   "IMAGE"
	//   "AUDIO"
	//   "VIDEO"
	//   "FOLDER"
	//   "ARCHIVE"
	//   "SITE"
	Type string `json:"type,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 *DriveMimeTypeRestrict) MarshalJSON() ([]byte, error) {
	type NoMethod DriveMimeTypeRestrict
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DriveTimeSpanRestrict: The time span search restrict (e.g.
// "after:2017-09-11 before:2017-09-12").
type DriveTimeSpanRestrict struct {
	// Possible values:
	//   "UNSPECIFIED"
	//   "TODAY"
	//   "YESTERDAY"
	//   "LAST_7_DAYS"
	//   "LAST_30_DAYS" - Not Enabled
	//   "LAST_90_DAYS" - Not Enabled
	Type string `json:"type,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 *DriveTimeSpanRestrict) MarshalJSON() ([]byte, error) {
	type NoMethod DriveTimeSpanRestrict
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EmailAddress: A person's email address.
type EmailAddress struct {
	// EmailAddress: The email address.
	EmailAddress string `json:"emailAddress,omitempty"`

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

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

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

// EnumOperatorOptions: Used to provide a search operator for enum
// properties. This is optional. Search operators let users restrict the
// query to specific fields relevant to the type of item being searched.
// For example, if you provide no operator for a *priority* enum
// property with possible values *p0* and *p1*, a query that contains
// the term *p0* returns items that have *p0* as the value of the
// *priority* property, as well as any items that contain the string
// *p0* in other fields. If you provide an operator name for the enum,
// such as *priority*, then search users can use that operator to refine
// results to only items that have *p0* as this property's value, with
// the query *priority:p0*.
type EnumOperatorOptions struct {
	// OperatorName: Indicates the operator name required in the query in
	// order to isolate the enum property. For example, if operatorName is
	// *priority* and the property's name is *priorityVal*, then queries
	// like *priority:<value>* show results only where the value of the
	// property named *priorityVal* matches *<value>*. By contrast, a search
	// that uses the same *<value>* without an operator returns all items
	// where *<value>* matches the value of any String properties or text
	// within the content field for the item. The operator name can only
	// contain lowercase letters (a-z). The maximum length is 32 characters.
	OperatorName string `json:"operatorName,omitempty"`

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

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

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

// EnumPropertyOptions: Options for enum properties, which allow you to
// define a restricted set of strings to match user queries, set
// rankings for those string values, and define an operator name to be
// paired with those strings so that users can narrow results to only
// items with a specific value. For example, for items in a request
// tracking system with priority information, you could define *p0* as
// an allowable enum value and tie this enum to the operator name
// *priority* so that search users could add *priority:p0* to their
// query to restrict the set of results to only those items indexed with
// the value *p0*.
type EnumPropertyOptions struct {
	// OperatorOptions: If set, describes how the enum should be used as a
	// search operator.
	OperatorOptions *EnumOperatorOptions `json:"operatorOptions,omitempty"`

	// OrderedRanking: Used to specify the ordered ranking for the
	// enumeration that determines how the integer values provided in the
	// possible EnumValuePairs are used to rank results. If specified,
	// integer values must be provided for all possible EnumValuePair values
	// given for this property. Can only be used if isRepeatable is false.
	//
	// Possible values:
	//   "NO_ORDER" - There is no ranking order for the property. Results
	// aren't adjusted by this property's value.
	//   "ASCENDING" - This property is ranked in ascending order. Lower
	// values indicate lower ranking.
	//   "DESCENDING" - This property is ranked in descending order. Lower
	// values indicate higher ranking.
	OrderedRanking string `json:"orderedRanking,omitempty"`

	// PossibleValues: The list of possible values for the enumeration
	// property. All EnumValuePairs must provide a string value. If you
	// specify an integer value for one EnumValuePair, then all possible
	// EnumValuePairs must provide an integer value. Both the string value
	// and integer value must be unique over all possible values. Once set,
	// possible values cannot be removed or modified. If you supply an
	// ordered ranking and think you might insert additional enum values in
	// the future, leave gaps in the initial integer values to allow adding
	// a value in between previously registered values. The maximum number
	// of elements is 100.
	PossibleValues []*EnumValuePair `json:"possibleValues,omitempty"`

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

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

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

// EnumValuePair: The enumeration value pair defines two things: a
// required string value and an optional integer value. The string value
// defines the necessary query term required to retrieve that item, such
// as *p0* for a priority item. The integer value determines the ranking
// of that string value relative to other enumerated values for the same
// property. For example, you might associate *p0* with *0* and define
// another enum pair such as *p1* and *1*. You must use the integer
// value in combination with ordered ranking to set the ranking of a
// given value relative to other enumerated values for the same property
// name. Here, a ranking order of DESCENDING for *priority* properties
// results in a ranking boost for items indexed with a value of *p0*
// compared to items indexed with a value of *p1*. Without a specified
// ranking order, the integer value has no effect on item ranking.
type EnumValuePair struct {
	// IntegerValue: The integer value of the EnumValuePair which must be
	// non-negative. Optional.
	IntegerValue int64 `json:"integerValue,omitempty"`

	// StringValue: The string value of the EnumValuePair. The maximum
	// length is 32 characters.
	StringValue string `json:"stringValue,omitempty"`

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

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

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

// EnumValues: List of enum values.
type EnumValues struct {
	// Values: The maximum allowable length for string values is 32
	// characters.
	Values []string `json:"values,omitempty"`

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

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

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

// ErrorInfo: Error information about the response.
type ErrorInfo struct {
	ErrorMessages []*ErrorMessage `json:"errorMessages,omitempty"`

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

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

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

// ErrorMessage: Error message per source response.
type ErrorMessage struct {
	ErrorMessage string `json:"errorMessage,omitempty"`

	Source *Source `json:"source,omitempty"`

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

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

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

// FacetBucket: A bucket in a facet is the basic unit of operation. A
// bucket can comprise either a single value OR a contiguous range of
// values, depending on the type of the field bucketed. FacetBucket is
// currently used only for returning the response object.
type FacetBucket struct {
	// Count: Number of results that match the bucket value. Counts are only
	// returned for searches when count accuracy is ensured. Can be empty.
	Count int64 `json:"count,omitempty"`

	// Percentage: Percent of results that match the bucket value. The
	// returned value is between (0-100], and is rounded down to an integer
	// if fractional. If the value is not explicitly returned, it represents
	// a percentage value that rounds to 0. Percentages are returned for all
	// searches, but are an estimate. Because percentages are always
	// returned, you should render percentages instead of counts.
	Percentage int64 `json:"percentage,omitempty"`

	Value *Value `json:"value,omitempty"`

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

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

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

// FacetOptions: Specifies operators to return facet results for. There
// will be one FacetResult for every
// source_name/object_type/operator_name combination.
type FacetOptions struct {
	// NumFacetBuckets: Maximum number of facet buckets that should be
	// returned for this facet. Defaults to 10. Maximum value is 100.
	NumFacetBuckets int64 `json:"numFacetBuckets,omitempty"`

	// ObjectType: If object_type is set, only those objects of that type
	// will be used to compute facets. If empty, then all objects will be
	// used to compute facets.
	ObjectType string `json:"objectType,omitempty"`

	// OperatorName: Name of the operator chosen for faceting. @see
	// cloudsearch.SchemaPropertyOptions
	OperatorName string `json:"operatorName,omitempty"`

	// SourceName: Source name to facet on. Format: datasources/{source_id}
	// If empty, all data sources will be used.
	SourceName string `json:"sourceName,omitempty"`

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

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

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

// FacetResult: Source specific facet response
type FacetResult struct {
	// Buckets: FacetBuckets for values in response containing at least a
	// single result.
	Buckets []*FacetBucket `json:"buckets,omitempty"`

	// ObjectType: Object type for which facet results are returned. Can be
	// empty.
	ObjectType string `json:"objectType,omitempty"`

	// OperatorName: Name of the operator chosen for faceting. @see
	// cloudsearch.SchemaPropertyOptions
	OperatorName string `json:"operatorName,omitempty"`

	// SourceName: Source name for which facet results are returned. Will
	// not be empty.
	SourceName string `json:"sourceName,omitempty"`

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

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

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

type FieldViolation struct {
	// Description: Description of the error.
	Description string `json:"description,omitempty"`

	// Field: Path of field with violation.
	Field string `json:"field,omitempty"`

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

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

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

// Filter: A generic way of expressing filters in a query, which
// supports two approaches: **1. Setting a ValueFilter.** The name must
// match an operator_name defined in the schema for your data source.
// **2. Setting a CompositeFilter.** The filters are evaluated using the
// logical operator. The top-level operators can only be either an AND
// or a NOT. AND can appear only at the top-most level. OR can appear
// only under a top-level AND.
type Filter struct {
	CompositeFilter *CompositeFilter `json:"compositeFilter,omitempty"`

	ValueFilter *ValueFilter `json:"valueFilter,omitempty"`

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

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

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

// FilterOptions: Filter options to be applied on query.
type FilterOptions struct {
	// Filter: Generic filter to restrict the search, such as `lang:en`,
	// `site:xyz`.
	Filter *Filter `json:"filter,omitempty"`

	// ObjectType: If object_type is set, only objects of that type are
	// returned. This should correspond to the name of the object that was
	// registered within the definition of schema. The maximum length is 256
	// characters.
	ObjectType string `json:"objectType,omitempty"`

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

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

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

// FreshnessOptions: Indicates which freshness property to use when
// adjusting search ranking for an item. Fresher, more recent dates
// indicate higher quality. Use the freshness option property that best
// works with your data. For fileshare documents, last modified time is
// most relevant. For calendar event data, the time when the event
// occurs is a more relevant freshness indicator. In this way, calendar
// events that occur closer to the time of the search query are
// considered higher quality and ranked accordingly.
type FreshnessOptions struct {
	// FreshnessDuration: The duration after which an object should be
	// considered stale. The default value is 180 days (in seconds).
	FreshnessDuration string `json:"freshnessDuration,omitempty"`

	// FreshnessProperty: This property indicates the freshness level of the
	// object in the index. If set, this property must be a top-level
	// property within the property definitions and it must be a timestamp
	// type or date type. Otherwise, the Indexing API uses updateTime as the
	// freshness indicator. The maximum length is 256 characters. When a
	// property is used to calculate freshness, the value defaults to 2
	// years from the current time.
	FreshnessProperty string `json:"freshnessProperty,omitempty"`

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

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

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

type GSuitePrincipal struct {
	// GsuiteDomain: This principal represents all users of the G Suite
	// domain of the customer.
	GsuiteDomain bool `json:"gsuiteDomain,omitempty"`

	// GsuiteGroupEmail: This principal references a G Suite group account
	GsuiteGroupEmail string `json:"gsuiteGroupEmail,omitempty"`

	// GsuiteUserEmail: This principal references a G Suite user account
	GsuiteUserEmail string `json:"gsuiteUserEmail,omitempty"`

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

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

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

type GetCustomerIndexStatsResponse struct {
	// Stats: Summary of indexed item counts, one for each day in the
	// requested range.
	Stats []*CustomerIndexStats `json:"stats,omitempty"`

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

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

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

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

type GetCustomerQueryStatsResponse struct {
	Stats []*CustomerQueryStats `json:"stats,omitempty"`

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

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

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

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

type GetCustomerSessionStatsResponse struct {
	Stats []*CustomerSessionStats `json:"stats,omitempty"`

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

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

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

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

type GetCustomerUserStatsResponse struct {
	Stats []*CustomerUserStats `json:"stats,omitempty"`

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

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

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

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

type GetDataSourceIndexStatsResponse struct {
	// Stats: Summary of indexed item counts, one for each day in the
	// requested range.
	Stats []*DataSourceIndexStats `json:"stats,omitempty"`

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

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

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

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

type GetSearchApplicationQueryStatsResponse struct {
	Stats []*SearchApplicationQueryStats `json:"stats,omitempty"`

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

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

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

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

type GetSearchApplicationSessionStatsResponse struct {
	Stats []*SearchApplicationSessionStats `json:"stats,omitempty"`

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

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

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

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

type GetSearchApplicationUserStatsResponse struct {
	Stats []*SearchApplicationUserStats `json:"stats,omitempty"`

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

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

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

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

// HtmlOperatorOptions: Used to provide a search operator for html
// properties. This is optional. Search operators let users restrict the
// query to specific fields relevant to the type of item being searched.
type HtmlOperatorOptions struct {
	// OperatorName: Indicates the operator name required in the query in
	// order to isolate the html property. For example, if operatorName is
	// *subject* and the property's name is *subjectLine*, then queries like
	// *subject:<value>* show results only where the value of the property
	// named *subjectLine* matches *<value>*. By contrast, a search that
	// uses the same *<value>* without an operator return all items where
	// *<value>* matches the value of any html properties or text within the
	// content field for the item. The operator name can only contain
	// lowercase letters (a-z). The maximum length is 32 characters.
	OperatorName string `json:"operatorName,omitempty"`

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

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

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

// HtmlPropertyOptions: Options for html properties.
type HtmlPropertyOptions struct {
	// OperatorOptions: If set, describes how the property should be used as
	// a search operator.
	OperatorOptions *HtmlOperatorOptions `json:"operatorOptions,omitempty"`

	// RetrievalImportance: Indicates the search quality importance of the
	// tokens within the field when used for retrieval. Can only be set to
	// DEFAULT or NONE.
	RetrievalImportance *RetrievalImportance `json:"retrievalImportance,omitempty"`

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

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

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

// HtmlValues: List of html values.
type HtmlValues struct {
	// Values: The maximum allowable length for html values is 2048
	// characters.
	Values []string `json:"values,omitempty"`

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

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

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

type IndexItemOptions struct {
	// AllowUnknownGsuitePrincipals: Specifies if the index request should
	// allow gsuite principals that do not exist or are deleted in the index
	// request.
	AllowUnknownGsuitePrincipals bool `json:"allowUnknownGsuitePrincipals,omitempty"`

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

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

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

type IndexItemRequest struct {
	// ConnectorName: Name of connector making this call. Format:
	// datasources/{source_id}/connectors/{ID}
	ConnectorName string `json:"connectorName,omitempty"`

	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	IndexItemOptions *IndexItemOptions `json:"indexItemOptions,omitempty"`

	// Item: Name of the item. Format:
	// datasources/{source_id}/items/{item_id}
	Item *Item `json:"item,omitempty"`

	// Mode: Required. The RequestMode for this request.
	//
	// Possible values:
	//   "UNSPECIFIED" - Priority is not specified in the update request.
	// Leaving priority unspecified results in an update failure.
	//   "SYNCHRONOUS" - For real-time updates.
	//   "ASYNCHRONOUS" - For changes that are executed after the response
	// is sent back to the caller.
	Mode string `json:"mode,omitempty"`

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

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

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

// IntegerOperatorOptions: Used to provide a search operator for integer
// properties. This is optional. Search operators let users restrict the
// query to specific fields relevant to the type of item being searched.
type IntegerOperatorOptions struct {
	// GreaterThanOperatorName: Indicates the operator name required in the
	// query in order to isolate the integer property using the greater-than
	// operator. For example, if greaterThanOperatorName is *priorityabove*
	// and the property's name is *priorityVal*, then queries like
	// *priorityabove:<value>* show results only where the value of the
	// property named *priorityVal* is greater than *<value>*. The operator
	// name can only contain lowercase letters (a-z). The maximum length is
	// 32 characters.
	GreaterThanOperatorName string `json:"greaterThanOperatorName,omitempty"`

	// LessThanOperatorName: Indicates the operator name required in the
	// query in order to isolate the integer property using the less-than
	// operator. For example, if lessThanOperatorName is *prioritybelow* and
	// the property's name is *priorityVal*, then queries like
	// *prioritybelow:<value>* show results only where the value of the
	// property named *priorityVal* is less than *<value>*. The operator
	// name can only contain lowercase letters (a-z). The maximum length is
	// 32 characters.
	LessThanOperatorName string `json:"lessThanOperatorName,omitempty"`

	// OperatorName: Indicates the operator name required in the query in
	// order to isolate the integer property. For example, if operatorName
	// is *priority* and the property's name is *priorityVal*, then queries
	// like *priority:<value>* show results only where the value of the
	// property named *priorityVal* matches *<value>*. By contrast, a search
	// that uses the same *<value>* without an operator returns all items
	// where *<value>* matches the value of any String properties or text
	// within the content field for the item. The operator name can only
	// contain lowercase letters (a-z). The maximum length is 32 characters.
	OperatorName string `json:"operatorName,omitempty"`

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

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

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

// IntegerPropertyOptions: Options for integer properties.
type IntegerPropertyOptions struct {
	// MaximumValue: The maximum value of the property. The minimum and
	// maximum values for the property are used to rank results according to
	// the ordered ranking. Indexing requests with values greater than the
	// maximum are accepted and ranked with the same weight as items indexed
	// with the maximum value.
	MaximumValue int64 `json:"maximumValue,omitempty,string"`

	// MinimumValue: The minimum value of the property. The minimum and
	// maximum values for the property are used to rank results according to
	// the ordered ranking. Indexing requests with values less than the
	// minimum are accepted and ranked with the same weight as items indexed
	// with the minimum value.
	MinimumValue int64 `json:"minimumValue,omitempty,string"`

	// OperatorOptions: If set, describes how the integer should be used as
	// a search operator.
	OperatorOptions *IntegerOperatorOptions `json:"operatorOptions,omitempty"`

	// OrderedRanking: Used to specify the ordered ranking for the integer.
	// Can only be used if isRepeatable is false.
	//
	// Possible values:
	//   "NO_ORDER" - There is no ranking order for the property. Results
	// are not adjusted by this property's value.
	//   "ASCENDING" - This property is ranked in ascending order. Lower
	// values indicate lower ranking.
	//   "DESCENDING" - This property is ranked in descending order. Lower
	// values indicate higher ranking.
	OrderedRanking string `json:"orderedRanking,omitempty"`

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

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

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

// IntegerValues: List of integer values.
type IntegerValues struct {
	Values googleapi.Int64s `json:"values,omitempty"`

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

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

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

// Interaction: Represents an interaction between a user and an item.
type Interaction struct {
	// InteractionTime: The time when the user acted on the item. If
	// multiple actions of the same type exist for a single user, only the
	// most recent action is recorded.
	InteractionTime string `json:"interactionTime,omitempty"`

	// Principal: The user that acted on the item.
	Principal *Principal `json:"principal,omitempty"`

	// Possible values:
	//   "UNSPECIFIED" - Invalid value.
	//   "VIEW" - This interaction indicates the user viewed the item.
	//   "EDIT" - This interaction indicates the user edited the item.
	Type string `json:"type,omitempty"`

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

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

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

// Item: Represents a single object that is an item in the search index,
// such as a file, folder, or a database record.
type Item struct {
	// Acl: Access control list for this item.
	Acl *ItemAcl `json:"acl,omitempty"`

	// Content: Item content to be indexed and made text searchable.
	Content *ItemContent `json:"content,omitempty"`

	// ItemType: Type for this item.
	//
	// Possible values:
	//   "UNSPECIFIED"
	//   "CONTENT_ITEM" - An item that is indexed for the only purpose of
	// serving information. These items cannot be referred in containerName
	// or inheritAclFrom fields.
	//   "CONTAINER_ITEM" - An item that gets indexed and whose purpose is
	// to supply other items with ACLs and/or contain other items.
	//   "VIRTUAL_CONTAINER_ITEM" - An item that does not get indexed, but
	// otherwise has the same purpose as CONTAINER_ITEM.
	ItemType string `json:"itemType,omitempty"`

	// Metadata: Metadata information.
	Metadata *ItemMetadata `json:"metadata,omitempty"`

	// Name: Name of the Item. Format:
	// datasources/{source_id}/items/{item_id} This is a required field. The
	// maximum length is 1536 characters.
	Name string `json:"name,omitempty"`

	// Payload: Additional state connector can store for this item. The
	// maximum length is 10000 bytes.
	Payload string `json:"payload,omitempty"`

	// Queue: Queue this item belongs to. The maximum length is 100
	// characters.
	Queue string `json:"queue,omitempty"`

	// Status: Status of the item. Output only field.
	Status *ItemStatus `json:"status,omitempty"`

	// StructuredData: The structured data for the item that should conform
	// to a registered object definition in the schema for the data source.
	StructuredData *ItemStructuredData `json:"structuredData,omitempty"`

	// Version: Required. The indexing system stores the version from the
	// datasource as a byte string and compares the Item version in the
	// index to the version of the queued Item using lexical ordering. Cloud
	// Search Indexing won't index or delete any queued item with a version
	// value that is less than or equal to the version of the currently
	// indexed item. The maximum length for this field is 1024 bytes.
	Version string `json:"version,omitempty"`

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

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

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

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

// ItemAcl: Access control list information for the item. For more
// information see [Map ACLs](/cloud-search/docs/guides/acls).
type ItemAcl struct {
	// AclInheritanceType: Sets the type of access rules to apply when an
	// item inherits its ACL from a parent. This should always be set in
	// tandem with the inheritAclFrom field. Also, when the inheritAclFrom
	// field is set, this field should be set to a valid AclInheritanceType.
	//
	// Possible values:
	//   "NOT_APPLICABLE" - The default value when this item does not
	// inherit an ACL. Use NOT_APPLICABLE when inheritAclFrom is empty. An
	// item without ACL inheritance can still have ACLs supplied by its own
	// readers and deniedReaders fields.
	//   "CHILD_OVERRIDE" - During an authorization conflict, the ACL of the
	// child item determines its read access.
	//   "PARENT_OVERRIDE" - During an authorization conflict, the ACL of
	// the parent item specified in the inheritAclFrom field determines read
	// access.
	//   "BOTH_PERMIT" - Access is granted only if this item and the parent
	// item specified in the inheritAclFrom field both permit read access.
	AclInheritanceType string `json:"aclInheritanceType,omitempty"`

	// DeniedReaders: List of principals who are explicitly denied access to
	// the item in search results. While principals are denied access by
	// default, use denied readers to handle exceptions and override the
	// list allowed readers. The maximum number of elements is 100.
	DeniedReaders []*Principal `json:"deniedReaders,omitempty"`

	// InheritAclFrom: Name of the item to inherit the Access Permission
	// List (ACL) from. Note: ACL inheritance *only* provides access
	// permissions to child items and does not define structural
	// relationships, nor does it provide convenient ways to delete large
	// groups of items. Deleting an ACL parent from the index only alters
	// the access permissions of child items that reference the parent in
	// the inheritAclFrom field. The item is still in the index, but may not
	// visible in search results. By contrast, deletion of a container item
	// also deletes all items that reference the container via the
	// containerName field. The maximum length for this field is 1536
	// characters.
	InheritAclFrom string `json:"inheritAclFrom,omitempty"`

	// Owners: Optional. List of owners for the item. This field has no
	// bearing on document access permissions. It does, however, offer a
	// slight ranking boosts items where the querying user is an owner. The
	// maximum number of elements is 5.
	Owners []*Principal `json:"owners,omitempty"`

	// Readers: List of principals who are allowed to see the item in search
	// results. Optional if inheriting permissions from another item or if
	// the item is not intended to be visible, such as virtual containers.
	// The maximum number of elements is 1000.
	Readers []*Principal `json:"readers,omitempty"`

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

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

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

// ItemContent: Content of an item to be indexed and surfaced by Cloud
// Search.
type ItemContent struct {
	// ContentDataRef: Upload reference ID of a previously uploaded content
	// via write method.
	ContentDataRef *UploadItemRef `json:"contentDataRef,omitempty"`

	// Possible values:
	//   "UNSPECIFIED" - Invalid value.
	//   "HTML" - contentFormat is HTML.
	//   "TEXT" - contentFormat is free text.
	//   "RAW" - contentFormat is raw bytes.
	ContentFormat string `json:"contentFormat,omitempty"`

	// Hash: Hashing info calculated and provided by the API client for
	// content. Can be used with the items.push method to calculate modified
	// state. The maximum length is 2048 characters.
	Hash string `json:"hash,omitempty"`

	// InlineContent: Content that is supplied inlined within the update
	// method. The maximum length is 102400 bytes (100 KiB).
	InlineContent string `json:"inlineContent,omitempty"`

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

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

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

type ItemCountByStatus struct {
	// Count: Number of items matching the status code.
	Count int64 `json:"count,omitempty,string"`

	// StatusCode: Status of the items.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - Input-only value. Used with Items.list to list
	// all items in the queue, regardless of status.
	//   "ERROR" - Error encountered by Cloud Search while processing this
	// item. Details of the error are in repositoryError.
	//   "MODIFIED" - Item has been modified in the repository, and is out
	// of date with the version previously accepted into Cloud Search.
	//   "NEW_ITEM" - Item is known to exist in the repository, but is not
	// yet accepted by Cloud Search. An item can be in this state when
	// Items.push has been called for an item of this name that did not
	// exist previously.
	//   "ACCEPTED" - API has accepted the up-to-date data of this item.
	StatusCode string `json:"statusCode,omitempty"`

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

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

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

// ItemMetadata: Available metadata fields for the item.
type ItemMetadata struct {
	// ContainerName: The name of the container for this item. Deletion of
	// the container item leads to automatic deletion of this item. Note:
	// ACLs are not inherited from a container item. To provide ACL
	// inheritance for an item, use the inheritAclFrom field. The maximum
	// length is 1536 characters.
	ContainerName string `json:"containerName,omitempty"`

	// ContentLanguage: The BCP-47 language code for the item, such as
	// "en-US" or "sr-Latn". For more information, see
	// http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. The
	// maximum length is 32 characters.
	ContentLanguage string `json:"contentLanguage,omitempty"`

	// CreateTime: The time when the item was created in the source
	// repository.
	CreateTime string `json:"createTime,omitempty"`

	// Hash: Hashing value provided by the API caller. This can be used with
	// the items.push method to calculate modified state. The maximum length
	// is 2048 characters.
	Hash string `json:"hash,omitempty"`

	// Interactions: A list of interactions for the item. Interactions are
	// used to improve Search quality, but are not exposed to end users. The
	// maximum number of elements is 1000.
	Interactions []*Interaction `json:"interactions,omitempty"`

	// Keywords: Additional keywords or phrases that should match the item.
	// Used internally for user generated content. The maximum number of
	// elements is 100. The maximum length is 8192 characters.
	Keywords []string `json:"keywords,omitempty"`

	// MimeType: The original mime-type of ItemContent.content in the source
	// repository. The maximum length is 256 characters.
	MimeType string `json:"mimeType,omitempty"`

	// ObjectType: The type of the item. This should correspond to the name
	// of an object definition in the schema registered for the data source.
	// For example, if the schema for the data source contains an object
	// definition with name 'document', then item indexing requests for
	// objects of that type should set objectType to 'document'. The maximum
	// length is 256 characters.
	ObjectType string `json:"objectType,omitempty"`

	// SearchQualityMetadata: Additional search quality metadata of the item
	SearchQualityMetadata *SearchQualityMetadata `json:"searchQualityMetadata,omitempty"`

	// SourceRepositoryUrl: Link to the source repository serving the data.
	// Search results apply this link to the title. Whitespace or special
	// characters may cause Cloud Search result links to trigger a redirect
	// notice; to avoid this, encode the URL. The maximum length is 2048
	// characters.
	SourceRepositoryUrl string `json:"sourceRepositoryUrl,omitempty"`

	// Title: The title of the item. If given, this will be the displayed
	// title of the Search result. The maximum length is 2048 characters.
	Title string `json:"title,omitempty"`

	// UpdateTime: The time when the item was last modified in the source
	// repository.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

// ItemStatus: This contains item's status and any errors.
type ItemStatus struct {
	// Code: Status code.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - Input-only value. Used with Items.list to list
	// all items in the queue, regardless of status.
	//   "ERROR" - Error encountered by Cloud Search while processing this
	// item. Details of the error are in repositoryError.
	//   "MODIFIED" - Item has been modified in the repository, and is out
	// of date with the version previously accepted into Cloud Search.
	//   "NEW_ITEM" - Item is known to exist in the repository, but is not
	// yet accepted by Cloud Search. An item can be in this state when
	// Items.push has been called for an item of this name that did not
	// exist previously.
	//   "ACCEPTED" - API has accepted the up-to-date data of this item.
	Code string `json:"code,omitempty"`

	// ProcessingErrors: Error details in case the item is in ERROR state.
	ProcessingErrors []*ProcessingError `json:"processingErrors,omitempty"`

	// RepositoryErrors: Repository error reported by connector.
	RepositoryErrors []*RepositoryError `json:"repositoryErrors,omitempty"`

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

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

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

// ItemStructuredData: Available structured data fields for the item.
type ItemStructuredData struct {
	// Hash: Hashing value provided by the API caller. This can be used with
	// the items.push method to calculate modified state. The maximum length
	// is 2048 characters.
	Hash string `json:"hash,omitempty"`

	// Object: The structured data object that should conform to a
	// registered object definition in the schema for the data source.
	Object *StructuredDataObject `json:"object,omitempty"`

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

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

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

type ListDataSourceResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	Sources []*DataSource `json:"sources,omitempty"`

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

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

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

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

type ListItemNamesForUnmappedIdentityResponse struct {
	ItemNames []string `json:"itemNames,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

type ListItemsResponse struct {
	Items []*Item `json:"items,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// ListQuerySourcesResponse: List sources response.
type ListQuerySourcesResponse struct {
	NextPageToken string `json:"nextPageToken,omitempty"`

	Sources []*QuerySource `json:"sources,omitempty"`

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

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

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

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

type ListSearchApplicationsResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	SearchApplications []*SearchApplication `json:"searchApplications,omitempty"`

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

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

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

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

type ListUnmappedIdentitiesResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	UnmappedIdentities []*UnmappedIdentity `json:"unmappedIdentities,omitempty"`

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

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

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

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

// MatchRange: Matched range of a snippet [start, end).
type MatchRange struct {
	// End: End of the match in the snippet.
	End int64 `json:"end,omitempty"`

	// Start: Starting position of the match in the snippet.
	Start int64 `json:"start,omitempty"`

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

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

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

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

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

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

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

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

// Metadata: Metadata of a matched search result.
type Metadata struct {
	// CreateTime: The creation time for this document or object in the
	// search result.
	CreateTime string `json:"createTime,omitempty"`

	// DisplayOptions: Options that specify how to display a structured data
	// search result.
	DisplayOptions *ResultDisplayMetadata `json:"displayOptions,omitempty"`

	// Fields: Indexed fields in structured data, returned as a generic
	// named property.
	Fields []*NamedProperty `json:"fields,omitempty"`

	// MimeType: Mime type of the search result.
	MimeType string `json:"mimeType,omitempty"`

	// ObjectType: Object type of the search result.
	ObjectType string `json:"objectType,omitempty"`

	// Owner: Owner (usually creator) of the document or object of the
	// search result.
	Owner *Person `json:"owner,omitempty"`

	// Source: The named source for the result, such as Gmail.
	Source *Source `json:"source,omitempty"`

	// UpdateTime: The last modified date for the object in the search
	// result. If not set in the item, the value returned here is empty.
	// When `updateTime` is used for calculating freshness and is not set,
	// this value defaults to 2 years from the current time.
	UpdateTime string `json:"updateTime,omitempty"`

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

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

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

// Metaline: A metaline is a list of properties that are displayed along
// with the search result to provide context.
type Metaline struct {
	// Properties: The list of displayed properties for the metaline. The
	// maximum number of properties is 5.
	Properties []*DisplayedProperty `json:"properties,omitempty"`

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

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

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

// Name: A person's name.
type Name struct {
	// DisplayName: The read-only display name formatted according to the
	// locale specified by the viewer's account or the Accept-Language HTTP
	// header.
	DisplayName string `json:"displayName,omitempty"`

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

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

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

// NamedProperty: A typed name-value pair for structured data. The type
// of the value should be the same as the registered type for the `name`
// property in the object definition of `objectType`.
type NamedProperty struct {
	BooleanValue bool `json:"booleanValue,omitempty"`

	DateValues *DateValues `json:"dateValues,omitempty"`

	DoubleValues *DoubleValues `json:"doubleValues,omitempty"`

	EnumValues *EnumValues `json:"enumValues,omitempty"`

	HtmlValues *HtmlValues `json:"htmlValues,omitempty"`

	IntegerValues *IntegerValues `json:"integerValues,omitempty"`

	// Name: The name of the property. This name should correspond to the
	// name of the property that was registered for object definition in the
	// schema. The maximum allowable length for this property is 256
	// characters.
	Name string `json:"name,omitempty"`

	ObjectValues *ObjectValues `json:"objectValues,omitempty"`

	TextValues *TextValues `json:"textValues,omitempty"`

	TimestampValues *TimestampValues `json:"timestampValues,omitempty"`

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

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

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

// ObjectDefinition: The definition for an object within a data source.
type ObjectDefinition struct {
	// Name: Name for the object, which then defines its type. Item indexing
	// requests should set the objectType field equal to this value. For
	// example, if *name* is *Document*, then indexing requests for items of
	// type Document should set objectType equal to *Document*. Each object
	// definition must be uniquely named within a schema. The name must
	// start with a letter and can only contain letters (A-Z, a-z) or
	// numbers (0-9). The maximum length is 256 characters.
	Name string `json:"name,omitempty"`

	// Options: The optional object-specific options.
	Options *ObjectOptions `json:"options,omitempty"`

	// PropertyDefinitions: The property definitions for the object. The
	// maximum number of elements is 1000.
	PropertyDefinitions []*PropertyDefinition `json:"propertyDefinitions,omitempty"`

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

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

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

// ObjectDisplayOptions: The display options for an object.
type ObjectDisplayOptions struct {
	// Metalines: Defines the properties that are displayed in the metalines
	// of the search results. The property values are displayed in the order
	// given here. If a property holds multiple values, all of the values
	// are displayed before the next properties. For this reason, it is a
	// good practice to specify singular properties before repeated
	// properties in this list. All of the properties must set is_returnable
	// to true. The maximum number of metalines is 3.
	Metalines []*Metaline `json:"metalines,omitempty"`

	// ObjectDisplayLabel: The user friendly label to display in the search
	// result to indicate the type of the item. This is OPTIONAL; if not
	// provided, an object label isn't displayed on the context line of the
	// search results. The maximum length is 64 characters.
	ObjectDisplayLabel string `json:"objectDisplayLabel,omitempty"`

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

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

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

// ObjectOptions: The options for an object.
type ObjectOptions struct {
	// DisplayOptions: Options that determine how the object is displayed in
	// the Cloud Search results page.
	DisplayOptions *ObjectDisplayOptions `json:"displayOptions,omitempty"`

	// FreshnessOptions: The freshness options for an object.
	FreshnessOptions *FreshnessOptions `json:"freshnessOptions,omitempty"`

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

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

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

// ObjectPropertyOptions: Options for object properties.
type ObjectPropertyOptions struct {
	// SubobjectProperties: The properties of the sub-object. These
	// properties represent a nested object. For example, if this property
	// represents a postal address, the subobjectProperties might be named
	// *street*, *city*, and *state*. The maximum number of elements is
	// 1000.
	SubobjectProperties []*PropertyDefinition `json:"subobjectProperties,omitempty"`

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

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

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

// ObjectValues: List of object values.
type ObjectValues struct {
	Values []*StructuredDataObject `json:"values,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

// PeopleSuggestion: This field contains information about the person
// being suggested.
type PeopleSuggestion struct {
	// Person: Suggested person. All fields of the person object might not
	// be populated.
	Person *Person `json:"person,omitempty"`

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

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

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

// Person: Object to represent a person.
type Person struct {
	// EmailAddresses: The person's email addresses
	EmailAddresses []*EmailAddress `json:"emailAddresses,omitempty"`

	// Name: The resource name of the person to provide information about.
	// See People.get from Google People API.
	Name string `json:"name,omitempty"`

	// ObfuscatedId: Obfuscated ID of a person.
	ObfuscatedId string `json:"obfuscatedId,omitempty"`

	// PersonNames: The person's name
	PersonNames []*Name `json:"personNames,omitempty"`

	// Photos: A person's read-only photo. A picture shown next to the
	// person's name to help others recognize the person in search results.
	Photos []*Photo `json:"photos,omitempty"`

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

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

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

// Photo: A person's photo.
type Photo struct {
	// Url: The URL of the photo.
	Url string `json:"url,omitempty"`

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

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

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

type PollItemsRequest struct {
	// ConnectorName: Name of connector making this call. Format:
	// datasources/{source_id}/connectors/{ID}
	ConnectorName string `json:"connectorName,omitempty"`

	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	// Limit: Maximum number of items to return. The maximum value is 100
	// and the default value is 20.
	Limit int64 `json:"limit,omitempty"`

	// Queue: Queue name to fetch items from. If unspecified, PollItems will
	// fetch from 'default' queue. The maximum length is 100 characters.
	Queue string `json:"queue,omitempty"`

	// StatusCodes: Limit the items polled to the ones with these statuses.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - Input-only value. Used with Items.list to list
	// all items in the queue, regardless of status.
	//   "ERROR" - Error encountered by Cloud Search while processing this
	// item. Details of the error are in repositoryError.
	//   "MODIFIED" - Item has been modified in the repository, and is out
	// of date with the version previously accepted into Cloud Search.
	//   "NEW_ITEM" - Item is known to exist in the repository, but is not
	// yet accepted by Cloud Search. An item can be in this state when
	// Items.push has been called for an item of this name that did not
	// exist previously.
	//   "ACCEPTED" - API has accepted the up-to-date data of this item.
	StatusCodes []string `json:"statusCodes,omitempty"`

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

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

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

type PollItemsResponse struct {
	// Items: Set of items from the queue available for connector to
	// process. These items have the following subset of fields populated:
	// version metadata.hash structured_data.hash content.hash payload
	// status queue
	Items []*Item `json:"items,omitempty"`

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

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

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

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

// Principal: Reference to a user, group, or domain.
type Principal struct {
	// GroupResourceName: This principal is a group identified using an
	// external identity. The name field must specify the group resource
	// name with this format: identitysources/{source_id}/groups/{ID}
	GroupResourceName string `json:"groupResourceName,omitempty"`

	// GsuitePrincipal: This principal is a GSuite user, group or domain.
	GsuitePrincipal *GSuitePrincipal `json:"gsuitePrincipal,omitempty"`

	// UserResourceName: This principal is a user identified using an
	// external identity. The name field must specify the user resource name
	// with this format: identitysources/{source_id}/users/{ID}
	UserResourceName string `json:"userResourceName,omitempty"`

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

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

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

type ProcessingError struct {
	// Code: Error code indicating the nature of the error.
	//
	// Possible values:
	//   "PROCESSING_ERROR_CODE_UNSPECIFIED" - Input only value. Use this
	// value in Items.
	//   "MALFORMED_REQUEST" - Item's ACL, metadata, or content is malformed
	// or in invalid state. FieldViolations contains more details on where
	// the problem is.
	//   "UNSUPPORTED_CONTENT_FORMAT" - Countent format is unsupported.
	//   "INDIRECT_BROKEN_ACL" - Items with incomplete ACL information due
	// to inheriting other items with broken ACL or having groups with
	// unmapped descendants.
	//   "ACL_CYCLE" - ACL inheritance graph formed a cycle.
	Code string `json:"code,omitempty"`

	// ErrorMessage: Description of the error.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// FieldViolations: In case the item fields are invalid, this field
	// contains the details about the validation errors.
	FieldViolations []*FieldViolation `json:"fieldViolations,omitempty"`

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

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

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

// PropertyDefinition: The definition of a property within an object.
type PropertyDefinition struct {
	BooleanPropertyOptions *BooleanPropertyOptions `json:"booleanPropertyOptions,omitempty"`

	DatePropertyOptions *DatePropertyOptions `json:"datePropertyOptions,omitempty"`

	// DisplayOptions: Options that determine how the property is displayed
	// in the Cloud Search results page if it is specified to be displayed
	// in the object's display options .
	DisplayOptions *PropertyDisplayOptions `json:"displayOptions,omitempty"`

	DoublePropertyOptions *DoublePropertyOptions `json:"doublePropertyOptions,omitempty"`

	EnumPropertyOptions *EnumPropertyOptions `json:"enumPropertyOptions,omitempty"`

	HtmlPropertyOptions *HtmlPropertyOptions `json:"htmlPropertyOptions,omitempty"`

	IntegerPropertyOptions *IntegerPropertyOptions `json:"integerPropertyOptions,omitempty"`

	// IsFacetable: Indicates that the property can be used for generating
	// facets. Cannot be true for properties whose type is object.
	// IsReturnable must be true to set this option. Only supported for
	// Boolean, Enum, and Text properties.
	IsFacetable bool `json:"isFacetable,omitempty"`

	// IsRepeatable: Indicates that multiple values are allowed for the
	// property. For example, a document only has one description but can
	// have multiple comments. Cannot be true for properties whose type is a
	// boolean. If set to false, properties that contain more than one value
	// cause the indexing request for that item to be rejected.
	IsRepeatable bool `json:"isRepeatable,omitempty"`

	// IsReturnable: Indicates that the property identifies data that should
	// be returned in search results via the Query API. If set to *true*,
	// indicates that Query API users can use matching property fields in
	// results. However, storing fields requires more space allocation and
	// uses more bandwidth for search queries, which impacts performance
	// over large datasets. Set to *true* here only if the field is needed
	// for search results. Cannot be true for properties whose type is an
	// object.
	IsReturnable bool `json:"isReturnable,omitempty"`

	// IsSortable: Indicates that the property can be used for sorting.
	// Cannot be true for properties that are repeatable. Cannot be true for
	// properties whose type is object or user identifier. IsReturnable must
	// be true to set this option. Only supported for Boolean, Date, Double,
	// Integer, and Timestamp properties.
	IsSortable bool `json:"isSortable,omitempty"`

	// IsSuggestable: Indicates that the property can be used for generating
	// query suggestions.
	IsSuggestable bool `json:"isSuggestable,omitempty"`

	// IsWildcardSearchable: Indicates that users can perform wildcard
	// search for this property. Only supported for Text properties.
	// IsReturnable must be true to set this option. In a given datasource
	// maximum of 5 properties can be marked as is_wildcard_searchable.
	IsWildcardSearchable bool `json:"isWildcardSearchable,omitempty"`

	// Name: The name of the property. Item indexing requests sent to the
	// Indexing API should set the property name equal to this value. For
	// example, if name is *subject_line*, then indexing requests for
	// document items with subject fields should set the name for that field
	// equal to *subject_line*. Use the name as the identifier for the
	// object property. Once registered as a property for an object, you
	// cannot re-use this name for another property within that object. The
	// name must start with a letter and can only contain letters (A-Z, a-z)
	// or numbers (0-9). The maximum length is 256 characters.
	Name string `json:"name,omitempty"`

	ObjectPropertyOptions *ObjectPropertyOptions `json:"objectPropertyOptions,omitempty"`

	TextPropertyOptions *TextPropertyOptions `json:"textPropertyOptions,omitempty"`

	TimestampPropertyOptions *TimestampPropertyOptions `json:"timestampPropertyOptions,omitempty"`

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

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

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

// PropertyDisplayOptions: The display options for a property.
type PropertyDisplayOptions struct {
	// DisplayLabel: The user friendly label for the property that is used
	// if the property is specified to be displayed in ObjectDisplayOptions.
	// If provided, the display label is shown in front of the property
	// values when the property is part of the object display options. For
	// example, if the property value is '1', the value by itself may not be
	// useful context for the user. If the display name given was
	// 'priority', then the user sees 'priority : 1' in the search results
	// which provides clear context to search users. This is OPTIONAL; if
	// not given, only the property values are displayed. The maximum length
	// is 64 characters.
	DisplayLabel string `json:"displayLabel,omitempty"`

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

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

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

// PushItem: Represents an item to be pushed to the indexing queue.
type PushItem struct {
	// ContentHash: Content hash of the item according to the repository. If
	// specified, this is used to determine how to modify this item's
	// status. Setting this field and the type field results in argument
	// error. The maximum length is 2048 characters.
	ContentHash string `json:"contentHash,omitempty"`

	// MetadataHash: Metadata hash of the item according to the repository.
	// If specified, this is used to determine how to modify this item's
	// status. Setting this field and the type field results in argument
	// error. The maximum length is 2048 characters.
	MetadataHash string `json:"metadataHash,omitempty"`

	// Payload: Provides additional document state information for the
	// connector, such as an alternate repository ID and other metadata. The
	// maximum length is 8192 bytes.
	Payload string `json:"payload,omitempty"`

	// Queue: Queue to which this item belongs to. The default queue is
	// chosen if this field is not specified. The maximum length is 512
	// characters.
	Queue string `json:"queue,omitempty"`

	// RepositoryError: Populate this field to store Connector or repository
	// error details. This information is displayed in the Admin Console.
	// This field may only be populated when the Type is REPOSITORY_ERROR.
	RepositoryError *RepositoryError `json:"repositoryError,omitempty"`

	// StructuredDataHash: Structured data hash of the item according to the
	// repository. If specified, this is used to determine how to modify
	// this item's status. Setting this field and the type field results in
	// argument error. The maximum length is 2048 characters.
	StructuredDataHash string `json:"structuredDataHash,omitempty"`

	// Type: The type of the push operation that defines the push behavior.
	//
	// Possible values:
	//   "UNSPECIFIED" - Default UNSPECIFIED. Specifies that the push
	// operation should not modify ItemStatus
	//   "MODIFIED" - Indicates that the repository document has been
	// modified or updated since the previous update call. This changes
	// status to MODIFIED state for an existing item. If this is called on a
	// non existing item, the status is changed to NEW_ITEM.
	//   "NOT_MODIFIED" - Item in the repository has not been modified since
	// the last update call. This push operation will set status to ACCEPTED
	// state.
	//   "REPOSITORY_ERROR" - Connector is facing a repository error
	// regarding this item. Change status to REPOSITORY_ERROR state. Item is
	// unreserved and rescheduled at a future time determined by exponential
	// backoff.
	//   "REQUEUE" - Call push with REQUEUE only for items that have been
	// reserved. This action unreserves the item and resets its available
	// time to the wall clock time.
	Type string `json:"type,omitempty"`

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

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

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

type PushItemRequest struct {
	// ConnectorName: Name of connector making this call. Format:
	// datasources/{source_id}/connectors/{ID}
	ConnectorName string `json:"connectorName,omitempty"`

	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	// Item: Item to push onto the queue.
	Item *PushItem `json:"item,omitempty"`

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

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

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

type QueryCountByStatus struct {
	Count int64 `json:"count,omitempty,string"`

	// StatusCode: This represents the http status code.
	StatusCode int64 `json:"statusCode,omitempty"`

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

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

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

type QueryInterpretation struct {
	// Possible values:
	//   "NONE" - Neither the natural language interpretation, nor a broader
	// version of the query is used to fetch the search results.
	//   "BLEND" - The results from original query are blended with other
	// results. The reason for blending these other results with the results
	// from original query is populated in the 'Reason' field below.
	//   "REPLACE" - The results from original query are replaced. The
	// reason for replacing the results from original query is populated in
	// the 'Reason' field below.
	InterpretationType string `json:"interpretationType,omitempty"`

	// InterpretedQuery: The interpretation of the query used in search. For
	// example, queries with natural language intent like "email from john"
	// will be interpreted as "from:john source:mail". This field will not
	// be filled when the reason is NOT_ENOUGH_RESULTS_FOUND_FOR_USER_QUERY.
	InterpretedQuery string `json:"interpretedQuery,omitempty"`

	// Reason: The reason for interpretation of the query. This field will
	// not be UNSPECIFIED if the interpretation type is not NONE.
	//
	// Possible values:
	//   "UNSPECIFIED"
	//   "QUERY_HAS_NATURAL_LANGUAGE_INTENT" - Natural language
	// interpretation of the query is used to fetch the search results.
	//   "NOT_ENOUGH_RESULTS_FOUND_FOR_USER_QUERY" - Query and document
	// terms similarity is used to selectively broaden the query to retrieve
	// additional search results since enough results were not found for the
	// user query. Interpreted query will be empty for this case.
	Reason string `json:"reason,omitempty"`

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

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

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

// QueryInterpretationOptions: Options to interpret user query.
type QueryInterpretationOptions struct {
	// DisableNlInterpretation: Flag to disable natural language (NL)
	// interpretation of queries. Default is false, Set to true to disable
	// natural language interpretation. NL interpretation only applies to
	// predefined datasources.
	DisableNlInterpretation bool `json:"disableNlInterpretation,omitempty"`

	// EnableVerbatimMode: Enable this flag to turn off all internal
	// optimizations like natural language (NL) interpretation of queries,
	// supplemental result retrieval, and usage of synonyms including custom
	// ones. Nl interpretation will be disabled if either one of the two
	// flags is true.
	EnableVerbatimMode bool `json:"enableVerbatimMode,omitempty"`

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

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

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

// QueryItem: Information relevant only to a query entry.
type QueryItem struct {
	// IsSynthetic: True if the text was generated by means other than a
	// previous user search.
	IsSynthetic bool `json:"isSynthetic,omitempty"`

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

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

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

// QueryOperator: The definition of a operator that can be used in a
// Search/Suggest request.
type QueryOperator struct {
	// DisplayName: Display name of the operator
	DisplayName string `json:"displayName,omitempty"`

	// EnumValues: Potential list of values for the opeatror field. This
	// field is only filled when we can safely enumerate all the possible
	// values of this operator.
	EnumValues []string `json:"enumValues,omitempty"`

	// GreaterThanOperatorName: Indicates the operator name that can be used
	// to isolate the property using the greater-than operator.
	GreaterThanOperatorName string `json:"greaterThanOperatorName,omitempty"`

	// IsFacetable: Can this operator be used to get facets.
	IsFacetable bool `json:"isFacetable,omitempty"`

	// IsRepeatable: Indicates if multiple values can be set for this
	// property.
	IsRepeatable bool `json:"isRepeatable,omitempty"`

	// IsReturnable: Will the property associated with this facet be
	// returned as part of search results.
	IsReturnable bool `json:"isReturnable,omitempty"`

	// IsSortable: Can this operator be used to sort results.
	IsSortable bool `json:"isSortable,omitempty"`

	// IsSuggestable: Can get suggestions for this field.
	IsSuggestable bool `json:"isSuggestable,omitempty"`

	// LessThanOperatorName: Indicates the operator name that can be used to
	// isolate the property using the less-than operator.
	LessThanOperatorName string `json:"lessThanOperatorName,omitempty"`

	// ObjectType: Name of the object corresponding to the operator. This
	// field is only filled for schema-specific operators, and is unset for
	// common operators.
	ObjectType string `json:"objectType,omitempty"`

	// OperatorName: The name of the operator.
	OperatorName string `json:"operatorName,omitempty"`

	// Type: Type of the operator.
	//
	// Possible values:
	//   "UNKNOWN" - Invalid value.
	//   "INTEGER"
	//   "DOUBLE"
	//   "TIMESTAMP"
	//   "BOOLEAN"
	//   "ENUM"
	//   "DATE"
	//   "TEXT"
	//   "HTML"
	Type string `json:"type,omitempty"`

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

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

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

// QuerySource: List of sources that the user can search using the query
// API.
type QuerySource struct {
	// DisplayName: Display name of the data source.
	DisplayName string `json:"displayName,omitempty"`

	// Operators: List of all operators applicable for this source.
	Operators []*QueryOperator `json:"operators,omitempty"`

	// ShortName: A short name or alias for the source. This value can be
	// used with the 'source' operator.
	ShortName string `json:"shortName,omitempty"`

	// Source: Name of the source
	Source *Source `json:"source,omitempty"`

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

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

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

// QuerySuggestion: This field does not contain anything as of now and
// is just used as an indicator that the suggest result was a phrase
// completion.
type QuerySuggestion struct {
}

// RepositoryError: Errors when the connector is communicating to the
// source repository.
type RepositoryError struct {
	// ErrorMessage: Message that describes the error. The maximum allowable
	// length of the message is 8192 characters.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// HttpStatusCode: Error codes. Matches the definition of HTTP status
	// codes.
	HttpStatusCode int64 `json:"httpStatusCode,omitempty"`

	// Type: Type of error.
	//
	// Possible values:
	//   "UNKNOWN" - Unknown error.
	//   "NETWORK_ERROR" - Unknown or unreachable host.
	//   "DNS_ERROR" - DNS problem, such as the DNS server is not
	// responding.
	//   "CONNECTION_ERROR" - Cannot connect to the repository server.
	//   "AUTHENTICATION_ERROR" - Failed authentication due to incorrect
	// credentials.
	//   "AUTHORIZATION_ERROR" - Service account is not authorized for the
	// repository.
	//   "SERVER_ERROR" - Repository server error.
	//   "QUOTA_EXCEEDED" - Quota exceeded.
	//   "SERVICE_UNAVAILABLE" - Server temporarily unavailable.
	//   "CLIENT_ERROR" - Client-related error, such as an invalid request
	// from the connector to the repository server.
	Type string `json:"type,omitempty"`

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

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

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

// RequestOptions: Shared request options for all RPC methods.
type RequestOptions struct {
	// DebugOptions: Debug options of the request
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	// LanguageCode: The BCP-47 language code, such as "en-US" or "sr-Latn".
	// For more information, see
	// http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. For
	// translations. Set this field using the language set in browser or for
	// the page. In the event that the user's language preference is known,
	// set this field to the known user language. When specified, the
	// documents in search results are biased towards the specified
	// language. The suggest API does not use this parameter. Instead,
	// suggest autocompletes only based on characters in the query.
	LanguageCode string `json:"languageCode,omitempty"`

	// SearchApplicationId: The ID generated when you create a search
	// application using the [admin
	// console](https://support.google.com/a/answer/9043922).
	SearchApplicationId string `json:"searchApplicationId,omitempty"`

	// TimeZone: Current user's time zone id, such as "America/Los_Angeles"
	// or "Australia/Sydney". These IDs are defined by [Unicode Common
	// Locale Data Repository (CLDR)](http://cldr.unicode.org/) project, and
	// currently available in the file
	// [timezone.xml](http://unicode.org/repos/cldr/trunk/common/bcp47/timezo
	// ne.xml). This field is used to correctly interpret date and time
	// queries. If this field is not specified, the default time zone (UTC)
	// is used.
	TimeZone string `json:"timeZone,omitempty"`

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

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

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

type ResetSearchApplicationRequest struct {
	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

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

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

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

// ResponseDebugInfo: Debugging information about the response.
type ResponseDebugInfo struct {
	// FormattedDebugInfo: General debug info formatted for display.
	FormattedDebugInfo string `json:"formattedDebugInfo,omitempty"`

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

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

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

// RestrictItem: Information relevant only to a restrict entry. NextId:
// 12
type RestrictItem struct {
	// DriveFollowUpRestrict:
	// LINT.ThenChange(//depot/google3/java/com/google/apps/search/quality/it
	// emsuggest/utils/SubtypeRerankingUtils.java)
	DriveFollowUpRestrict *DriveFollowUpRestrict `json:"driveFollowUpRestrict,omitempty"`

	DriveLocationRestrict *DriveLocationRestrict `json:"driveLocationRestrict,omitempty"`

	// DriveMimeTypeRestrict: LINT.IfChange Drive Types.
	DriveMimeTypeRestrict *DriveMimeTypeRestrict `json:"driveMimeTypeRestrict,omitempty"`

	DriveTimeSpanRestrict *DriveTimeSpanRestrict `json:"driveTimeSpanRestrict,omitempty"`

	// SearchOperator: The search restrict (e.g. "after:2017-09-11
	// before:2017-09-12").
	SearchOperator string `json:"searchOperator,omitempty"`

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

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

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

// ResultCounts: Result count information
type ResultCounts struct {
	// SourceResultCounts: Result count information for each source with
	// results.
	SourceResultCounts []*SourceResultCount `json:"sourceResultCounts,omitempty"`

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

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

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

// ResultDebugInfo: Debugging information about the result.
type ResultDebugInfo struct {
	// FormattedDebugInfo: General debug info formatted for display.
	FormattedDebugInfo string `json:"formattedDebugInfo,omitempty"`

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

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

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

// ResultDisplayField: Display Fields for Search Results
type ResultDisplayField struct {
	// Label: The display label for the property.
	Label string `json:"label,omitempty"`

	// OperatorName: The operator name of the property.
	OperatorName string `json:"operatorName,omitempty"`

	// Property: The name value pair for the property.
	Property *NamedProperty `json:"property,omitempty"`

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

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

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

// ResultDisplayLine: The collection of fields that make up a displayed
// line
type ResultDisplayLine struct {
	Fields []*ResultDisplayField `json:"fields,omitempty"`

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

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

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

type ResultDisplayMetadata struct {
	// Metalines: The metalines content to be displayed with the result.
	Metalines []*ResultDisplayLine `json:"metalines,omitempty"`

	// ObjectTypeLabel: The display label for the object.
	ObjectTypeLabel string `json:"objectTypeLabel,omitempty"`

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

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

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

type RetrievalImportance struct {
	// Importance: Indicates the ranking importance given to property when
	// it is matched during retrieval. Once set, the token importance of a
	// property cannot be changed.
	//
	// Possible values:
	//   "DEFAULT" - Treat the match like a body text match.
	//   "HIGHEST" - Treat the match like a match against title of the item.
	//   "HIGH" - Treat the match with higher importance than body text.
	//   "LOW" - Treat the match with lower importance than body text.
	//   "NONE" - Do not match against this field during retrieval. The
	// property can still be used for operator matching, faceting, and
	// suggest if desired.
	Importance string `json:"importance,omitempty"`

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

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

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

// Schema: The schema definition for a data source.
type Schema struct {
	// ObjectDefinitions: The list of top-level objects for the data source.
	// The maximum number of elements is 10.
	ObjectDefinitions []*ObjectDefinition `json:"objectDefinitions,omitempty"`

	// OperationIds: IDs of the Long Running Operations (LROs) currently
	// running for this schema. After modifying the schema, wait for
	// operations to complete before indexing additional content.
	OperationIds []string `json:"operationIds,omitempty"`

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

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

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

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

// ScoringConfig: Scoring configurations for a source while processing a
// Search or Suggest request.
type ScoringConfig struct {
	// DisableFreshness: Whether to use freshness as a ranking signal. By
	// default, freshness is used as a ranking signal. Note that this
	// setting is not available in the Admin UI.
	DisableFreshness bool `json:"disableFreshness,omitempty"`

	// DisablePersonalization: Whether to personalize the results. By
	// default, personal signals will be used to boost results.
	DisablePersonalization bool `json:"disablePersonalization,omitempty"`

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

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

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

// SearchApplication: SearchApplication
type SearchApplication struct {
	// DataSourceRestrictions: Retrictions applied to the configurations.
	// The maximum number of elements is 10.
	DataSourceRestrictions []*DataSourceRestriction `json:"dataSourceRestrictions,omitempty"`

	// DefaultFacetOptions: The default fields for returning facet results.
	// The sources specified here also have been included in
	// data_source_restrictions above.
	DefaultFacetOptions []*FacetOptions `json:"defaultFacetOptions,omitempty"`

	// DefaultSortOptions: The default options for sorting the search
	// results
	DefaultSortOptions *SortOptions `json:"defaultSortOptions,omitempty"`

	// DisplayName: Display name of the Search Application. The maximum
	// length is 300 characters.
	DisplayName string `json:"displayName,omitempty"`

	// Name: Name of the Search Application. Format:
	// searchapplications/{application_id}.
	Name string `json:"name,omitempty"`

	// OperationIds: Output only. IDs of the Long Running Operations (LROs)
	// currently running for this schema. Output only field.
	OperationIds []string `json:"operationIds,omitempty"`

	// ScoringConfig: Configuration for ranking results.
	ScoringConfig *ScoringConfig `json:"scoringConfig,omitempty"`

	// SourceConfig: Configuration for a sources specified in
	// data_source_restrictions.
	SourceConfig []*SourceConfig `json:"sourceConfig,omitempty"`

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

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

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

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

type SearchApplicationQueryStats struct {
	// Date: Date for which query stats were calculated. Stats calculated on
	// the next day close to midnight are returned.
	Date *Date `json:"date,omitempty"`

	QueryCountByStatus []*QueryCountByStatus `json:"queryCountByStatus,omitempty"`

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

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

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

type SearchApplicationSessionStats struct {
	// Date: Date for which session stats were calculated. Stats calculated
	// on the next day close to midnight are returned.
	Date *Date `json:"date,omitempty"`

	// SearchSessionsCount: The count of search sessions on the day
	SearchSessionsCount int64 `json:"searchSessionsCount,omitempty,string"`

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

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

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

type SearchApplicationUserStats struct {
	// Date: Date for which session stats were calculated. Stats calculated
	// on the next day close to midnight are returned.
	Date *Date `json:"date,omitempty"`

	// OneDayActiveUsersCount: The count of unique active users in the past
	// one day
	OneDayActiveUsersCount int64 `json:"oneDayActiveUsersCount,omitempty,string"`

	// SevenDaysActiveUsersCount: The count of unique active users in the
	// past seven days
	SevenDaysActiveUsersCount int64 `json:"sevenDaysActiveUsersCount,omitempty,string"`

	// ThirtyDaysActiveUsersCount: The count of unique active users in the
	// past thirty days
	ThirtyDaysActiveUsersCount int64 `json:"thirtyDaysActiveUsersCount,omitempty,string"`

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

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

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

type SearchItemsByViewUrlRequest struct {
	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	// PageToken: The next_page_token value returned from a previous
	// request, if any.
	PageToken string `json:"pageToken,omitempty"`

	// ViewUrl: Specify the full view URL to find the corresponding item.
	// The maximum length is 2048 characters.
	ViewUrl string `json:"viewUrl,omitempty"`

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

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

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

type SearchItemsByViewUrlResponse struct {
	Items []*Item `json:"items,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// SearchQualityMetadata: Additional search quality metadata of the
// item.
type SearchQualityMetadata struct {
	// Quality: An indication of the quality of the item, used to influence
	// search quality. Value should be between 0.0 (lowest quality) and 1.0
	// (highest quality). The default value is 0.0.
	Quality float64 `json:"quality,omitempty"`

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

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

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

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

// SearchRequest: The search API request.
type SearchRequest struct {
	// DataSourceRestrictions: The sources to use for querying. If not
	// specified, all data sources from the current search application are
	// used.
	DataSourceRestrictions []*DataSourceRestriction `json:"dataSourceRestrictions,omitempty"`

	FacetOptions []*FacetOptions `json:"facetOptions,omitempty"`

	// PageSize: Maximum number of search results to return in one page.
	// Valid values are between 1 and 100, inclusive. Default value is 10.
	PageSize int64 `json:"pageSize,omitempty"`

	// Query: The raw query string. See supported search operators in the
	// [Cloud search Cheat
	// Sheet](https://support.google.com/a/users/answer/9299929)
	Query string `json:"query,omitempty"`

	// QueryInterpretationOptions: Options to interpret the user query.
	QueryInterpretationOptions *QueryInterpretationOptions `json:"queryInterpretationOptions,omitempty"`

	// RequestOptions: Request options, such as the search application and
	// user timezone.
	RequestOptions *RequestOptions `json:"requestOptions,omitempty"`

	// SortOptions: The options for sorting the search results
	SortOptions *SortOptions `json:"sortOptions,omitempty"`

	// Start: Starting index of the results.
	Start int64 `json:"start,omitempty"`

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

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

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

// SearchResponse: The search API response.
type SearchResponse struct {
	// DebugInfo: Debugging information about the response.
	DebugInfo *ResponseDebugInfo `json:"debugInfo,omitempty"`

	// ErrorInfo: Error information about the response.
	ErrorInfo *ErrorInfo `json:"errorInfo,omitempty"`

	// FacetResults: Repeated facet results.
	FacetResults []*FacetResult `json:"facetResults,omitempty"`

	// HasMoreResults: Whether there are more search results matching the
	// query.
	HasMoreResults bool `json:"hasMoreResults,omitempty"`

	// QueryInterpretation: Query interpretation result for user query.
	// Empty if query interpretation is disabled.
	QueryInterpretation *QueryInterpretation `json:"queryInterpretation,omitempty"`

	// ResultCountEstimate: The estimated result count for this query.
	ResultCountEstimate int64 `json:"resultCountEstimate,omitempty,string"`

	// ResultCountExact: The exact result count for this query.
	ResultCountExact int64 `json:"resultCountExact,omitempty,string"`

	// ResultCounts: Expanded result count information.
	ResultCounts *ResultCounts `json:"resultCounts,omitempty"`

	// Results: Results from a search query.
	Results []*SearchResult `json:"results,omitempty"`

	// SpellResults: Suggested spelling for the query.
	SpellResults []*SpellResult `json:"spellResults,omitempty"`

	// StructuredResults: Structured results for the user query. These
	// results are not counted against the page_size.
	StructuredResults []*StructuredResult `json:"structuredResults,omitempty"`

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

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

// SearchResult: Results containing indexed information for a document.
type SearchResult struct {
	// ClusteredResults: If source is clustered, provide list of clustered
	// results. There will only be one level of clustered results. If
	// current source is not enabled for clustering, this field will be
	// empty.
	ClusteredResults []*SearchResult `json:"clusteredResults,omitempty"`

	// DebugInfo: Debugging information about this search result.
	DebugInfo *ResultDebugInfo `json:"debugInfo,omitempty"`

	// Metadata: Metadata of the search result.
	Metadata *Metadata `json:"metadata,omitempty"`

	// Snippet: The concatenation of all snippets (summaries) available for
	// this result.
	Snippet *Snippet `json:"snippet,omitempty"`

	// Title: Title of the search result.
	Title string `json:"title,omitempty"`

	// Url: The URL of the search result. The URL contains a Google redirect
	// to the actual item. This URL is signed and shouldn't be changed.
	Url string `json:"url,omitempty"`

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

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

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

// Snippet: Snippet of the search result, which summarizes the content
// of the resulting page.
type Snippet struct {
	// MatchRanges: The matched ranges in the snippet.
	MatchRanges []*MatchRange `json:"matchRanges,omitempty"`

	// Snippet: The snippet of the document. The snippet of the document.
	// May contain escaped HTML character that should be unescaped prior to
	// rendering.
	Snippet string `json:"snippet,omitempty"`

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

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

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

type SortOptions struct {
	// OperatorName: Name of the operator corresponding to the field to sort
	// on. The corresponding property must be marked as sortable.
	OperatorName string `json:"operatorName,omitempty"`

	// SortOrder: Ascending is the default sort order
	//
	// Possible values:
	//   "ASCENDING"
	//   "DESCENDING"
	SortOrder string `json:"sortOrder,omitempty"`

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

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

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

// Source: Defines sources for the suggest/search APIs.
type Source struct {
	// Name: Source name for content indexed by the Indexing API.
	Name string `json:"name,omitempty"`

	// PredefinedSource: Predefined content source for Google Apps.
	//
	// Possible values:
	//   "NONE"
	//   "QUERY_HISTORY" - Suggests queries issued by the user in the past.
	// Only valid when used with the suggest API. Ignored when used in the
	// query API.
	//   "PERSON" - Suggests people in the organization. Only valid when
	// used with the suggest API. Results in an error when used in the query
	// API.
	//   "GOOGLE_DRIVE"
	//   "GOOGLE_GMAIL"
	//   "GOOGLE_SITES"
	//   "GOOGLE_GROUPS"
	//   "GOOGLE_CALENDAR"
	//   "GOOGLE_KEEP"
	PredefinedSource string `json:"predefinedSource,omitempty"`

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

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

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

// SourceConfig: Configurations for a source while processing a Search
// or Suggest request.
type SourceConfig struct {
	// CrowdingConfig: The crowding configuration for the source.
	CrowdingConfig *SourceCrowdingConfig `json:"crowdingConfig,omitempty"`

	// ScoringConfig: The scoring configuration for the source.
	ScoringConfig *SourceScoringConfig `json:"scoringConfig,omitempty"`

	// Source: The source for which this configuration is to be used.
	Source *Source `json:"source,omitempty"`

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

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

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

// SourceCrowdingConfig: Set search results crowding limits. Crowding is
// a situation in which multiple results from the same source or host
// "crowd out" other results, diminishing the quality of search for
// users. To foster better search quality and source diversity in search
// results, you can set a condition to reduce repetitive results by
// source.
type SourceCrowdingConfig struct {
	// NumResults: Maximum number of results allowed from a source. No
	// limits will be set on results if this value is less than or equal to
	// 0.
	NumResults int64 `json:"numResults,omitempty"`

	// NumSuggestions: Maximum number of suggestions allowed from a source.
	// No limits will be set on results if this value is less than or equal
	// to 0.
	NumSuggestions int64 `json:"numSuggestions,omitempty"`

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

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

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

// SourceResultCount: Per source result count information.
type SourceResultCount struct {
	// HasMoreResults: Whether there are more search results for this
	// source.
	HasMoreResults bool `json:"hasMoreResults,omitempty"`

	// ResultCountEstimate: The estimated result count for this source.
	ResultCountEstimate int64 `json:"resultCountEstimate,omitempty,string"`

	// ResultCountExact: The exact result count for this source.
	ResultCountExact int64 `json:"resultCountExact,omitempty,string"`

	// Source: The source the result count information is associated with.
	Source *Source `json:"source,omitempty"`

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

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

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

// SourceScoringConfig: Set the scoring configuration. This allows
// modifying the ranking of results for a source.
type SourceScoringConfig struct {
	// SourceImportance: Importance of the source.
	//
	// Possible values:
	//   "DEFAULT"
	//   "LOW"
	//   "HIGH"
	SourceImportance string `json:"sourceImportance,omitempty"`

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

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

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

type SpellResult struct {
	// SuggestedQuery: The suggested spelling of the query.
	SuggestedQuery string `json:"suggestedQuery,omitempty"`

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

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

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

// StartUploadItemRequest: Start upload file request.
type StartUploadItemRequest struct {
	// ConnectorName: Name of connector making this call. Format:
	// datasources/{source_id}/connectors/{ID}
	ConnectorName string `json:"connectorName,omitempty"`

	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

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

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

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

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

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

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

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

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

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

// StructuredDataObject: A structured data object consisting of named
// properties.
type StructuredDataObject struct {
	// Properties: The properties for the object. The maximum number of
	// elements is 1000.
	Properties []*NamedProperty `json:"properties,omitempty"`

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

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

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

// StructuredResult: Structured results that are returned as part of
// search request.
type StructuredResult struct {
	// Person: Representation of a person
	Person *Person `json:"person,omitempty"`

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

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

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

// SuggestRequest: Request of suggest API.
type SuggestRequest struct {
	// DataSourceRestrictions: The sources to use for suggestions. If not
	// specified, the data sources are taken from the current search
	// application. NOTE: Suggestions are supported only for third party
	// data sources and people (i.e. PredefinedSource.PERSON).
	DataSourceRestrictions []*DataSourceRestriction `json:"dataSourceRestrictions,omitempty"`

	// Query: Partial query for which autocomplete suggestions will be
	// shown. For example, if the query is "sea", then the server might
	// return "season", "search", "seagull" and so on.
	Query string `json:"query,omitempty"`

	// RequestOptions: Request options, such as the search application and
	// user timezone.
	RequestOptions *RequestOptions `json:"requestOptions,omitempty"`

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

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

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

// SuggestResponse: Response of the suggest API.
type SuggestResponse struct {
	// SuggestResults: List of suggestions.
	SuggestResults []*SuggestResult `json:"suggestResults,omitempty"`

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

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

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

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

// SuggestResult: One suggestion result.
type SuggestResult struct {
	// PeopleSuggestion: This is present when the suggestion indicates a
	// person. It contains more information about the person - like their
	// email ID, name etc.
	PeopleSuggestion *PeopleSuggestion `json:"peopleSuggestion,omitempty"`

	// QuerySuggestion: This field will be present if the suggested query is
	// a word/phrase completion.
	QuerySuggestion *QuerySuggestion `json:"querySuggestion,omitempty"`

	// Source: The source of the suggestion.
	Source *Source `json:"source,omitempty"`

	// SuggestedQuery: The suggested query that will be used for search,
	// when the user clicks on the suggestion
	SuggestedQuery string `json:"suggestedQuery,omitempty"`

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

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

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

// TextOperatorOptions: Used to provide a search operator for text
// properties. This is optional. Search operators let users restrict the
// query to specific fields relevant to the type of item being searched.
type TextOperatorOptions struct {
	// ExactMatchWithOperator: If true, the text value is tokenized as one
	// atomic value in operator searches and facet matches. For example, if
	// the operator name is "genre" and the value is "science-fiction" the
	// query restrictions "genre:science" and "genre:fiction" doesn't match
	// the item; "genre:science-fiction" does. Value matching is
	// case-sensitive and does not remove special characters. If false, the
	// text is tokenized. For example, if the value is "science-fiction" the
	// queries "genre:science" and "genre:fiction" matches the item.
	ExactMatchWithOperator bool `json:"exactMatchWithOperator,omitempty"`

	// OperatorName: Indicates the operator name required in the query in
	// order to isolate the text property. For example, if operatorName is
	// *subject* and the property's name is *subjectLine*, then queries like
	// *subject:<value>* show results only where the value of the property
	// named *subjectLine* matches *<value>*. By contrast, a search that
	// uses the same *<value>* without an operator returns all items where
	// *<value>* matches the value of any text properties or text within the
	// content field for the item. The operator name can only contain
	// lowercase letters (a-z). The maximum length is 32 characters.
	OperatorName string `json:"operatorName,omitempty"`

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

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

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

// TextPropertyOptions: Options for text properties.
type TextPropertyOptions struct {
	// OperatorOptions: If set, describes how the property should be used as
	// a search operator.
	OperatorOptions *TextOperatorOptions `json:"operatorOptions,omitempty"`

	// RetrievalImportance: Indicates the search quality importance of the
	// tokens within the field when used for retrieval.
	RetrievalImportance *RetrievalImportance `json:"retrievalImportance,omitempty"`

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

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

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

// TextValues: List of text values.
type TextValues struct {
	// Values: The maximum allowable length for text values is 2048
	// characters.
	Values []string `json:"values,omitempty"`

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

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

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

// TimestampOperatorOptions: Used to provide a search operator for
// timestamp properties. This is optional. Search operators let users
// restrict the query to specific fields relevant to the type of item
// being searched.
type TimestampOperatorOptions struct {
	// GreaterThanOperatorName: Indicates the operator name required in the
	// query in order to isolate the timestamp property using the
	// greater-than operator. For example, if greaterThanOperatorName is
	// *closedafter* and the property's name is *closeDate*, then queries
	// like *closedafter:<value>* show results only where the value of the
	// property named *closeDate* is later than *<value>*. The operator name
	// can only contain lowercase letters (a-z). The maximum length is 32
	// characters.
	GreaterThanOperatorName string `json:"greaterThanOperatorName,omitempty"`

	// LessThanOperatorName: Indicates the operator name required in the
	// query in order to isolate the timestamp property using the less-than
	// operator. For example, if lessThanOperatorName is *closedbefore* and
	// the property's name is *closeDate*, then queries like
	// *closedbefore:<value>* show results only where the value of the
	// property named *closeDate* is earlier than *<value>*. The operator
	// name can only contain lowercase letters (a-z). The maximum length is
	// 32 characters.
	LessThanOperatorName string `json:"lessThanOperatorName,omitempty"`

	// OperatorName: Indicates the operator name required in the query in
	// order to isolate the timestamp property. For example, if operatorName
	// is *closedon* and the property's name is *closeDate*, then queries
	// like *closedon:<value>* show results only where the value of the
	// property named *closeDate* matches *<value>*. By contrast, a search
	// that uses the same *<value>* without an operator returns all items
	// where *<value>* matches the value of any String properties or text
	// within the content field for the item. The operator name can only
	// contain lowercase letters (a-z). The maximum length is 32 characters.
	OperatorName string `json:"operatorName,omitempty"`

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

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

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

// TimestampPropertyOptions: Options for timestamp properties.
type TimestampPropertyOptions struct {
	// OperatorOptions: If set, describes how the timestamp should be used
	// as a search operator.
	OperatorOptions *TimestampOperatorOptions `json:"operatorOptions,omitempty"`

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

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

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

// TimestampValues: List of timestamp values.
type TimestampValues struct {
	Values []string `json:"values,omitempty"`

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

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

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

type UnmappedIdentity struct {
	// ExternalIdentity: The resource name for an external user.
	ExternalIdentity *Principal `json:"externalIdentity,omitempty"`

	// ResolutionStatusCode: The resolution status for the external
	// identity.
	//
	// Possible values:
	//   "CODE_UNSPECIFIED" - Input-only value. Used to list all unmapped
	// identities regardless of status.
	//   "NOT_FOUND" - The unmapped identity was not found in IDaaS, and
	// needs to be provided by the user.
	//   "IDENTITY_SOURCE_NOT_FOUND" - The identity source associated with
	// the identity was either not found or deleted.
	//   "IDENTITY_SOURCE_MISCONFIGURED" - IDaaS does not understand the
	// identity source, probably because the schema was modified in a non
	// compatible way.
	//   "TOO_MANY_MAPPINGS_FOUND" - The number of users associated with the
	// external identity is too large.
	//   "INTERNAL_ERROR" - Internal error.
	ResolutionStatusCode string `json:"resolutionStatusCode,omitempty"`

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

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

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

type UnreserveItemsRequest struct {
	// ConnectorName: Name of connector making this call. Format:
	// datasources/{source_id}/connectors/{ID}
	ConnectorName string `json:"connectorName,omitempty"`

	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	// Queue: Name of a queue to unreserve items from.
	Queue string `json:"queue,omitempty"`

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

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

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

type UpdateDataSourceRequest struct {
	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	Source *DataSource `json:"source,omitempty"`

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

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

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

type UpdateSchemaRequest struct {
	// DebugOptions: Common debug options.
	DebugOptions *DebugOptions `json:"debugOptions,omitempty"`

	// Schema: The new schema for the source.
	Schema *Schema `json:"schema,omitempty"`

	// ValidateOnly: If true, the schema will be checked for validity, but
	// will not be registered with the data source, even if valid.
	ValidateOnly bool `json:"validateOnly,omitempty"`

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

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

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

// UploadItemRef: Represents an upload session reference. This reference
// is created via upload method. Updating of item content may refer to
// this uploaded content via contentDataRef.
type UploadItemRef struct {
	// Name: Name of the content reference. The maximum length is 2048
	// characters.
	Name string `json:"name,omitempty"`

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

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

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

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

// Value: Definition of a single value with generic type.
type Value struct {
	BooleanValue bool `json:"booleanValue,omitempty"`

	DateValue *Date `json:"dateValue,omitempty"`

	DoubleValue float64 `json:"doubleValue,omitempty"`

	IntegerValue int64 `json:"integerValue,omitempty,string"`

	StringValue string `json:"stringValue,omitempty"`

	TimestampValue string `json:"timestampValue,omitempty"`

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

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

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

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

type ValueFilter struct {
	// OperatorName: The `operator_name` applied to the query, such as
	// *price_greater_than*. The filter can work against both types of
	// filters defined in the schema for your data source: 1.
	// `operator_name`, where the query filters results by the property that
	// matches the value. 2. `greater_than_operator_name` or
	// `less_than_operator_name` in your schema. The query filters the
	// results for the property values that are greater than or less than
	// the supplied value in the query.
	OperatorName string `json:"operatorName,omitempty"`

	// Value: The value to be compared with.
	Value *Value `json:"value,omitempty"`

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

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

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

// method id "cloudsearch.debug.datasources.items.checkAccess":

type DebugDatasourcesItemsCheckAccessCall struct {
	s          *Service
	name       string
	principal  *Principal
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// CheckAccess: Checks whether an item is accessible by specified
// principal. **Note:** This API requires an admin account to execute.
func (r *DebugDatasourcesItemsService) CheckAccess(name string, principal *Principal) *DebugDatasourcesItemsCheckAccessCall {
	c := &DebugDatasourcesItemsCheckAccessCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.principal = principal
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *DebugDatasourcesItemsCheckAccessCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *DebugDatasourcesItemsCheckAccessCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

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

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

func (c *DebugDatasourcesItemsCheckAccessCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.principal)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/debug/{+name}:checkAccess")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.debug.datasources.items.checkAccess" call.
// Exactly one of *CheckAccessResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CheckAccessResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DebugDatasourcesItemsCheckAccessCall) Do(opts ...googleapi.CallOption) (*CheckAccessResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CheckAccessResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Checks whether an item is accessible by specified principal. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/debug/datasources/{datasourcesId}/items/{itemsId}:checkAccess",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.debug.datasources.items.checkAccess",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Item name, format: datasources/{source_id}/items/{item_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+/items/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/debug/{+name}:checkAccess",
	//   "request": {
	//     "$ref": "Principal"
	//   },
	//   "response": {
	//     "$ref": "CheckAccessResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.debug"
	//   ]
	// }

}

// method id "cloudsearch.debug.datasources.items.searchByViewUrl":

type DebugDatasourcesItemsSearchByViewUrlCall struct {
	s                           *Service
	name                        string
	searchitemsbyviewurlrequest *SearchItemsByViewUrlRequest
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
	header_                     http.Header
}

// SearchByViewUrl: Fetches the item whose viewUrl exactly matches that
// of the URL provided in the request. **Note:** This API requires an
// admin account to execute.
func (r *DebugDatasourcesItemsService) SearchByViewUrl(name string, searchitemsbyviewurlrequest *SearchItemsByViewUrlRequest) *DebugDatasourcesItemsSearchByViewUrlCall {
	c := &DebugDatasourcesItemsSearchByViewUrlCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.searchitemsbyviewurlrequest = searchitemsbyviewurlrequest
	return c
}

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

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

func (c *DebugDatasourcesItemsSearchByViewUrlCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.searchitemsbyviewurlrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/debug/{+name}/items:searchByViewUrl")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.debug.datasources.items.searchByViewUrl" call.
// Exactly one of *SearchItemsByViewUrlResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *SearchItemsByViewUrlResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DebugDatasourcesItemsSearchByViewUrlCall) Do(opts ...googleapi.CallOption) (*SearchItemsByViewUrlResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SearchItemsByViewUrlResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Fetches the item whose viewUrl exactly matches that of the URL provided in the request. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/debug/datasources/{datasourcesId}/items:searchByViewUrl",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.debug.datasources.items.searchByViewUrl",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Source name, format: datasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/debug/{+name}/items:searchByViewUrl",
	//   "request": {
	//     "$ref": "SearchItemsByViewUrlRequest"
	//   },
	//   "response": {
	//     "$ref": "SearchItemsByViewUrlResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.debug"
	//   ]
	// }

}

// 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 *DebugDatasourcesItemsSearchByViewUrlCall) Pages(ctx context.Context, f func(*SearchItemsByViewUrlResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.searchitemsbyviewurlrequest.PageToken = pt }(c.searchitemsbyviewurlrequest.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.searchitemsbyviewurlrequest.PageToken = x.NextPageToken
	}
}

// method id "cloudsearch.debug.datasources.items.unmappedids.list":

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

// List: List all unmapped identities for a specific item. **Note:**
// This API requires an admin account to execute.
func (r *DebugDatasourcesItemsUnmappedidsService) List(parent string) *DebugDatasourcesItemsUnmappedidsListCall {
	c := &DebugDatasourcesItemsUnmappedidsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *DebugDatasourcesItemsUnmappedidsListCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *DebugDatasourcesItemsUnmappedidsListCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// items to fetch in a request. Defaults to 100.
func (c *DebugDatasourcesItemsUnmappedidsListCall) PageSize(pageSize int64) *DebugDatasourcesItemsUnmappedidsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous List request, if any.
func (c *DebugDatasourcesItemsUnmappedidsListCall) PageToken(pageToken string) *DebugDatasourcesItemsUnmappedidsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

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

func (c *DebugDatasourcesItemsUnmappedidsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/debug/{+parent}/unmappedids")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.debug.datasources.items.unmappedids.list" call.
// Exactly one of *ListUnmappedIdentitiesResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListUnmappedIdentitiesResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DebugDatasourcesItemsUnmappedidsListCall) Do(opts ...googleapi.CallOption) (*ListUnmappedIdentitiesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListUnmappedIdentitiesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List all unmapped identities for a specific item. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/debug/datasources/{datasourcesId}/items/{itemsId}/unmappedids",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.debug.datasources.items.unmappedids.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of items to fetch in a request. Defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The next_page_token value returned from a previous List request, if any.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The name of the item, in the following format: datasources/{source_id}/items/{ID}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+/items/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/debug/{+parent}/unmappedids",
	//   "response": {
	//     "$ref": "ListUnmappedIdentitiesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.debug"
	//   ]
	// }

}

// 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 *DebugDatasourcesItemsUnmappedidsListCall) Pages(ctx context.Context, f func(*ListUnmappedIdentitiesResponse) 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 "cloudsearch.debug.identitysources.items.listForunmappedidentity":

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

// ListForunmappedidentity: Lists names of items associated with an
// unmapped identity. **Note:** This API requires an admin account to
// execute.
func (r *DebugIdentitysourcesItemsService) ListForunmappedidentity(parent string) *DebugIdentitysourcesItemsListForunmappedidentityCall {
	c := &DebugIdentitysourcesItemsListForunmappedidentityCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *DebugIdentitysourcesItemsListForunmappedidentityCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *DebugIdentitysourcesItemsListForunmappedidentityCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

// GroupResourceName sets the optional parameter "groupResourceName":
func (c *DebugIdentitysourcesItemsListForunmappedidentityCall) GroupResourceName(groupResourceName string) *DebugIdentitysourcesItemsListForunmappedidentityCall {
	c.urlParams_.Set("groupResourceName", groupResourceName)
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// items to fetch in a request. Defaults to 100.
func (c *DebugIdentitysourcesItemsListForunmappedidentityCall) PageSize(pageSize int64) *DebugIdentitysourcesItemsListForunmappedidentityCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous List request, if any.
func (c *DebugIdentitysourcesItemsListForunmappedidentityCall) PageToken(pageToken string) *DebugIdentitysourcesItemsListForunmappedidentityCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// UserResourceName sets the optional parameter "userResourceName":
func (c *DebugIdentitysourcesItemsListForunmappedidentityCall) UserResourceName(userResourceName string) *DebugIdentitysourcesItemsListForunmappedidentityCall {
	c.urlParams_.Set("userResourceName", userResourceName)
	return c
}

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

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

func (c *DebugIdentitysourcesItemsListForunmappedidentityCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/debug/{+parent}/items:forunmappedidentity")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.debug.identitysources.items.listForunmappedidentity" call.
// Exactly one of *ListItemNamesForUnmappedIdentityResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *ListItemNamesForUnmappedIdentityResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *DebugIdentitysourcesItemsListForunmappedidentityCall) Do(opts ...googleapi.CallOption) (*ListItemNamesForUnmappedIdentityResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListItemNamesForUnmappedIdentityResponse{
		ServerResponse: googleapi.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 names of items associated with an unmapped identity. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/debug/identitysources/{identitysourcesId}/items:forunmappedidentity",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.debug.identitysources.items.listForunmappedidentity",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "groupResourceName": {
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of items to fetch in a request. Defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The next_page_token value returned from a previous List request, if any.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The name of the identity source, in the following format: identitysources/{source_id}}",
	//       "location": "path",
	//       "pattern": "^identitysources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "userResourceName": {
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/debug/{+parent}/items:forunmappedidentity",
	//   "response": {
	//     "$ref": "ListItemNamesForUnmappedIdentityResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.debug"
	//   ]
	// }

}

// 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 *DebugIdentitysourcesItemsListForunmappedidentityCall) Pages(ctx context.Context, f func(*ListItemNamesForUnmappedIdentityResponse) 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 "cloudsearch.debug.identitysources.unmappedids.list":

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

// List: Lists unmapped user identities for an identity source.
// **Note:** This API requires an admin account to execute.
func (r *DebugIdentitysourcesUnmappedidsService) List(parent string) *DebugIdentitysourcesUnmappedidsListCall {
	c := &DebugIdentitysourcesUnmappedidsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *DebugIdentitysourcesUnmappedidsListCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *DebugIdentitysourcesUnmappedidsListCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// items to fetch in a request. Defaults to 100.
func (c *DebugIdentitysourcesUnmappedidsListCall) PageSize(pageSize int64) *DebugIdentitysourcesUnmappedidsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous List request, if any.
func (c *DebugIdentitysourcesUnmappedidsListCall) PageToken(pageToken string) *DebugIdentitysourcesUnmappedidsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ResolutionStatusCode sets the optional parameter
// "resolutionStatusCode": Limit users selection to this status.
//
// Possible values:
//   "CODE_UNSPECIFIED" - Input-only value. Used to list all unmapped
// identities regardless of status.
//   "NOT_FOUND" - The unmapped identity was not found in IDaaS, and
// needs to be provided by the user.
//   "IDENTITY_SOURCE_NOT_FOUND" - The identity source associated with
// the identity was either not found or deleted.
//   "IDENTITY_SOURCE_MISCONFIGURED" - IDaaS does not understand the
// identity source, probably because the schema was modified in a non
// compatible way.
//   "TOO_MANY_MAPPINGS_FOUND" - The number of users associated with the
// external identity is too large.
//   "INTERNAL_ERROR" - Internal error.
func (c *DebugIdentitysourcesUnmappedidsListCall) ResolutionStatusCode(resolutionStatusCode string) *DebugIdentitysourcesUnmappedidsListCall {
	c.urlParams_.Set("resolutionStatusCode", resolutionStatusCode)
	return c
}

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

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

func (c *DebugIdentitysourcesUnmappedidsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/debug/{+parent}/unmappedids")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.debug.identitysources.unmappedids.list" call.
// Exactly one of *ListUnmappedIdentitiesResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListUnmappedIdentitiesResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DebugIdentitysourcesUnmappedidsListCall) Do(opts ...googleapi.CallOption) (*ListUnmappedIdentitiesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListUnmappedIdentitiesResponse{
		ServerResponse: googleapi.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 unmapped user identities for an identity source. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/debug/identitysources/{identitysourcesId}/unmappedids",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.debug.identitysources.unmappedids.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of items to fetch in a request. Defaults to 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The next_page_token value returned from a previous List request, if any.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The name of the identity source, in the following format: identitysources/{source_id}",
	//       "location": "path",
	//       "pattern": "^identitysources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "resolutionStatusCode": {
	//       "description": "Limit users selection to this status.",
	//       "enum": [
	//         "CODE_UNSPECIFIED",
	//         "NOT_FOUND",
	//         "IDENTITY_SOURCE_NOT_FOUND",
	//         "IDENTITY_SOURCE_MISCONFIGURED",
	//         "TOO_MANY_MAPPINGS_FOUND",
	//         "INTERNAL_ERROR"
	//       ],
	//       "enumDescriptions": [
	//         "Input-only value. Used to list all unmapped identities regardless of status.",
	//         "The unmapped identity was not found in IDaaS, and needs to be provided by the user.",
	//         "The identity source associated with the identity was either not found or deleted.",
	//         "IDaaS does not understand the identity source, probably because the schema was modified in a non compatible way.",
	//         "The number of users associated with the external identity is too large.",
	//         "Internal error."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/debug/{+parent}/unmappedids",
	//   "response": {
	//     "$ref": "ListUnmappedIdentitiesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.debug"
	//   ]
	// }

}

// 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 *DebugIdentitysourcesUnmappedidsListCall) Pages(ctx context.Context, f func(*ListUnmappedIdentitiesResponse) 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 "cloudsearch.indexing.datasources.deleteSchema":

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

// DeleteSchema: Deletes the schema of a data source. **Note:** This API
// requires an admin or service account to execute.
func (r *IndexingDatasourcesService) DeleteSchema(name string) *IndexingDatasourcesDeleteSchemaCall {
	c := &IndexingDatasourcesDeleteSchemaCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *IndexingDatasourcesDeleteSchemaCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *IndexingDatasourcesDeleteSchemaCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

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

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

func (c *IndexingDatasourcesDeleteSchemaCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}/schema")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.deleteSchema" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *IndexingDatasourcesDeleteSchemaCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes the schema of a data source. **Note:** This API requires an admin or service account to execute.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/schema",
	//   "httpMethod": "DELETE",
	//   "id": "cloudsearch.indexing.datasources.deleteSchema",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the data source to delete Schema. Format: datasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}/schema",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.getSchema":

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

// GetSchema: Gets the schema of a data source. **Note:** This API
// requires an admin or service account to execute.
func (r *IndexingDatasourcesService) GetSchema(name string) *IndexingDatasourcesGetSchemaCall {
	c := &IndexingDatasourcesGetSchemaCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *IndexingDatasourcesGetSchemaCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *IndexingDatasourcesGetSchemaCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

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

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

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

// Do executes the "cloudsearch.indexing.datasources.getSchema" call.
// Exactly one of *Schema or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Schema.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *IndexingDatasourcesGetSchemaCall) Do(opts ...googleapi.CallOption) (*Schema, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Schema{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the schema of a data source. **Note:** This API requires an admin or service account to execute.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/schema",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.indexing.datasources.getSchema",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the data source to get Schema. Format: datasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}/schema",
	//   "response": {
	//     "$ref": "Schema"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.updateSchema":

type IndexingDatasourcesUpdateSchemaCall struct {
	s                   *Service
	name                string
	updateschemarequest *UpdateSchemaRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// UpdateSchema: Updates the schema of a data source. This method does
// not perform incremental updates to the schema. Instead, this method
// updates the schema by overwriting the entire schema. **Note:** This
// API requires an admin or service account to execute.
func (r *IndexingDatasourcesService) UpdateSchema(name string, updateschemarequest *UpdateSchemaRequest) *IndexingDatasourcesUpdateSchemaCall {
	c := &IndexingDatasourcesUpdateSchemaCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.updateschemarequest = updateschemarequest
	return c
}

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

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

func (c *IndexingDatasourcesUpdateSchemaCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.updateschemarequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}/schema")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.updateSchema" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *IndexingDatasourcesUpdateSchemaCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates the schema of a data source. This method does not perform incremental updates to the schema. Instead, this method updates the schema by overwriting the entire schema. **Note:** This API requires an admin or service account to execute.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/schema",
	//   "httpMethod": "PUT",
	//   "id": "cloudsearch.indexing.datasources.updateSchema",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the data source to update Schema. Format: datasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}/schema",
	//   "request": {
	//     "$ref": "UpdateSchemaRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.items.delete":

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

// Delete: Deletes Item resource for the specified resource name. This
// API requires an admin or service account to execute. The service
// account used is the one whitelisted in the corresponding data source.
func (r *IndexingDatasourcesItemsService) Delete(name string) *IndexingDatasourcesItemsDeleteCall {
	c := &IndexingDatasourcesItemsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ConnectorName sets the optional parameter "connectorName": Name of
// connector making this call. Format:
// datasources/{source_id}/connectors/{ID}
func (c *IndexingDatasourcesItemsDeleteCall) ConnectorName(connectorName string) *IndexingDatasourcesItemsDeleteCall {
	c.urlParams_.Set("connectorName", connectorName)
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *IndexingDatasourcesItemsDeleteCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *IndexingDatasourcesItemsDeleteCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

// Mode sets the optional parameter "mode": Required. The RequestMode
// for this request.
//
// Possible values:
//   "UNSPECIFIED" - Priority is not specified in the update request.
// Leaving priority unspecified results in an update failure.
//   "SYNCHRONOUS" - For real-time updates.
//   "ASYNCHRONOUS" - For changes that are executed after the response
// is sent back to the caller.
func (c *IndexingDatasourcesItemsDeleteCall) Mode(mode string) *IndexingDatasourcesItemsDeleteCall {
	c.urlParams_.Set("mode", mode)
	return c
}

// Version sets the optional parameter "version": Required. The
// incremented version of the item to delete from the index. The
// indexing system stores the version from the datasource as a byte
// string and compares the Item version in the index to the version of
// the queued Item using lexical ordering. Cloud Search Indexing won't
// delete any queued item with a version value that is less than or
// equal to the version of the currently indexed item. The maximum
// length for this field is 1024 bytes.
func (c *IndexingDatasourcesItemsDeleteCall) Version(version string) *IndexingDatasourcesItemsDeleteCall {
	c.urlParams_.Set("version", version)
	return c
}

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

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

func (c *IndexingDatasourcesItemsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.items.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *IndexingDatasourcesItemsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes Item resource for the specified resource name. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items/{itemsId}",
	//   "httpMethod": "DELETE",
	//   "id": "cloudsearch.indexing.datasources.items.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "connectorName": {
	//       "description": "Name of connector making this call. Format: datasources/{source_id}/connectors/{ID}",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "mode": {
	//       "description": "Required. The RequestMode for this request.",
	//       "enum": [
	//         "UNSPECIFIED",
	//         "SYNCHRONOUS",
	//         "ASYNCHRONOUS"
	//       ],
	//       "enumDescriptions": [
	//         "Priority is not specified in the update request. Leaving priority unspecified results in an update failure.",
	//         "For real-time updates.",
	//         "For changes that are executed after the response is sent back to the caller."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Name of the item to delete. Format: datasources/{source_id}/items/{item_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+/items/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "version": {
	//       "description": "Required. The incremented version of the item to delete from the index. The indexing system stores the version from the datasource as a byte string and compares the Item version in the index to the version of the queued Item using lexical ordering. Cloud Search Indexing won't delete any queued item with a version value that is less than or equal to the version of the currently indexed item. The maximum length for this field is 1024 bytes.",
	//       "format": "byte",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.items.deleteQueueItems":

type IndexingDatasourcesItemsDeleteQueueItemsCall struct {
	s                       *Service
	name                    string
	deletequeueitemsrequest *DeleteQueueItemsRequest
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// DeleteQueueItems: Deletes all items in a queue. This method is useful
// for deleting stale items. This API requires an admin or service
// account to execute. The service account used is the one whitelisted
// in the corresponding data source.
func (r *IndexingDatasourcesItemsService) DeleteQueueItems(name string, deletequeueitemsrequest *DeleteQueueItemsRequest) *IndexingDatasourcesItemsDeleteQueueItemsCall {
	c := &IndexingDatasourcesItemsDeleteQueueItemsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.deletequeueitemsrequest = deletequeueitemsrequest
	return c
}

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

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

func (c *IndexingDatasourcesItemsDeleteQueueItemsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.deletequeueitemsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}/items:deleteQueueItems")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.items.deleteQueueItems" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *IndexingDatasourcesItemsDeleteQueueItemsCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes all items in a queue. This method is useful for deleting stale items. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items:deleteQueueItems",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.indexing.datasources.items.deleteQueueItems",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the Data Source to delete items in a queue. Format: datasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}/items:deleteQueueItems",
	//   "request": {
	//     "$ref": "DeleteQueueItemsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.items.get":

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

// Get: Gets Item resource by item name. This API requires an admin or
// service account to execute. The service account used is the one
// whitelisted in the corresponding data source.
func (r *IndexingDatasourcesItemsService) Get(name string) *IndexingDatasourcesItemsGetCall {
	c := &IndexingDatasourcesItemsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ConnectorName sets the optional parameter "connectorName": Name of
// connector making this call. Format:
// datasources/{source_id}/connectors/{ID}
func (c *IndexingDatasourcesItemsGetCall) ConnectorName(connectorName string) *IndexingDatasourcesItemsGetCall {
	c.urlParams_.Set("connectorName", connectorName)
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *IndexingDatasourcesItemsGetCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *IndexingDatasourcesItemsGetCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

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

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

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

// Do executes the "cloudsearch.indexing.datasources.items.get" call.
// Exactly one of *Item or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Item.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *IndexingDatasourcesItemsGetCall) Do(opts ...googleapi.CallOption) (*Item, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Item{
		ServerResponse: googleapi.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 Item resource by item name. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items/{itemsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.indexing.datasources.items.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "connectorName": {
	//       "description": "Name of connector making this call. Format: datasources/{source_id}/connectors/{ID}",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the item to get info. Format: datasources/{source_id}/items/{item_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+/items/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}",
	//   "response": {
	//     "$ref": "Item"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.items.index":

type IndexingDatasourcesItemsIndexCall struct {
	s                *Service
	name             string
	indexitemrequest *IndexItemRequest
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Index: Updates Item ACL, metadata, and content. It will insert the
// Item if it does not exist. This method does not support partial
// updates. Fields with no provided values are cleared out in the Cloud
// Search index. This API requires an admin or service account to
// execute. The service account used is the one whitelisted in the
// corresponding data source.
func (r *IndexingDatasourcesItemsService) Index(name string, indexitemrequest *IndexItemRequest) *IndexingDatasourcesItemsIndexCall {
	c := &IndexingDatasourcesItemsIndexCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.indexitemrequest = indexitemrequest
	return c
}

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

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

func (c *IndexingDatasourcesItemsIndexCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.indexitemrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}:index")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.items.index" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *IndexingDatasourcesItemsIndexCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates Item ACL, metadata, and content. It will insert the Item if it does not exist. This method does not support partial updates. Fields with no provided values are cleared out in the Cloud Search index. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items/{itemsId}:index",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.indexing.datasources.items.index",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the Item. Format: datasources/{source_id}/items/{item_id} This is a required field. The maximum length is 1536 characters.",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+/items/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}:index",
	//   "request": {
	//     "$ref": "IndexItemRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.items.list":

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

// List: Lists all or a subset of Item resources. This API requires an
// admin or service account to execute. The service account used is the
// one whitelisted in the corresponding data source.
func (r *IndexingDatasourcesItemsService) List(name string) *IndexingDatasourcesItemsListCall {
	c := &IndexingDatasourcesItemsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Brief sets the optional parameter "brief": When set to true, the
// indexing system only populates the following fields: name, version,
// queue. metadata.hash, metadata.title, metadata.sourceRepositoryURL,
// metadata.objectType, metadata.createTime, metadata.updateTime,
// metadata.contentLanguage, metadata.mimeType, structured_data.hash,
// content.hash, itemType, itemStatus.code,
// itemStatus.processingError.code, itemStatus.repositoryError.type, If
// this value is false, then all the fields are populated in Item.
func (c *IndexingDatasourcesItemsListCall) Brief(brief bool) *IndexingDatasourcesItemsListCall {
	c.urlParams_.Set("brief", fmt.Sprint(brief))
	return c
}

// ConnectorName sets the optional parameter "connectorName": Name of
// connector making this call. Format:
// datasources/{source_id}/connectors/{ID}
func (c *IndexingDatasourcesItemsListCall) ConnectorName(connectorName string) *IndexingDatasourcesItemsListCall {
	c.urlParams_.Set("connectorName", connectorName)
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *IndexingDatasourcesItemsListCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *IndexingDatasourcesItemsListCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// items to fetch in a request. The max value is 1000 when brief is
// true. The max value is 10 if brief is false. The default value is 10
func (c *IndexingDatasourcesItemsListCall) PageSize(pageSize int64) *IndexingDatasourcesItemsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous List request, if any.
func (c *IndexingDatasourcesItemsListCall) PageToken(pageToken string) *IndexingDatasourcesItemsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

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

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

// Do executes the "cloudsearch.indexing.datasources.items.list" call.
// Exactly one of *ListItemsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListItemsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *IndexingDatasourcesItemsListCall) Do(opts ...googleapi.CallOption) (*ListItemsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListItemsResponse{
		ServerResponse: googleapi.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 all or a subset of Item resources. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.indexing.datasources.items.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "brief": {
	//       "description": "When set to true, the indexing system only populates the following fields: name, version, queue. metadata.hash, metadata.title, metadata.sourceRepositoryURL, metadata.objectType, metadata.createTime, metadata.updateTime, metadata.contentLanguage, metadata.mimeType, structured_data.hash, content.hash, itemType, itemStatus.code, itemStatus.processingError.code, itemStatus.repositoryError.type, If this value is false, then all the fields are populated in Item.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "connectorName": {
	//       "description": "Name of connector making this call. Format: datasources/{source_id}/connectors/{ID}",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the Data Source to list Items. Format: datasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of items to fetch in a request. The max value is 1000 when brief is true. The max value is 10 if brief is false. The default value is 10",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The next_page_token value returned from a previous List request, if any.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}/items",
	//   "response": {
	//     "$ref": "ListItemsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// 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 *IndexingDatasourcesItemsListCall) Pages(ctx context.Context, f func(*ListItemsResponse) 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 "cloudsearch.indexing.datasources.items.poll":

type IndexingDatasourcesItemsPollCall struct {
	s                *Service
	name             string
	pollitemsrequest *PollItemsRequest
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Poll: Polls for unreserved items from the indexing queue and marks a
// set as reserved, starting with items that have the oldest timestamp
// from the highest priority ItemStatus. The priority order is as
// follows: ERROR MODIFIED NEW_ITEM ACCEPTED Reserving items ensures
// that polling from other threads cannot create overlapping sets. After
// handling the reserved items, the client should put items back into
// the unreserved state, either by calling index, or by calling push
// with the type REQUEUE. Items automatically become available
// (unreserved) after 4 hours even if no update or push method is
// called. This API requires an admin or service account to execute. The
// service account used is the one whitelisted in the corresponding data
// source.
func (r *IndexingDatasourcesItemsService) Poll(name string, pollitemsrequest *PollItemsRequest) *IndexingDatasourcesItemsPollCall {
	c := &IndexingDatasourcesItemsPollCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.pollitemsrequest = pollitemsrequest
	return c
}

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

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

func (c *IndexingDatasourcesItemsPollCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.pollitemsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}/items:poll")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.items.poll" call.
// Exactly one of *PollItemsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PollItemsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *IndexingDatasourcesItemsPollCall) Do(opts ...googleapi.CallOption) (*PollItemsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PollItemsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Polls for unreserved items from the indexing queue and marks a set as reserved, starting with items that have the oldest timestamp from the highest priority ItemStatus. The priority order is as follows: ERROR MODIFIED NEW_ITEM ACCEPTED Reserving items ensures that polling from other threads cannot create overlapping sets. After handling the reserved items, the client should put items back into the unreserved state, either by calling index, or by calling push with the type REQUEUE. Items automatically become available (unreserved) after 4 hours even if no update or push method is called. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items:poll",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.indexing.datasources.items.poll",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the Data Source to poll items. Format: datasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}/items:poll",
	//   "request": {
	//     "$ref": "PollItemsRequest"
	//   },
	//   "response": {
	//     "$ref": "PollItemsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.items.push":

type IndexingDatasourcesItemsPushCall struct {
	s               *Service
	name            string
	pushitemrequest *PushItemRequest
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Push: Pushes an item onto a queue for later polling and updating.
// This API requires an admin or service account to execute. The service
// account used is the one whitelisted in the corresponding data source.
func (r *IndexingDatasourcesItemsService) Push(name string, pushitemrequest *PushItemRequest) *IndexingDatasourcesItemsPushCall {
	c := &IndexingDatasourcesItemsPushCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.pushitemrequest = pushitemrequest
	return c
}

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

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

func (c *IndexingDatasourcesItemsPushCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.pushitemrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}:push")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.items.push" call.
// Exactly one of *Item or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Item.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *IndexingDatasourcesItemsPushCall) Do(opts ...googleapi.CallOption) (*Item, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Item{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Pushes an item onto a queue for later polling and updating. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items/{itemsId}:push",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.indexing.datasources.items.push",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the item to push into the indexing queue. Format: datasources/{source_id}/items/{ID} This is a required field. The maximum length is 1536 characters.",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+/items/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}:push",
	//   "request": {
	//     "$ref": "PushItemRequest"
	//   },
	//   "response": {
	//     "$ref": "Item"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.items.unreserve":

type IndexingDatasourcesItemsUnreserveCall struct {
	s                     *Service
	name                  string
	unreserveitemsrequest *UnreserveItemsRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Unreserve: Unreserves all items from a queue, making them all
// eligible to be polled. This method is useful for resetting the
// indexing queue after a connector has been restarted. This API
// requires an admin or service account to execute. The service account
// used is the one whitelisted in the corresponding data source.
func (r *IndexingDatasourcesItemsService) Unreserve(name string, unreserveitemsrequest *UnreserveItemsRequest) *IndexingDatasourcesItemsUnreserveCall {
	c := &IndexingDatasourcesItemsUnreserveCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.unreserveitemsrequest = unreserveitemsrequest
	return c
}

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

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

func (c *IndexingDatasourcesItemsUnreserveCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.unreserveitemsrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}/items:unreserve")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.items.unreserve" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *IndexingDatasourcesItemsUnreserveCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Unreserves all items from a queue, making them all eligible to be polled. This method is useful for resetting the indexing queue after a connector has been restarted. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items:unreserve",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.indexing.datasources.items.unreserve",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the Data Source to unreserve all items. Format: datasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}/items:unreserve",
	//   "request": {
	//     "$ref": "UnreserveItemsRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// method id "cloudsearch.indexing.datasources.items.upload":

type IndexingDatasourcesItemsUploadCall struct {
	s                      *Service
	name                   string
	startuploaditemrequest *StartUploadItemRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Upload: Creates an upload session for uploading item content. For
// items smaller than 100 KB, it's easier to embed the content inline
// within an index request. This API requires an admin or service
// account to execute. The service account used is the one whitelisted
// in the corresponding data source.
func (r *IndexingDatasourcesItemsService) Upload(name string, startuploaditemrequest *StartUploadItemRequest) *IndexingDatasourcesItemsUploadCall {
	c := &IndexingDatasourcesItemsUploadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.startuploaditemrequest = startuploaditemrequest
	return c
}

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

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

func (c *IndexingDatasourcesItemsUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.startuploaditemrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/indexing/{+name}:upload")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.indexing.datasources.items.upload" call.
// Exactly one of *UploadItemRef or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *UploadItemRef.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *IndexingDatasourcesItemsUploadCall) Do(opts ...googleapi.CallOption) (*UploadItemRef, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UploadItemRef{
		ServerResponse: googleapi.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 upload session for uploading item content. For items smaller than 100 KB, it's easier to embed the content inline within an index request. This API requires an admin or service account to execute. The service account used is the one whitelisted in the corresponding data source.",
	//   "flatPath": "v1/indexing/datasources/{datasourcesId}/items/{itemsId}:upload",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.indexing.datasources.items.upload",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the Item to start a resumable upload. Format: datasources/{source_id}/items/{item_id}. The maximum length is 1536 bytes.",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+/items/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/indexing/{+name}:upload",
	//   "request": {
	//     "$ref": "StartUploadItemRequest"
	//   },
	//   "response": {
	//     "$ref": "UploadItemRef"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ]
	// }

}

// method id "cloudsearch.media.upload":

type MediaUploadCall struct {
	s            *Service
	resourceName string
	media        *Media
	urlParams_   gensupport.URLParams
	mediaInfo_   *gensupport.MediaInfo
	ctx_         context.Context
	header_      http.Header
}

// Upload: Uploads media for indexing. The upload endpoint supports
// direct and resumable upload protocols and is intended for large items
// that can not be [inlined during index
// requests](https://developers.google.com/cloud-search/docs/reference/re
// st/v1/indexing.datasources.items#itemcontent). To index large
// content: 1. Call indexing.datasources.items.upload with the resource
// name to begin an upload session and retrieve the UploadItemRef. 1.
// Call media.upload to upload the content using the same resource name
// from step 1. 1. Call indexing.datasources.items.index to index the
// item. Populate the
// [ItemContent](/cloud-search/docs/reference/rest/v1/indexing.datasource
// s.items#ItemContent) with the UploadItemRef from step 1. For
// additional information, see [Create a content connector using the
// REST
// API](https://developers.google.com/cloud-search/docs/guides/content-co
// nnector#rest). **Note:** This API requires a service account to
// execute.
func (r *MediaService) Upload(resourceName string, media *Media) *MediaUploadCall {
	c := &MediaUploadCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.resourceName = resourceName
	c.media = media
	return c
}

// Media specifies the media to upload in one or more chunks. The chunk
// size may be controlled by supplying a MediaOption generated by
// googleapi.ChunkSize. The chunk size defaults to
// googleapi.DefaultUploadChunkSize.The Content-Type header used in the
// upload request will be determined by sniffing the contents of r,
// unless a MediaOption generated by googleapi.ContentType is
// supplied.
// At most one of Media and ResumableMedia may be set.
func (c *MediaUploadCall) Media(r io.Reader, options ...googleapi.MediaOption) *MediaUploadCall {
	c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options)
	return c
}

// ResumableMedia specifies the media to upload in chunks and can be
// canceled with ctx.
//
// Deprecated: use Media instead.
//
// At most one of Media and ResumableMedia may be set. mediaType
// identifies the MIME media type of the upload, such as "image/png". If
// mediaType is "", it will be auto-detected. The provided ctx will
// supersede any context previously provided to the Context method.
func (c *MediaUploadCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *MediaUploadCall {
	c.ctx_ = ctx
	c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType)
	return c
}

// ProgressUpdater provides a callback function that will be called
// after every chunk. It should be a low-latency function in order to
// not slow down the upload operation. This should only be called when
// using ResumableMedia (as opposed to Media).
func (c *MediaUploadCall) ProgressUpdater(pu googleapi.ProgressUpdater) *MediaUploadCall {
	c.mediaInfo_.SetProgressUpdater(pu)
	return c
}

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

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

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

func (c *MediaUploadCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.media)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/media/{+resourceName}")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/v1/media/{+resourceName}")
		c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())
	}
	if body == nil {
		body = new(bytes.Buffer)
		reqHeaders.Set("Content-Type", "application/json")
	}
	body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)
	defer cleanup()
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	req.GetBody = getBody
	googleapi.Expand(req.URL, map[string]string{
		"resourceName": c.resourceName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.media.upload" call.
// Exactly one of *Media or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Media.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *MediaUploadCall) Do(opts ...googleapi.CallOption) (*Media, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))
	if rx != nil {
		rx.Client = c.s.client
		rx.UserAgent = c.s.userAgent()
		ctx := c.ctx_
		if ctx == nil {
			ctx = context.TODO()
		}
		res, err = rx.Upload(ctx)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		if err := googleapi.CheckResponse(res); err != nil {
			return nil, err
		}
	}
	ret := &Media{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Uploads media for indexing. The upload endpoint supports direct and resumable upload protocols and is intended for large items that can not be [inlined during index requests](https://developers.google.com/cloud-search/docs/reference/rest/v1/indexing.datasources.items#itemcontent). To index large content: 1. Call indexing.datasources.items.upload with the resource name to begin an upload session and retrieve the UploadItemRef. 1. Call media.upload to upload the content using the same resource name from step 1. 1. Call indexing.datasources.items.index to index the item. Populate the [ItemContent](/cloud-search/docs/reference/rest/v1/indexing.datasources.items#ItemContent) with the UploadItemRef from step 1. For additional information, see [Create a content connector using the REST API](https://developers.google.com/cloud-search/docs/guides/content-connector#rest). **Note:** This API requires a service account to execute.",
	//   "flatPath": "v1/media/{mediaId}",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.media.upload",
	//   "mediaUpload": {
	//     "accept": [
	//       "*/*"
	//     ],
	//     "protocols": {
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/v1/media/{+resourceName}"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "resourceName"
	//   ],
	//   "parameters": {
	//     "resourceName": {
	//       "description": "Name of the media that is being downloaded. See ReadRequest.resource_name.",
	//       "location": "path",
	//       "pattern": "^.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/media/{+resourceName}",
	//   "request": {
	//     "$ref": "Media"
	//   },
	//   "response": {
	//     "$ref": "Media"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.indexing"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "cloudsearch.operations.get":

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

// Get: Gets the latest state of a long-running operation. Clients can
// use this method to poll the operation result at intervals as
// recommended by the API service.
func (r *OperationsService) Get(name string) *OperationsGetCall {
	c := &OperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

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

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

// Do executes the "cloudsearch.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *OperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest state of a long-running operation. Clients can use this method to poll the operation result at intervals as recommended by the API service.",
	//   "flatPath": "v1/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^operations/.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.debug",
	//     "https://www.googleapis.com/auth/cloud_search.indexing",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing",
	//     "https://www.googleapis.com/auth/cloud_search.settings.query"
	//   ]
	// }

}

// method id "cloudsearch.query.search":

type QuerySearchCall struct {
	s             *Service
	searchrequest *SearchRequest
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Search: The Cloud Search Query API provides the search method, which
// returns the most relevant results from a user query. The results can
// come from G Suite Apps, such as Gmail or Google Drive, or they can
// come from data that you have indexed from a third party. **Note:**
// This API requires a standard end user account to execute. A service
// account can't perform Query API requests directly; to use a service
// account to perform queries, set up [G Suite domain-wide delegation of
// authority](https://developers.google.com/cloud-search/docs/guides/dele
// gation/).
func (r *QueryService) Search(searchrequest *SearchRequest) *QuerySearchCall {
	c := &QuerySearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.searchrequest = searchrequest
	return c
}

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

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

func (c *QuerySearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.searchrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/query/search")
	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 "cloudsearch.query.search" call.
// Exactly one of *SearchResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SearchResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *QuerySearchCall) Do(opts ...googleapi.CallOption) (*SearchResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SearchResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "The Cloud Search Query API provides the search method, which returns the most relevant results from a user query. The results can come from G Suite Apps, such as Gmail or Google Drive, or they can come from data that you have indexed from a third party. **Note:** This API requires a standard end user account to execute. A service account can't perform Query API requests directly; to use a service account to perform queries, set up [G Suite domain-wide delegation of authority](https://developers.google.com/cloud-search/docs/guides/delegation/).",
	//   "flatPath": "v1/query/search",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.query.search",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/query/search",
	//   "request": {
	//     "$ref": "SearchRequest"
	//   },
	//   "response": {
	//     "$ref": "SearchResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.query"
	//   ]
	// }

}

// method id "cloudsearch.query.suggest":

type QuerySuggestCall struct {
	s              *Service
	suggestrequest *SuggestRequest
	urlParams_     gensupport.URLParams
	ctx_           context.Context
	header_        http.Header
}

// Suggest: Provides suggestions for autocompleting the query. **Note:**
// This API requires a standard end user account to execute. A service
// account can't perform Query API requests directly; to use a service
// account to perform queries, set up [G Suite domain-wide delegation of
// authority](https://developers.google.com/cloud-search/docs/guides/dele
// gation/).
func (r *QueryService) Suggest(suggestrequest *SuggestRequest) *QuerySuggestCall {
	c := &QuerySuggestCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.suggestrequest = suggestrequest
	return c
}

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

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

func (c *QuerySuggestCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.suggestrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/query/suggest")
	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 "cloudsearch.query.suggest" call.
// Exactly one of *SuggestResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SuggestResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *QuerySuggestCall) Do(opts ...googleapi.CallOption) (*SuggestResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SuggestResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Provides suggestions for autocompleting the query. **Note:** This API requires a standard end user account to execute. A service account can't perform Query API requests directly; to use a service account to perform queries, set up [G Suite domain-wide delegation of authority](https://developers.google.com/cloud-search/docs/guides/delegation/).",
	//   "flatPath": "v1/query/suggest",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.query.suggest",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/query/suggest",
	//   "request": {
	//     "$ref": "SuggestRequest"
	//   },
	//   "response": {
	//     "$ref": "SuggestResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.query"
	//   ]
	// }

}

// method id "cloudsearch.query.sources.list":

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

// List: Returns list of sources that user can use for Search and
// Suggest APIs. **Note:** This API requires a standard end user account
// to execute. A service account can't perform Query API requests
// directly; to use a service account to perform queries, set up [G
// Suite domain-wide delegation of
// authority](https://developers.google.com/cloud-search/docs/guides/dele
// gation/).
func (r *QuerySourcesService) List() *QuerySourcesListCall {
	c := &QuerySourcesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageToken sets the optional parameter "pageToken": Number of sources
// to return in the response.
func (c *QuerySourcesListCall) PageToken(pageToken string) *QuerySourcesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RequestOptionsDebugOptionsEnableDebugging sets the optional parameter
// "requestOptions.debugOptions.enableDebugging": If you are asked by
// Google to help with debugging, set this field. Otherwise, ignore this
// field.
func (c *QuerySourcesListCall) RequestOptionsDebugOptionsEnableDebugging(requestOptionsDebugOptionsEnableDebugging bool) *QuerySourcesListCall {
	c.urlParams_.Set("requestOptions.debugOptions.enableDebugging", fmt.Sprint(requestOptionsDebugOptionsEnableDebugging))
	return c
}

// RequestOptionsLanguageCode sets the optional parameter
// "requestOptions.languageCode": The BCP-47 language code, such as
// "en-US" or "sr-Latn". For more information, see
// http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. For
// translations. Set this field using the language set in browser or for
// the page. In the event that the user's language preference is known,
// set this field to the known user language. When specified, the
// documents in search results are biased towards the specified
// language. The suggest API does not use this parameter. Instead,
// suggest autocompletes only based on characters in the query.
func (c *QuerySourcesListCall) RequestOptionsLanguageCode(requestOptionsLanguageCode string) *QuerySourcesListCall {
	c.urlParams_.Set("requestOptions.languageCode", requestOptionsLanguageCode)
	return c
}

// RequestOptionsSearchApplicationId sets the optional parameter
// "requestOptions.searchApplicationId": The ID generated when you
// create a search application using the [admin
// console](https://support.google.com/a/answer/9043922).
func (c *QuerySourcesListCall) RequestOptionsSearchApplicationId(requestOptionsSearchApplicationId string) *QuerySourcesListCall {
	c.urlParams_.Set("requestOptions.searchApplicationId", requestOptionsSearchApplicationId)
	return c
}

// RequestOptionsTimeZone sets the optional parameter
// "requestOptions.timeZone": Current user's time zone id, such as
// "America/Los_Angeles" or "Australia/Sydney". These IDs are defined by
// [Unicode Common Locale Data Repository
// (CLDR)](http://cldr.unicode.org/) project, and currently available in
// the file
// [timezone.xml](http://unicode.org/repos/cldr/trunk/common/bcp47/timezo
// ne.xml). This field is used to correctly interpret date and time
// queries. If this field is not specified, the default time zone (UTC)
// is used.
func (c *QuerySourcesListCall) RequestOptionsTimeZone(requestOptionsTimeZone string) *QuerySourcesListCall {
	c.urlParams_.Set("requestOptions.timeZone", requestOptionsTimeZone)
	return c
}

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

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

func (c *QuerySourcesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/query/sources")
	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 "cloudsearch.query.sources.list" call.
// Exactly one of *ListQuerySourcesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListQuerySourcesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *QuerySourcesListCall) Do(opts ...googleapi.CallOption) (*ListQuerySourcesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListQuerySourcesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns list of sources that user can use for Search and Suggest APIs. **Note:** This API requires a standard end user account to execute. A service account can't perform Query API requests directly; to use a service account to perform queries, set up [G Suite domain-wide delegation of authority](https://developers.google.com/cloud-search/docs/guides/delegation/).",
	//   "flatPath": "v1/query/sources",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.query.sources.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageToken": {
	//       "description": "Number of sources to return in the response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestOptions.debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "requestOptions.languageCode": {
	//       "description": "The BCP-47 language code, such as \"en-US\" or \"sr-Latn\". For more information, see http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. For translations. Set this field using the language set in browser or for the page. In the event that the user's language preference is known, set this field to the known user language. When specified, the documents in search results are biased towards the specified language. The suggest API does not use this parameter. Instead, suggest autocompletes only based on characters in the query.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestOptions.searchApplicationId": {
	//       "description": "The ID generated when you create a search application using the [admin console](https://support.google.com/a/answer/9043922).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestOptions.timeZone": {
	//       "description": "Current user's time zone id, such as \"America/Los_Angeles\" or \"Australia/Sydney\". These IDs are defined by [Unicode Common Locale Data Repository (CLDR)](http://cldr.unicode.org/) project, and currently available in the file [timezone.xml](http://unicode.org/repos/cldr/trunk/common/bcp47/timezone.xml). This field is used to correctly interpret date and time queries. If this field is not specified, the default time zone (UTC) is used.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/query/sources",
	//   "response": {
	//     "$ref": "ListQuerySourcesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.query"
	//   ]
	// }

}

// 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 *QuerySourcesListCall) Pages(ctx context.Context, f func(*ListQuerySourcesResponse) 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 "cloudsearch.settings.datasources.create":

type SettingsDatasourcesCreateCall struct {
	s          *Service
	datasource *DataSource
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a datasource. **Note:** This API requires an admin
// account to execute.
func (r *SettingsDatasourcesService) Create(datasource *DataSource) *SettingsDatasourcesCreateCall {
	c := &SettingsDatasourcesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.datasource = datasource
	return c
}

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

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

func (c *SettingsDatasourcesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.datasource)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/datasources")
	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 "cloudsearch.settings.datasources.create" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SettingsDatasourcesCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a datasource. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/datasources",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.settings.datasources.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/settings/datasources",
	//   "request": {
	//     "$ref": "DataSource"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing"
	//   ]
	// }

}

// method id "cloudsearch.settings.datasources.delete":

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

// Delete: Deletes a datasource. **Note:** This API requires an admin
// account to execute.
func (r *SettingsDatasourcesService) Delete(name string) *SettingsDatasourcesDeleteCall {
	c := &SettingsDatasourcesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *SettingsDatasourcesDeleteCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *SettingsDatasourcesDeleteCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

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

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

func (c *SettingsDatasourcesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.settings.datasources.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SettingsDatasourcesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a datasource. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/datasources/{datasourcesId}",
	//   "httpMethod": "DELETE",
	//   "id": "cloudsearch.settings.datasources.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the datasource. Format: datasources/{source_id}.",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing"
	//   ]
	// }

}

// method id "cloudsearch.settings.datasources.get":

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

// Get: Gets a datasource. **Note:** This API requires an admin account
// to execute.
func (r *SettingsDatasourcesService) Get(name string) *SettingsDatasourcesGetCall {
	c := &SettingsDatasourcesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *SettingsDatasourcesGetCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *SettingsDatasourcesGetCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

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

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

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

// Do executes the "cloudsearch.settings.datasources.get" call.
// Exactly one of *DataSource or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DataSource.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SettingsDatasourcesGetCall) Do(opts ...googleapi.CallOption) (*DataSource, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DataSource{
		ServerResponse: googleapi.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 datasource. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/datasources/{datasourcesId}",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.settings.datasources.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the datasource resource. Format: datasources/{source_id}.",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/{+name}",
	//   "response": {
	//     "$ref": "DataSource"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing"
	//   ]
	// }

}

// method id "cloudsearch.settings.datasources.list":

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

// List: Lists datasources. **Note:** This API requires an admin account
// to execute.
func (r *SettingsDatasourcesService) List() *SettingsDatasourcesListCall {
	c := &SettingsDatasourcesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *SettingsDatasourcesListCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *SettingsDatasourcesListCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// datasources to fetch in a request. The max value is 100. The default
// value is 10
func (c *SettingsDatasourcesListCall) PageSize(pageSize int64) *SettingsDatasourcesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": Starting index of
// the results.
func (c *SettingsDatasourcesListCall) PageToken(pageToken string) *SettingsDatasourcesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

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

func (c *SettingsDatasourcesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/datasources")
	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 "cloudsearch.settings.datasources.list" call.
// Exactly one of *ListDataSourceResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListDataSourceResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SettingsDatasourcesListCall) Do(opts ...googleapi.CallOption) (*ListDataSourceResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListDataSourceResponse{
		ServerResponse: googleapi.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 datasources. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/datasources",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.settings.datasources.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of datasources to fetch in a request. The max value is 100. The default value is 10",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Starting index of the results.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/datasources",
	//   "response": {
	//     "$ref": "ListDataSourceResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing"
	//   ]
	// }

}

// 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 *SettingsDatasourcesListCall) Pages(ctx context.Context, f func(*ListDataSourceResponse) 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 "cloudsearch.settings.datasources.update":

type SettingsDatasourcesUpdateCall struct {
	s                       *Service
	name                    string
	updatedatasourcerequest *UpdateDataSourceRequest
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Update: Updates a datasource. **Note:** This API requires an admin
// account to execute.
func (r *SettingsDatasourcesService) Update(name string, updatedatasourcerequest *UpdateDataSourceRequest) *SettingsDatasourcesUpdateCall {
	c := &SettingsDatasourcesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.updatedatasourcerequest = updatedatasourcerequest
	return c
}

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

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

func (c *SettingsDatasourcesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.updatedatasourcerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.settings.datasources.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SettingsDatasourcesUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a datasource. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/datasources/{datasourcesId}",
	//   "httpMethod": "PUT",
	//   "id": "cloudsearch.settings.datasources.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the datasource resource. Format: datasources/{source_id}. The name is ignored when creating a datasource.",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/{+name}",
	//   "request": {
	//     "$ref": "UpdateDataSourceRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.indexing"
	//   ]
	// }

}

// method id "cloudsearch.settings.searchapplications.create":

type SettingsSearchapplicationsCreateCall struct {
	s                 *Service
	searchapplication *SearchApplication
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Create: Creates a search application. **Note:** This API requires an
// admin account to execute.
func (r *SettingsSearchapplicationsService) Create(searchapplication *SearchApplication) *SettingsSearchapplicationsCreateCall {
	c := &SettingsSearchapplicationsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.searchapplication = searchapplication
	return c
}

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

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

func (c *SettingsSearchapplicationsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.searchapplication)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/searchapplications")
	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 "cloudsearch.settings.searchapplications.create" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SettingsSearchapplicationsCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a search application. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/searchapplications",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.settings.searchapplications.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/settings/searchapplications",
	//   "request": {
	//     "$ref": "SearchApplication"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.query"
	//   ]
	// }

}

// method id "cloudsearch.settings.searchapplications.delete":

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

// Delete: Deletes a search application. **Note:** This API requires an
// admin account to execute.
func (r *SettingsSearchapplicationsService) Delete(name string) *SettingsSearchapplicationsDeleteCall {
	c := &SettingsSearchapplicationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *SettingsSearchapplicationsDeleteCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *SettingsSearchapplicationsDeleteCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

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

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

func (c *SettingsSearchapplicationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.settings.searchapplications.delete" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SettingsSearchapplicationsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes a search application. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/searchapplications/{searchapplicationsId}",
	//   "httpMethod": "DELETE",
	//   "id": "cloudsearch.settings.searchapplications.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "The name of the search application to be deleted. Format: applications/{application_id}.",
	//       "location": "path",
	//       "pattern": "^searchapplications/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.query"
	//   ]
	// }

}

// method id "cloudsearch.settings.searchapplications.get":

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

// Get: Gets the specified search application. **Note:** This API
// requires an admin account to execute.
func (r *SettingsSearchapplicationsService) Get(name string) *SettingsSearchapplicationsGetCall {
	c := &SettingsSearchapplicationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *SettingsSearchapplicationsGetCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *SettingsSearchapplicationsGetCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

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

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

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

// Do executes the "cloudsearch.settings.searchapplications.get" call.
// Exactly one of *SearchApplication or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SearchApplication.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SettingsSearchapplicationsGetCall) Do(opts ...googleapi.CallOption) (*SearchApplication, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SearchApplication{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the specified search application. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/searchapplications/{searchapplicationsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.settings.searchapplications.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the search application. Format: searchapplications/{application_id}.",
	//       "location": "path",
	//       "pattern": "^searchapplications/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/{+name}",
	//   "response": {
	//     "$ref": "SearchApplication"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.query"
	//   ]
	// }

}

// method id "cloudsearch.settings.searchapplications.list":

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

// List: Lists all search applications. **Note:** This API requires an
// admin account to execute.
func (r *SettingsSearchapplicationsService) List() *SettingsSearchapplicationsListCall {
	c := &SettingsSearchapplicationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// DebugOptionsEnableDebugging sets the optional parameter
// "debugOptions.enableDebugging": If you are asked by Google to help
// with debugging, set this field. Otherwise, ignore this field.
func (c *SettingsSearchapplicationsListCall) DebugOptionsEnableDebugging(debugOptionsEnableDebugging bool) *SettingsSearchapplicationsListCall {
	c.urlParams_.Set("debugOptions.enableDebugging", fmt.Sprint(debugOptionsEnableDebugging))
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of items to return.
func (c *SettingsSearchapplicationsListCall) PageSize(pageSize int64) *SettingsSearchapplicationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous List request, if any.
// The default value is 10
func (c *SettingsSearchapplicationsListCall) PageToken(pageToken string) *SettingsSearchapplicationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

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

func (c *SettingsSearchapplicationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/searchapplications")
	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 "cloudsearch.settings.searchapplications.list" call.
// Exactly one of *ListSearchApplicationsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListSearchApplicationsResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SettingsSearchapplicationsListCall) Do(opts ...googleapi.CallOption) (*ListSearchApplicationsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListSearchApplicationsResponse{
		ServerResponse: googleapi.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 all search applications. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/searchapplications",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.settings.searchapplications.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "debugOptions.enableDebugging": {
	//       "description": "If you are asked by Google to help with debugging, set this field. Otherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of items to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The next_page_token value returned from a previous List request, if any. The default value is 10",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/searchapplications",
	//   "response": {
	//     "$ref": "ListSearchApplicationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.query"
	//   ]
	// }

}

// 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 *SettingsSearchapplicationsListCall) Pages(ctx context.Context, f func(*ListSearchApplicationsResponse) 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 "cloudsearch.settings.searchapplications.reset":

type SettingsSearchapplicationsResetCall struct {
	s                             *Service
	name                          string
	resetsearchapplicationrequest *ResetSearchApplicationRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Reset: Resets a search application to default settings. This will
// return an empty response. **Note:** This API requires an admin
// account to execute.
func (r *SettingsSearchapplicationsService) Reset(name string, resetsearchapplicationrequest *ResetSearchApplicationRequest) *SettingsSearchapplicationsResetCall {
	c := &SettingsSearchapplicationsResetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.resetsearchapplicationrequest = resetsearchapplicationrequest
	return c
}

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

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

func (c *SettingsSearchapplicationsResetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.resetsearchapplicationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/{+name}:reset")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.settings.searchapplications.reset" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SettingsSearchapplicationsResetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Resets a search application to default settings. This will return an empty response. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/searchapplications/{searchapplicationsId}:reset",
	//   "httpMethod": "POST",
	//   "id": "cloudsearch.settings.searchapplications.reset",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the search application to be reset. Format: applications/{application_id}.",
	//       "location": "path",
	//       "pattern": "^searchapplications/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/{+name}:reset",
	//   "request": {
	//     "$ref": "ResetSearchApplicationRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.query"
	//   ]
	// }

}

// method id "cloudsearch.settings.searchapplications.update":

type SettingsSearchapplicationsUpdateCall struct {
	s                 *Service
	name              string
	searchapplication *SearchApplication
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Update: Updates a search application. **Note:** This API requires an
// admin account to execute.
func (r *SettingsSearchapplicationsService) Update(name string, searchapplication *SearchApplication) *SettingsSearchapplicationsUpdateCall {
	c := &SettingsSearchapplicationsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.searchapplication = searchapplication
	return c
}

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

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

func (c *SettingsSearchapplicationsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	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.searchapplication)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/settings/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "cloudsearch.settings.searchapplications.update" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SettingsSearchapplicationsUpdateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a search application. **Note:** This API requires an admin account to execute.",
	//   "flatPath": "v1/settings/searchapplications/{searchapplicationsId}",
	//   "httpMethod": "PUT",
	//   "id": "cloudsearch.settings.searchapplications.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of the Search Application. Format: searchapplications/{application_id}.",
	//       "location": "path",
	//       "pattern": "^searchapplications/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/settings/{+name}",
	//   "request": {
	//     "$ref": "SearchApplication"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.settings",
	//     "https://www.googleapis.com/auth/cloud_search.settings.query"
	//   ]
	// }

}

// method id "cloudsearch.stats.getIndex":

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

// GetIndex: Gets indexed item statistics aggreggated across all data
// sources. This API only returns statistics for previous dates; it
// doesn't return statistics for the current day. **Note:** This API
// requires a standard end user account to execute.
func (r *StatsService) GetIndex() *StatsGetIndexCall {
	c := &StatsGetIndexCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// FromDateDay sets the optional parameter "fromDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsGetIndexCall) FromDateDay(fromDateDay int64) *StatsGetIndexCall {
	c.urlParams_.Set("fromDate.day", fmt.Sprint(fromDateDay))
	return c
}

// FromDateMonth sets the optional parameter "fromDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsGetIndexCall) FromDateMonth(fromDateMonth int64) *StatsGetIndexCall {
	c.urlParams_.Set("fromDate.month", fmt.Sprint(fromDateMonth))
	return c
}

// FromDateYear sets the optional parameter "fromDate.year": Year of
// date. Must be from 1 to 9999.
func (c *StatsGetIndexCall) FromDateYear(fromDateYear int64) *StatsGetIndexCall {
	c.urlParams_.Set("fromDate.year", fmt.Sprint(fromDateYear))
	return c
}

// ToDateDay sets the optional parameter "toDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsGetIndexCall) ToDateDay(toDateDay int64) *StatsGetIndexCall {
	c.urlParams_.Set("toDate.day", fmt.Sprint(toDateDay))
	return c
}

// ToDateMonth sets the optional parameter "toDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsGetIndexCall) ToDateMonth(toDateMonth int64) *StatsGetIndexCall {
	c.urlParams_.Set("toDate.month", fmt.Sprint(toDateMonth))
	return c
}

// ToDateYear sets the optional parameter "toDate.year": Year of date.
// Must be from 1 to 9999.
func (c *StatsGetIndexCall) ToDateYear(toDateYear int64) *StatsGetIndexCall {
	c.urlParams_.Set("toDate.year", fmt.Sprint(toDateYear))
	return c
}

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

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

func (c *StatsGetIndexCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/stats/index")
	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 "cloudsearch.stats.getIndex" call.
// Exactly one of *GetCustomerIndexStatsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetCustomerIndexStatsResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *StatsGetIndexCall) Do(opts ...googleapi.CallOption) (*GetCustomerIndexStatsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetCustomerIndexStatsResponse{
		ServerResponse: googleapi.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 indexed item statistics aggreggated across all data sources. This API only returns statistics for previous dates; it doesn't return statistics for the current day. **Note:** This API requires a standard end user account to execute.",
	//   "flatPath": "v1/stats/index",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.stats.getIndex",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "fromDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/stats/index",
	//   "response": {
	//     "$ref": "GetCustomerIndexStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.stats",
	//     "https://www.googleapis.com/auth/cloud_search.stats.indexing"
	//   ]
	// }

}

// method id "cloudsearch.stats.getQuery":

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

// GetQuery: Get the query statistics for customer. **Note:** This API
// requires a standard end user account to execute.
func (r *StatsService) GetQuery() *StatsGetQueryCall {
	c := &StatsGetQueryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// FromDateDay sets the optional parameter "fromDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsGetQueryCall) FromDateDay(fromDateDay int64) *StatsGetQueryCall {
	c.urlParams_.Set("fromDate.day", fmt.Sprint(fromDateDay))
	return c
}

// FromDateMonth sets the optional parameter "fromDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsGetQueryCall) FromDateMonth(fromDateMonth int64) *StatsGetQueryCall {
	c.urlParams_.Set("fromDate.month", fmt.Sprint(fromDateMonth))
	return c
}

// FromDateYear sets the optional parameter "fromDate.year": Year of
// date. Must be from 1 to 9999.
func (c *StatsGetQueryCall) FromDateYear(fromDateYear int64) *StatsGetQueryCall {
	c.urlParams_.Set("fromDate.year", fmt.Sprint(fromDateYear))
	return c
}

// ToDateDay sets the optional parameter "toDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsGetQueryCall) ToDateDay(toDateDay int64) *StatsGetQueryCall {
	c.urlParams_.Set("toDate.day", fmt.Sprint(toDateDay))
	return c
}

// ToDateMonth sets the optional parameter "toDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsGetQueryCall) ToDateMonth(toDateMonth int64) *StatsGetQueryCall {
	c.urlParams_.Set("toDate.month", fmt.Sprint(toDateMonth))
	return c
}

// ToDateYear sets the optional parameter "toDate.year": Year of date.
// Must be from 1 to 9999.
func (c *StatsGetQueryCall) ToDateYear(toDateYear int64) *StatsGetQueryCall {
	c.urlParams_.Set("toDate.year", fmt.Sprint(toDateYear))
	return c
}

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

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

func (c *StatsGetQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/stats/query")
	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 "cloudsearch.stats.getQuery" call.
// Exactly one of *GetCustomerQueryStatsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetCustomerQueryStatsResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *StatsGetQueryCall) Do(opts ...googleapi.CallOption) (*GetCustomerQueryStatsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetCustomerQueryStatsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get the query statistics for customer. **Note:** This API requires a standard end user account to execute.",
	//   "flatPath": "v1/stats/query",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.stats.getQuery",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "fromDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/stats/query",
	//   "response": {
	//     "$ref": "GetCustomerQueryStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.stats",
	//     "https://www.googleapis.com/auth/cloud_search.stats.indexing"
	//   ]
	// }

}

// method id "cloudsearch.stats.getSession":

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

// GetSession: Get the # of search sessions, % of successful sessions
// with a click query statistics for customer. **Note:** This API
// requires a standard end user account to execute.
func (r *StatsService) GetSession() *StatsGetSessionCall {
	c := &StatsGetSessionCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// FromDateDay sets the optional parameter "fromDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsGetSessionCall) FromDateDay(fromDateDay int64) *StatsGetSessionCall {
	c.urlParams_.Set("fromDate.day", fmt.Sprint(fromDateDay))
	return c
}

// FromDateMonth sets the optional parameter "fromDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsGetSessionCall) FromDateMonth(fromDateMonth int64) *StatsGetSessionCall {
	c.urlParams_.Set("fromDate.month", fmt.Sprint(fromDateMonth))
	return c
}

// FromDateYear sets the optional parameter "fromDate.year": Year of
// date. Must be from 1 to 9999.
func (c *StatsGetSessionCall) FromDateYear(fromDateYear int64) *StatsGetSessionCall {
	c.urlParams_.Set("fromDate.year", fmt.Sprint(fromDateYear))
	return c
}

// ToDateDay sets the optional parameter "toDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsGetSessionCall) ToDateDay(toDateDay int64) *StatsGetSessionCall {
	c.urlParams_.Set("toDate.day", fmt.Sprint(toDateDay))
	return c
}

// ToDateMonth sets the optional parameter "toDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsGetSessionCall) ToDateMonth(toDateMonth int64) *StatsGetSessionCall {
	c.urlParams_.Set("toDate.month", fmt.Sprint(toDateMonth))
	return c
}

// ToDateYear sets the optional parameter "toDate.year": Year of date.
// Must be from 1 to 9999.
func (c *StatsGetSessionCall) ToDateYear(toDateYear int64) *StatsGetSessionCall {
	c.urlParams_.Set("toDate.year", fmt.Sprint(toDateYear))
	return c
}

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

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

func (c *StatsGetSessionCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/stats/session")
	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 "cloudsearch.stats.getSession" call.
// Exactly one of *GetCustomerSessionStatsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetCustomerSessionStatsResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *StatsGetSessionCall) Do(opts ...googleapi.CallOption) (*GetCustomerSessionStatsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetCustomerSessionStatsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get the # of search sessions, % of successful sessions with a click query statistics for customer. **Note:** This API requires a standard end user account to execute.",
	//   "flatPath": "v1/stats/session",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.stats.getSession",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "fromDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/stats/session",
	//   "response": {
	//     "$ref": "GetCustomerSessionStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.stats",
	//     "https://www.googleapis.com/auth/cloud_search.stats.indexing"
	//   ]
	// }

}

// method id "cloudsearch.stats.getUser":

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

// GetUser: Get the users statistics for customer. **Note:** This API
// requires a standard end user account to execute.
func (r *StatsService) GetUser() *StatsGetUserCall {
	c := &StatsGetUserCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// FromDateDay sets the optional parameter "fromDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsGetUserCall) FromDateDay(fromDateDay int64) *StatsGetUserCall {
	c.urlParams_.Set("fromDate.day", fmt.Sprint(fromDateDay))
	return c
}

// FromDateMonth sets the optional parameter "fromDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsGetUserCall) FromDateMonth(fromDateMonth int64) *StatsGetUserCall {
	c.urlParams_.Set("fromDate.month", fmt.Sprint(fromDateMonth))
	return c
}

// FromDateYear sets the optional parameter "fromDate.year": Year of
// date. Must be from 1 to 9999.
func (c *StatsGetUserCall) FromDateYear(fromDateYear int64) *StatsGetUserCall {
	c.urlParams_.Set("fromDate.year", fmt.Sprint(fromDateYear))
	return c
}

// ToDateDay sets the optional parameter "toDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsGetUserCall) ToDateDay(toDateDay int64) *StatsGetUserCall {
	c.urlParams_.Set("toDate.day", fmt.Sprint(toDateDay))
	return c
}

// ToDateMonth sets the optional parameter "toDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsGetUserCall) ToDateMonth(toDateMonth int64) *StatsGetUserCall {
	c.urlParams_.Set("toDate.month", fmt.Sprint(toDateMonth))
	return c
}

// ToDateYear sets the optional parameter "toDate.year": Year of date.
// Must be from 1 to 9999.
func (c *StatsGetUserCall) ToDateYear(toDateYear int64) *StatsGetUserCall {
	c.urlParams_.Set("toDate.year", fmt.Sprint(toDateYear))
	return c
}

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

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

func (c *StatsGetUserCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200819")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/stats/user")
	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 "cloudsearch.stats.getUser" call.
// Exactly one of *GetCustomerUserStatsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetCustomerUserStatsResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *StatsGetUserCall) Do(opts ...googleapi.CallOption) (*GetCustomerUserStatsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetCustomerUserStatsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get the users statistics for customer. **Note:** This API requires a standard end user account to execute.",
	//   "flatPath": "v1/stats/user",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.stats.getUser",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "fromDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/stats/user",
	//   "response": {
	//     "$ref": "GetCustomerUserStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.stats",
	//     "https://www.googleapis.com/auth/cloud_search.stats.indexing"
	//   ]
	// }

}

// method id "cloudsearch.stats.index.datasources.get":

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

// Get: Gets indexed item statistics for a single data source. **Note:**
// This API requires a standard end user account to execute.
func (r *StatsIndexDatasourcesService) Get(name string) *StatsIndexDatasourcesGetCall {
	c := &StatsIndexDatasourcesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// FromDateDay sets the optional parameter "fromDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsIndexDatasourcesGetCall) FromDateDay(fromDateDay int64) *StatsIndexDatasourcesGetCall {
	c.urlParams_.Set("fromDate.day", fmt.Sprint(fromDateDay))
	return c
}

// FromDateMonth sets the optional parameter "fromDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsIndexDatasourcesGetCall) FromDateMonth(fromDateMonth int64) *StatsIndexDatasourcesGetCall {
	c.urlParams_.Set("fromDate.month", fmt.Sprint(fromDateMonth))
	return c
}

// FromDateYear sets the optional parameter "fromDate.year": Year of
// date. Must be from 1 to 9999.
func (c *StatsIndexDatasourcesGetCall) FromDateYear(fromDateYear int64) *StatsIndexDatasourcesGetCall {
	c.urlParams_.Set("fromDate.year", fmt.Sprint(fromDateYear))
	return c
}

// ToDateDay sets the optional parameter "toDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsIndexDatasourcesGetCall) ToDateDay(toDateDay int64) *StatsIndexDatasourcesGetCall {
	c.urlParams_.Set("toDate.day", fmt.Sprint(toDateDay))
	return c
}

// ToDateMonth sets the optional parameter "toDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsIndexDatasourcesGetCall) ToDateMonth(toDateMonth int64) *StatsIndexDatasourcesGetCall {
	c.urlParams_.Set("toDate.month", fmt.Sprint(toDateMonth))
	return c
}

// ToDateYear sets the optional parameter "toDate.year": Year of date.
// Must be from 1 to 9999.
func (c *StatsIndexDatasourcesGetCall) ToDateYear(toDateYear int64) *StatsIndexDatasourcesGetCall {
	c.urlParams_.Set("toDate.year", fmt.Sprint(toDateYear))
	return c
}

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

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

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

// Do executes the "cloudsearch.stats.index.datasources.get" call.
// Exactly one of *GetDataSourceIndexStatsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GetDataSourceIndexStatsResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *StatsIndexDatasourcesGetCall) Do(opts ...googleapi.CallOption) (*GetDataSourceIndexStatsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetDataSourceIndexStatsResponse{
		ServerResponse: googleapi.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 indexed item statistics for a single data source. **Note:** This API requires a standard end user account to execute.",
	//   "flatPath": "v1/stats/index/datasources/{datasourcesId}",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.stats.index.datasources.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "fromDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "The resource id of the data source to retrieve statistics for, in the following format: \"datasources/{source_id}\"",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "toDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/stats/index/{+name}",
	//   "response": {
	//     "$ref": "GetDataSourceIndexStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.stats",
	//     "https://www.googleapis.com/auth/cloud_search.stats.indexing"
	//   ]
	// }

}

// method id "cloudsearch.stats.query.searchapplications.get":

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

// Get: Get the query statistics for search application. **Note:** This
// API requires a standard end user account to execute.
func (r *StatsQuerySearchapplicationsService) Get(name string) *StatsQuerySearchapplicationsGetCall {
	c := &StatsQuerySearchapplicationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// FromDateDay sets the optional parameter "fromDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsQuerySearchapplicationsGetCall) FromDateDay(fromDateDay int64) *StatsQuerySearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.day", fmt.Sprint(fromDateDay))
	return c
}

// FromDateMonth sets the optional parameter "fromDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsQuerySearchapplicationsGetCall) FromDateMonth(fromDateMonth int64) *StatsQuerySearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.month", fmt.Sprint(fromDateMonth))
	return c
}

// FromDateYear sets the optional parameter "fromDate.year": Year of
// date. Must be from 1 to 9999.
func (c *StatsQuerySearchapplicationsGetCall) FromDateYear(fromDateYear int64) *StatsQuerySearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.year", fmt.Sprint(fromDateYear))
	return c
}

// ToDateDay sets the optional parameter "toDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsQuerySearchapplicationsGetCall) ToDateDay(toDateDay int64) *StatsQuerySearchapplicationsGetCall {
	c.urlParams_.Set("toDate.day", fmt.Sprint(toDateDay))
	return c
}

// ToDateMonth sets the optional parameter "toDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsQuerySearchapplicationsGetCall) ToDateMonth(toDateMonth int64) *StatsQuerySearchapplicationsGetCall {
	c.urlParams_.Set("toDate.month", fmt.Sprint(toDateMonth))
	return c
}

// ToDateYear sets the optional parameter "toDate.year": Year of date.
// Must be from 1 to 9999.
func (c *StatsQuerySearchapplicationsGetCall) ToDateYear(toDateYear int64) *StatsQuerySearchapplicationsGetCall {
	c.urlParams_.Set("toDate.year", fmt.Sprint(toDateYear))
	return c
}

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

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

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

// Do executes the "cloudsearch.stats.query.searchapplications.get" call.
// Exactly one of *GetSearchApplicationQueryStatsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GetSearchApplicationQueryStatsResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *StatsQuerySearchapplicationsGetCall) Do(opts ...googleapi.CallOption) (*GetSearchApplicationQueryStatsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetSearchApplicationQueryStatsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get the query statistics for search application. **Note:** This API requires a standard end user account to execute.",
	//   "flatPath": "v1/stats/query/searchapplications/{searchapplicationsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.stats.query.searchapplications.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "fromDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "The resource id of the search application query stats, in the following format: searchapplications/{application_id}",
	//       "location": "path",
	//       "pattern": "^searchapplications/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "toDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/stats/query/{+name}",
	//   "response": {
	//     "$ref": "GetSearchApplicationQueryStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.stats",
	//     "https://www.googleapis.com/auth/cloud_search.stats.indexing"
	//   ]
	// }

}

// method id "cloudsearch.stats.session.searchapplications.get":

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

// Get: Get the # of search sessions, % of successful sessions with a
// click query statistics for search application. **Note:** This API
// requires a standard end user account to execute.
func (r *StatsSessionSearchapplicationsService) Get(name string) *StatsSessionSearchapplicationsGetCall {
	c := &StatsSessionSearchapplicationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// FromDateDay sets the optional parameter "fromDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsSessionSearchapplicationsGetCall) FromDateDay(fromDateDay int64) *StatsSessionSearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.day", fmt.Sprint(fromDateDay))
	return c
}

// FromDateMonth sets the optional parameter "fromDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsSessionSearchapplicationsGetCall) FromDateMonth(fromDateMonth int64) *StatsSessionSearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.month", fmt.Sprint(fromDateMonth))
	return c
}

// FromDateYear sets the optional parameter "fromDate.year": Year of
// date. Must be from 1 to 9999.
func (c *StatsSessionSearchapplicationsGetCall) FromDateYear(fromDateYear int64) *StatsSessionSearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.year", fmt.Sprint(fromDateYear))
	return c
}

// ToDateDay sets the optional parameter "toDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsSessionSearchapplicationsGetCall) ToDateDay(toDateDay int64) *StatsSessionSearchapplicationsGetCall {
	c.urlParams_.Set("toDate.day", fmt.Sprint(toDateDay))
	return c
}

// ToDateMonth sets the optional parameter "toDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsSessionSearchapplicationsGetCall) ToDateMonth(toDateMonth int64) *StatsSessionSearchapplicationsGetCall {
	c.urlParams_.Set("toDate.month", fmt.Sprint(toDateMonth))
	return c
}

// ToDateYear sets the optional parameter "toDate.year": Year of date.
// Must be from 1 to 9999.
func (c *StatsSessionSearchapplicationsGetCall) ToDateYear(toDateYear int64) *StatsSessionSearchapplicationsGetCall {
	c.urlParams_.Set("toDate.year", fmt.Sprint(toDateYear))
	return c
}

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

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

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

// Do executes the "cloudsearch.stats.session.searchapplications.get" call.
// Exactly one of *GetSearchApplicationSessionStatsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GetSearchApplicationSessionStatsResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *StatsSessionSearchapplicationsGetCall) Do(opts ...googleapi.CallOption) (*GetSearchApplicationSessionStatsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetSearchApplicationSessionStatsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get the # of search sessions, % of successful sessions with a click query statistics for search application. **Note:** This API requires a standard end user account to execute.",
	//   "flatPath": "v1/stats/session/searchapplications/{searchapplicationsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.stats.session.searchapplications.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "fromDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "The resource id of the search application session stats, in the following format: searchapplications/{application_id}",
	//       "location": "path",
	//       "pattern": "^searchapplications/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "toDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/stats/session/{+name}",
	//   "response": {
	//     "$ref": "GetSearchApplicationSessionStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.stats",
	//     "https://www.googleapis.com/auth/cloud_search.stats.indexing"
	//   ]
	// }

}

// method id "cloudsearch.stats.user.searchapplications.get":

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

// Get: Get the users statistics for search application. **Note:** This
// API requires a standard end user account to execute.
func (r *StatsUserSearchapplicationsService) Get(name string) *StatsUserSearchapplicationsGetCall {
	c := &StatsUserSearchapplicationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// FromDateDay sets the optional parameter "fromDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsUserSearchapplicationsGetCall) FromDateDay(fromDateDay int64) *StatsUserSearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.day", fmt.Sprint(fromDateDay))
	return c
}

// FromDateMonth sets the optional parameter "fromDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsUserSearchapplicationsGetCall) FromDateMonth(fromDateMonth int64) *StatsUserSearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.month", fmt.Sprint(fromDateMonth))
	return c
}

// FromDateYear sets the optional parameter "fromDate.year": Year of
// date. Must be from 1 to 9999.
func (c *StatsUserSearchapplicationsGetCall) FromDateYear(fromDateYear int64) *StatsUserSearchapplicationsGetCall {
	c.urlParams_.Set("fromDate.year", fmt.Sprint(fromDateYear))
	return c
}

// ToDateDay sets the optional parameter "toDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month.
func (c *StatsUserSearchapplicationsGetCall) ToDateDay(toDateDay int64) *StatsUserSearchapplicationsGetCall {
	c.urlParams_.Set("toDate.day", fmt.Sprint(toDateDay))
	return c
}

// ToDateMonth sets the optional parameter "toDate.month": Month of
// date. Must be from 1 to 12.
func (c *StatsUserSearchapplicationsGetCall) ToDateMonth(toDateMonth int64) *StatsUserSearchapplicationsGetCall {
	c.urlParams_.Set("toDate.month", fmt.Sprint(toDateMonth))
	return c
}

// ToDateYear sets the optional parameter "toDate.year": Year of date.
// Must be from 1 to 9999.
func (c *StatsUserSearchapplicationsGetCall) ToDateYear(toDateYear int64) *StatsUserSearchapplicationsGetCall {
	c.urlParams_.Set("toDate.year", fmt.Sprint(toDateYear))
	return c
}

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

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

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

// Do executes the "cloudsearch.stats.user.searchapplications.get" call.
// Exactly one of *GetSearchApplicationUserStatsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GetSearchApplicationUserStatsResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *StatsUserSearchapplicationsGetCall) Do(opts ...googleapi.CallOption) (*GetSearchApplicationUserStatsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetSearchApplicationUserStatsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get the users statistics for search application. **Note:** This API requires a standard end user account to execute.",
	//   "flatPath": "v1/stats/user/searchapplications/{searchapplicationsId}",
	//   "httpMethod": "GET",
	//   "id": "cloudsearch.stats.user.searchapplications.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "fromDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "fromDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "The resource id of the search application session stats, in the following format: searchapplications/{application_id}",
	//       "location": "path",
	//       "pattern": "^searchapplications/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "toDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.month": {
	//       "description": "Month of date. Must be from 1 to 12.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "toDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/stats/user/{+name}",
	//   "response": {
	//     "$ref": "GetSearchApplicationUserStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud_search",
	//     "https://www.googleapis.com/auth/cloud_search.stats",
	//     "https://www.googleapis.com/auth/cloud_search.stats.indexing"
	//   ]
	// }

}
