// 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:&lt;value&gt;* show results only where the value of
	// the
	// property named *isClosed* matches *&lt;value&gt;*. By contrast,
	// a
	// search that uses the same *&lt;value&gt;* without an operator
	// returns
	// all items where *&lt;value&gt;* 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}.
	// <br />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 *&lt;value&gt;*
	// then
	// queries like *source:&lt;value&gt;* 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:&lt;value&gt;*
	// show results only where the value of the property named *closeDate*
	// is
	// later than *&lt;value&gt;*.
	// 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:&lt;value&gt;*
	// show results only where the value of the property named *closeDate*
	// is
	// earlier than *&lt;value&gt;*.
	// 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:&lt;value&gt;* show results only where the value of
	// the
	// *closeDate* property matches *&lt;value&gt;*. By contrast, a
	// search that uses the same *&lt;value&gt;* without an operator
	// returns
	// all items where *&lt;value&gt;* 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.
	// <br />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:&lt;value&gt;* show results only where the value of
	// the
	// property named *priorityVal* matches *&lt;value&gt;*. By contrast,
	// a
	// search that uses the same *&lt;value&gt;* without an operator
	// returns
	// all items where *&lt;value&gt;* 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: <br/><br/>
// **1. Setting a ValueFilter.** The name must match an operator_name
// defined in
// the schema for your data source.
// <br/>
// **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:&lt;value&gt;* show results only where the value of
	// the
	// property named *subjectLine* matches *&lt;value&gt;*. By contrast,
	// a
	// search that uses the same *&lt;value&gt;* without an operator
	// return
	// all items where *&lt;value&gt;* 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.
	// <br />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:&lt;value&gt;*
	// show results only where the value of the property named *priorityVal*
	// is
	// greater than *&lt;value&gt;*.
	// 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:&lt;value&gt;*
	// show results only where the value of the property named *priorityVal*
	// is
	// less than *&lt;value&gt;*.
	// 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:&lt;value&gt;* show results only where the value of
	// the
	// property named *priorityVal* matches *&lt;value&gt;*. By contrast,
	// a
	// search that uses the same *&lt;value&gt;* without an operator
	// returns
	// all items where *&lt;value&gt;* 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}
	// <br />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.
	// <br /><br />
	// 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.
	// Th
	// e 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.
	// &#83;earch results apply
	// this link to the title.
	// Whitespace or special characters may cause Cloud &#83;earch 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 <code>Accept-Language</code> 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 <a
	// href="https://developers.google.com/people/api/rest/v1/people/get">
	// Pe
	// ople.get</a> 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.
	// <br />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.
	// <br />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.
	// <br />These items have the following subset of fields populated: <br
	// />
	// <br />version
	// <br />metadata.hash
	// <br />structured_data.hash
	// <br />content.hash
	// <br />payload
	// <br />status
	// <br />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 <code>default</code>
	// 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.
	// <br />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.
	// Fo
	// r 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/t
	// imezone.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.
	// <br />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.
	// <br />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:&lt;value&gt;* show results only where the value of
	// the
	// property named *subjectLine* matches *&lt;value&gt;*. By contrast,
	// a
	// search that uses the same *&lt;value&gt;* without an operator
	// returns
	// all items where *&lt;value&gt;* 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:&lt;value&gt;*
	// show results only where the value of the property named *closeDate*
	// is
	// later than *&lt;value&gt;*.
	// 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:&lt;value&gt;*
	// show results only where the value of the property named *closeDate*
	// is
	// earlier than *&lt;value&gt;*.
	// 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:&lt;value&gt;* show results only where the value of
	// the
	// property named *closeDate* matches *&lt;value&gt;*. By contrast,
	// a
	// search that uses the same *&lt;value&gt;* without an operator
	// returns
	// all items where *&lt;value&gt;* 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.
	// <br />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:
	// <br/><br/>
	// 1. `operator_name`, where the query filters results by the
	// property
	// that matches the value.
	// <br/>
	// 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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Item name, format:\ndatasources/{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/20200801")
	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\nin the request.\n\n**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:\ndatasources/{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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of items to fetch in a request.\nDefaults 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:\ndatasources/{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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "groupResourceName": {
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of items to fetch in a request.\nDefaults 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:\nidentitysources/{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"
//   "NOT_FOUND"
//   "IDENTITY_SOURCE_NOT_FOUND"
//   "IDENTITY_SOURCE_MISCONFIGURED"
//   "TOO_MANY_MAPPINGS_FOUND"
//   "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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of items to fetch in a request.\nDefaults 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:\nidentitysources/{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"
	//       ],
	//       "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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the data source to delete Schema.  Format:\ndatasources/{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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the data source to get Schema.  Format:\ndatasources/{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/20200801")
	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\nincremental updates to the schema. Instead, this method updates the schema\nby overwriting the entire schema.\n\n**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:\ndatasources/{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.
// <br />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"
//   "SYNCHRONOUS"
//   "ASYNCHRONOUS"
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.
// <br /><br />
// 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/20200801")
	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\nspecified resource name. This API requires an admin or service account\nto execute. The service account used is the one whitelisted in the\ncorresponding 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.\n\u003cbr /\u003eFormat: 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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "mode": {
	//       "description": "Required. The RequestMode for this request.",
	//       "enum": [
	//         "UNSPECIFIED",
	//         "SYNCHRONOUS",
	//         "ASYNCHRONOUS"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. Name of the item to delete.\nFormat: 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.\nThe indexing system stores the version from the datasource as a\nbyte string and compares the Item version in the index\nto the version of the queued Item using lexical ordering.\n\u003cbr /\u003e\u003cbr /\u003e\nCloud Search Indexing won't delete any queued item with\na version value that is less than or equal to\nthe version of the currently indexed item.\nThe 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/20200801")
	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\nitems.\n\nThis API requires an admin or service account to execute. The service\naccount 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.\nFormat: 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.
// <br />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/20200801")
	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.\n\nThis API requires an admin or service account to execute.  The service\naccount 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.\n\u003cbr /\u003eFormat: 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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the item to get info.\nFormat: 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/20200801")
	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\ncontent. It will insert the Item if it\ndoes not exist.\nThis method does not support partial updates.  Fields with no provided\nvalues are cleared out in the Cloud Search index.\n\nThis API requires an admin or service account to execute. The service\naccount 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:\ndatasources/{source_id}/items/{item_id}\n\u003cbr /\u003eThis is a required field.\nThe 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,
// metadat
// a.updateTime,
// metadata.contentLanguage,
// metadata.mimeType,
// structured_
// data.hash,
// content.hash,
// itemType,
// itemStatus.code,
// itemStatus.process
// ingError.code,
// itemStatus.repositoryError.type,
// <br />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.
// <br />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.
// <br />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/20200801")
	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.\n\nThis API requires an admin or service account to execute. The service\naccount 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:\nname,\nversion,\nqueue.\nmetadata.hash,\nmetadata.title,\nmetadata.sourceRepositoryURL,\nmetadata.objectType,\nmetadata.createTime,\nmetadata.updateTime,\nmetadata.contentLanguage,\nmetadata.mimeType,\nstructured_data.hash,\ncontent.hash,\nitemType,\nitemStatus.code,\nitemStatus.processingError.code,\nitemStatus.repositoryError.type,\n\u003cbr /\u003eIf this value is false, then all the fields are populated in Item.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "connectorName": {
	//       "description": "Name of connector making this call.\n\u003cbr /\u003eFormat: 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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the Data Source to list Items.  Format:\ndatasources/{source_id}",
	//       "location": "path",
	//       "pattern": "^datasources/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of items to fetch in a request.\nThe max value is 1000 when brief is true.  The max value is 10 if brief\nis false.\n\u003cbr /\u003eThe 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: <br />
// ERROR
// <br />
// MODIFIED
// <br />
// NEW_ITEM
// <br />
// ACCEPTED
// <br />
// 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/20200801")
	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\nset as reserved, starting with items that have\nthe oldest timestamp from the highest priority\nItemStatus.\nThe priority order is as follows: \u003cbr /\u003e\nERROR\n\u003cbr /\u003e\nMODIFIED\n\u003cbr /\u003e\nNEW_ITEM\n\u003cbr /\u003e\nACCEPTED\n\u003cbr /\u003e\nReserving items ensures that polling from other threads\ncannot create overlapping sets.\n\nAfter handling the reserved items, the client should put items back\ninto the unreserved state, either by calling\nindex,\nor by calling\npush with\nthe type REQUEUE.\n\nItems automatically become available (unreserved) after 4 hours even if no\nupdate or push method is called.\n\nThis API requires an admin or service account to execute. The service\naccount 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.\nFormat: 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/20200801")
	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.\n\nThis API requires an admin or service account to execute. The service\naccount 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\npush into the indexing queue.\u003cbr /\u003e\nFormat: datasources/{source_id}/items/{ID}\n\u003cbr /\u003eThis is a required field.\nThe 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/20200801")
	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\npolled.  This method is useful for resetting the indexing queue\nafter a connector has been restarted.\n\nThis API requires an admin or service account to execute. The service\naccount 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.\nFormat: 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/20200801")
	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\nthan 100 KB, it's easier to embed the content\ninline within\nan index request.\n\nThis API requires an admin or service account to execute. The service\naccount 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.\nFormat: datasources/{source_id}/items/{item_id}.\nThe 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/20200801")
	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.\n\nThe upload endpoint supports direct and resumable upload protocols and\nis intended for large items that can not be\n[inlined during index requests](https://developers.google.com/cloud-search/docs/reference/rest/v1/indexing.datasources.items#itemcontent).\nTo index large content:\n\n1. Call\n   indexing.datasources.items.upload\n   with the resource name to begin an upload session and retrieve the\n   UploadItemRef.\n1. Call media.upload to upload the content using the same resource name from step 1.\n1. Call indexing.datasources.items.index\n   to index the item. Populate the\n   [ItemContent](/cloud-search/docs/reference/rest/v1/indexing.datasources.items#ItemContent)\n   with the UploadItemRef from step 1.\n\n\nFor additional information, see\n[Create a content connector using the REST API](https://developers.google.com/cloud-search/docs/guides/content-connector#rest).\n\n  **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\nReadRequest.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/20200801")
	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\nmethod to poll the operation result at intervals as recommended by the API\nservice.",
	//   "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/do
// cs/guides/delegation/).
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/20200801")
	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\nthe most relevant results from a user query.  The results can come from\nG Suite Apps, such as Gmail or Google Drive, or they can come from data\nthat you have indexed from a third party.\n\n**Note:** This API requires a standard end user account to execute.\nA service account can't perform Query API requests directly; to use a\nservice account to perform queries, set up [G Suite domain-wide delegation\nof\nauthority](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/do
// cs/guides/delegation/).
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/20200801")
	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.\n\n**Note:** This API requires a standard end user account to execute.\nA service account can't perform Query API requests directly; to use a\nservice account to perform queries, set up [G Suite domain-wide delegation\nof\nauthority](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/do
// cs/guides/delegation/).
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.
// Fo
// r 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/t
// imezone.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/20200801")
	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.\n\n**Note:** This API requires a standard end user account to execute.\nA service account can't perform Query API requests directly; to use a\nservice account to perform queries, set up [G Suite domain-wide delegation\nof\nauthority](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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "requestOptions.languageCode": {
	//       "description": "The BCP-47 language code, such as \"en-US\" or \"sr-Latn\".\nFor more information, see\nhttp://www.unicode.org/reports/tr35/#Unicode_locale_identifier.\nFor translations.\n\nSet this field using the language set in browser or for the page. In the\nevent that the user's language preference is known, set this field to the\nknown user language.\n\nWhen specified, the documents in search results are biased towards the\nspecified language.\n\nThe suggest API does not use this parameter. Instead, suggest autocompletes\nonly based on characters in the query.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "requestOptions.searchApplicationId": {
	//       "description": "The ID generated when you create a search application using the\n[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\n\"Australia/Sydney\". These IDs are defined by\n[Unicode Common Locale Data Repository (CLDR)](http://cldr.unicode.org/)\nproject, and currently available in the file\n[timezone.xml](http://unicode.org/repos/cldr/trunk/common/bcp47/timezone.xml).\nThis field is used to correctly interpret date and time queries.\nIf 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/20200801")
	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.\n\n**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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the datasource.\nFormat: 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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the datasource resource.\nFormat: 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.
// <br />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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageSize": {
	//       "description": "Maximum number of datasources to fetch in a request.\nThe max value is 100.\n\u003cbr /\u003eThe 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/20200801")
	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.\n\n**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.\nFormat: datasources/{source_id}.\n\u003cbr /\u003eThe 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/20200801")
	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.\n\n**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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "The name of the search application to be deleted.\n\u003cbr /\u003eFormat: 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/20200801")
	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.\n\n**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.\nOtherwise, ignore this field.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "name": {
	//       "description": "Name of the search application.\n\u003cbr /\u003eFormat: 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.
// <br/> 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/20200801")
	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.\n\n**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.\nOtherwise, 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.\n\u003cbr/\u003e 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/20200801")
	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\nresponse.\n\n**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.\n\u003cbr /\u003eFormat: 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/20200801")
	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.\n\n**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.\n\u003cbr /\u003eFormat: 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/20200801")
	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\nAPI only returns statistics for previous dates; it doesn't return\nstatistics for the current day.\n\n**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/20200801")
	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.\n\n**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/20200801")
	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\nstatistics for customer.\n\n**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/20200801")
	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.\n\n**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/20200801")
	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.\n\n**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,\nin 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/20200801")
	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.\n\n**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\nformat: 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/20200801")
	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\nstatistics for search application.\n\n**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\nformat: 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/20200801")
	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.\n\n**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\nformat: 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"
	//   ]
	// }

}
