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

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

// OAuth2 scopes used by this API.
const (
	// See, edit, create, and delete all of your Google Drive files
	DriveScope = "https://www.googleapis.com/auth/drive"

	// View and manage Google Drive files and folders that you have opened
	// or created with this app
	DriveFileScope = "https://www.googleapis.com/auth/drive.file"

	// See and download all your Google Drive files
	DriveReadonlyScope = "https://www.googleapis.com/auth/drive.readonly"

	// See, edit, create, and delete your spreadsheets in Google Drive
	SpreadsheetsScope = "https://www.googleapis.com/auth/spreadsheets"

	// View your Google Spreadsheets
	SpreadsheetsReadonlyScope = "https://www.googleapis.com/auth/spreadsheets.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/drive",
		"https://www.googleapis.com/auth/drive.file",
		"https://www.googleapis.com/auth/drive.readonly",
		"https://www.googleapis.com/auth/spreadsheets",
		"https://www.googleapis.com/auth/spreadsheets.readonly",
	)
	// 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.Spreadsheets = NewSpreadsheetsService(s)
	return s, nil
}

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

	Spreadsheets *SpreadsheetsService
}

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

func NewSpreadsheetsService(s *Service) *SpreadsheetsService {
	rs := &SpreadsheetsService{s: s}
	rs.DeveloperMetadata = NewSpreadsheetsDeveloperMetadataService(s)
	rs.Sheets = NewSpreadsheetsSheetsService(s)
	rs.Values = NewSpreadsheetsValuesService(s)
	return rs
}

type SpreadsheetsService struct {
	s *Service

	DeveloperMetadata *SpreadsheetsDeveloperMetadataService

	Sheets *SpreadsheetsSheetsService

	Values *SpreadsheetsValuesService
}

func NewSpreadsheetsDeveloperMetadataService(s *Service) *SpreadsheetsDeveloperMetadataService {
	rs := &SpreadsheetsDeveloperMetadataService{s: s}
	return rs
}

type SpreadsheetsDeveloperMetadataService struct {
	s *Service
}

func NewSpreadsheetsSheetsService(s *Service) *SpreadsheetsSheetsService {
	rs := &SpreadsheetsSheetsService{s: s}
	return rs
}

type SpreadsheetsSheetsService struct {
	s *Service
}

func NewSpreadsheetsValuesService(s *Service) *SpreadsheetsValuesService {
	rs := &SpreadsheetsValuesService{s: s}
	return rs
}

type SpreadsheetsValuesService struct {
	s *Service
}

// AddBandingRequest: Adds a new banded range to the spreadsheet.
type AddBandingRequest struct {
	// BandedRange: The banded range to add. The bandedRangeId field is
	// optional; if one is not set, an id will be randomly generated. (It is
	// an error to specify the ID of a range that already exists.)
	BandedRange *BandedRange `json:"bandedRange,omitempty"`

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

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

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

// AddBandingResponse: The result of adding a banded range.
type AddBandingResponse struct {
	// BandedRange: The banded range that was added.
	BandedRange *BandedRange `json:"bandedRange,omitempty"`

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

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

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

// AddChartRequest: Adds a chart to a sheet in the spreadsheet.
type AddChartRequest struct {
	// Chart: The chart that should be added to the spreadsheet, including
	// the position where it should be placed. The chartId field is
	// optional; if one is not set, an id will be randomly generated. (It is
	// an error to specify the ID of an embedded object that already
	// exists.)
	Chart *EmbeddedChart `json:"chart,omitempty"`

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

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

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

// AddChartResponse: The result of adding a chart to a spreadsheet.
type AddChartResponse struct {
	// Chart: The newly added chart.
	Chart *EmbeddedChart `json:"chart,omitempty"`

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

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

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

// AddConditionalFormatRuleRequest: Adds a new conditional format rule
// at the given index. All subsequent rules' indexes are incremented.
type AddConditionalFormatRuleRequest struct {
	// Index: The zero-based index where the rule should be inserted.
	Index int64 `json:"index,omitempty"`

	// Rule: The rule to add.
	Rule *ConditionalFormatRule `json:"rule,omitempty"`

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

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

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

// AddDataSourceRequest: Adds a data source. After the data source is
// added successfully, an associated DataSource sheet is created and an
// execution is triggered to refresh the sheet to read data from the
// data source. The request requires an additional bigquery.readonly
// OAuth scope.
type AddDataSourceRequest struct {
	// DataSource: The data source to add.
	DataSource *DataSource `json:"dataSource,omitempty"`

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

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

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

// AddDataSourceResponse: The result of adding a data source.
type AddDataSourceResponse struct {
	// DataExecutionStatus: The data execution status.
	DataExecutionStatus *DataExecutionStatus `json:"dataExecutionStatus,omitempty"`

	// DataSource: The data source that was created.
	DataSource *DataSource `json:"dataSource,omitempty"`

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

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

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

// AddDimensionGroupRequest: Creates a group over the specified range.
// If the requested range is a superset of the range of an existing
// group G, then the depth of G is incremented and this new group G' has
// the depth of that group. For example, a group [C:D, depth 1] + [B:E]
// results in groups [B:E, depth 1] and [C:D, depth 2]. If the requested
// range is a subset of the range of an existing group G, then the depth
// of the new group G' becomes one greater than the depth of G. For
// example, a group [B:E, depth 1] + [C:D] results in groups [B:E, depth
// 1] and [C:D, depth 2]. If the requested range starts before and ends
// within, or starts within and ends after, the range of an existing
// group G, then the range of the existing group G becomes the union of
// the ranges, and the new group G' has depth one greater than the depth
// of G and range as the intersection of the ranges. For example, a
// group [B:D, depth 1] + [C:E] results in groups [B:E, depth 1] and
// [C:D, depth 2].
type AddDimensionGroupRequest struct {
	// Range: The range over which to create a group.
	Range *DimensionRange `json:"range,omitempty"`

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

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

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

// AddDimensionGroupResponse: The result of adding a group.
type AddDimensionGroupResponse struct {
	// DimensionGroups: All groups of a dimension after adding a group to
	// that dimension.
	DimensionGroups []*DimensionGroup `json:"dimensionGroups,omitempty"`

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

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

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

// AddFilterViewRequest: Adds a filter view.
type AddFilterViewRequest struct {
	// Filter: The filter to add. The filterViewId field is optional; if one
	// is not set, an id will be randomly generated. (It is an error to
	// specify the ID of a filter that already exists.)
	Filter *FilterView `json:"filter,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 *AddFilterViewRequest) MarshalJSON() ([]byte, error) {
	type NoMethod AddFilterViewRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AddFilterViewResponse: The result of adding a filter view.
type AddFilterViewResponse struct {
	// Filter: The newly added filter view.
	Filter *FilterView `json:"filter,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 *AddFilterViewResponse) MarshalJSON() ([]byte, error) {
	type NoMethod AddFilterViewResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AddNamedRangeRequest: Adds a named range to the spreadsheet.
type AddNamedRangeRequest struct {
	// NamedRange: The named range to add. The namedRangeId field is
	// optional; if one is not set, an id will be randomly generated. (It is
	// an error to specify the ID of a range that already exists.)
	NamedRange *NamedRange `json:"namedRange,omitempty"`

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

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

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

// AddNamedRangeResponse: The result of adding a named range.
type AddNamedRangeResponse struct {
	// NamedRange: The named range to add.
	NamedRange *NamedRange `json:"namedRange,omitempty"`

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

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

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

// AddProtectedRangeRequest: Adds a new protected range.
type AddProtectedRangeRequest struct {
	// ProtectedRange: The protected range to be added. The protectedRangeId
	// field is optional; if one is not set, an id will be randomly
	// generated. (It is an error to specify the ID of a range that already
	// exists.)
	ProtectedRange *ProtectedRange `json:"protectedRange,omitempty"`

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

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

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

// AddProtectedRangeResponse: The result of adding a new protected
// range.
type AddProtectedRangeResponse struct {
	// ProtectedRange: The newly added protected range.
	ProtectedRange *ProtectedRange `json:"protectedRange,omitempty"`

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

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

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

// AddSheetRequest: Adds a new sheet. When a sheet is added at a given
// index, all subsequent sheets' indexes are incremented. To add an
// object sheet, use AddChartRequest instead and specify
// EmbeddedObjectPosition.sheetId or EmbeddedObjectPosition.newSheet.
type AddSheetRequest struct {
	// Properties: The properties the new sheet should have. All properties
	// are optional. The sheetId field is optional; if one is not set, an id
	// will be randomly generated. (It is an error to specify the ID of a
	// sheet that already exists.)
	Properties *SheetProperties `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 *AddSheetRequest) MarshalJSON() ([]byte, error) {
	type NoMethod AddSheetRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AddSheetResponse: The result of adding a sheet.
type AddSheetResponse struct {
	// Properties: The properties of the newly added sheet.
	Properties *SheetProperties `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 *AddSheetResponse) MarshalJSON() ([]byte, error) {
	type NoMethod AddSheetResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AddSlicerRequest: Adds a slicer to a sheet in the spreadsheet.
type AddSlicerRequest struct {
	// Slicer: The slicer that should be added to the spreadsheet, including
	// the position where it should be placed. The slicerId field is
	// optional; if one is not set, an id will be randomly generated. (It is
	// an error to specify the ID of a slicer that already exists.)
	Slicer *Slicer `json:"slicer,omitempty"`

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

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

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

// AddSlicerResponse: The result of adding a slicer to a spreadsheet.
type AddSlicerResponse struct {
	// Slicer: The newly added slicer.
	Slicer *Slicer `json:"slicer,omitempty"`

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

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

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

// AppendCellsRequest: Adds new cells after the last row with data in a
// sheet, inserting new rows into the sheet if necessary.
type AppendCellsRequest struct {
	// Fields: The fields of CellData that should be updated. At least one
	// field must be specified. The root is the CellData; 'row.values.'
	// should not be specified. A single "*" can be used as short-hand for
	// listing every field.
	Fields string `json:"fields,omitempty"`

	// Rows: The data to append.
	Rows []*RowData `json:"rows,omitempty"`

	// SheetId: The sheet ID to append the data to.
	SheetId int64 `json:"sheetId,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 *AppendCellsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod AppendCellsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AppendDimensionRequest: Appends rows or columns to the end of a
// sheet.
type AppendDimensionRequest struct {
	// Dimension: Whether rows or columns should be appended.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
	//   "ROWS" - Operates on the rows of a sheet.
	//   "COLUMNS" - Operates on the columns of a sheet.
	Dimension string `json:"dimension,omitempty"`

	// Length: The number of rows or columns to append.
	Length int64 `json:"length,omitempty"`

	// SheetId: The sheet to append rows or columns to.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// AppendValuesResponse: The response when updating a range of values in
// a spreadsheet.
type AppendValuesResponse struct {
	// SpreadsheetId: The spreadsheet the updates were applied to.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// TableRange: The range (in A1 notation) of the table that values are
	// being appended to (before the values were appended). Empty if no
	// table was found.
	TableRange string `json:"tableRange,omitempty"`

	// Updates: Information about the updates that were applied.
	Updates *UpdateValuesResponse `json:"updates,omitempty"`

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

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

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

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

// AutoFillRequest: Fills in more data based on existing data.
type AutoFillRequest struct {
	// Range: The range to autofill. This will examine the range and detect
	// the location that has data and automatically fill that data in to the
	// rest of the range.
	Range *GridRange `json:"range,omitempty"`

	// SourceAndDestination: The source and destination areas to autofill.
	// This explicitly lists the source of the autofill and where to extend
	// that data.
	SourceAndDestination *SourceAndDestination `json:"sourceAndDestination,omitempty"`

	// UseAlternateSeries: True if we should generate data with the
	// "alternate" series. This differs based on the type and amount of
	// source data.
	UseAlternateSeries bool `json:"useAlternateSeries,omitempty"`

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

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

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

// AutoResizeDimensionsRequest: Automatically resizes one or more
// dimensions based on the contents of the cells in that dimension.
type AutoResizeDimensionsRequest struct {
	// DataSourceSheetDimensions: The dimensions on a data source sheet to
	// automatically resize.
	DataSourceSheetDimensions *DataSourceSheetDimensionRange `json:"dataSourceSheetDimensions,omitempty"`

	// Dimensions: The dimensions to automatically resize.
	Dimensions *DimensionRange `json:"dimensions,omitempty"`

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

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

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

// BandedRange: A banded (alternating colors) range in a sheet.
type BandedRange struct {
	// BandedRangeId: The id of the banded range.
	BandedRangeId int64 `json:"bandedRangeId,omitempty"`

	// ColumnProperties: Properties for column bands. These properties are
	// applied on a column- by-column basis throughout all the columns in
	// the range. At least one of row_properties or column_properties must
	// be specified.
	ColumnProperties *BandingProperties `json:"columnProperties,omitempty"`

	// Range: The range over which these properties are applied.
	Range *GridRange `json:"range,omitempty"`

	// RowProperties: Properties for row bands. These properties are applied
	// on a row-by-row basis throughout all the rows in the range. At least
	// one of row_properties or column_properties must be specified.
	RowProperties *BandingProperties `json:"rowProperties,omitempty"`

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

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

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

// BandingProperties: Properties referring a single dimension (either
// row or column). If both BandedRange.row_properties and
// BandedRange.column_properties are set, the fill colors are applied to
// cells according to the following rules: * header_color and
// footer_color take priority over band colors. * first_band_color takes
// priority over second_band_color. * row_properties takes priority over
// column_properties. For example, the first row color takes priority
// over the first column color, but the first column color takes
// priority over the second row color. Similarly, the row header takes
// priority over the column header in the top left cell, but the column
// header takes priority over the first row color if the row header is
// not set.
type BandingProperties struct {
	// FirstBandColor: The first color that is alternating. (Required)
	FirstBandColor *Color `json:"firstBandColor,omitempty"`

	// FirstBandColorStyle: The first color that is alternating. (Required)
	// If first_band_color is also set, this field takes precedence.
	FirstBandColorStyle *ColorStyle `json:"firstBandColorStyle,omitempty"`

	// FooterColor: The color of the last row or column. If this field is
	// not set, the last row or column is filled with either
	// first_band_color or second_band_color, depending on the color of the
	// previous row or column.
	FooterColor *Color `json:"footerColor,omitempty"`

	// FooterColorStyle: The color of the last row or column. If this field
	// is not set, the last row or column is filled with either
	// first_band_color or second_band_color, depending on the color of the
	// previous row or column. If footer_color is also set, this field takes
	// precedence.
	FooterColorStyle *ColorStyle `json:"footerColorStyle,omitempty"`

	// HeaderColor: The color of the first row or column. If this field is
	// set, the first row or column is filled with this color and the colors
	// alternate between first_band_color and second_band_color starting
	// from the second row or column. Otherwise, the first row or column is
	// filled with first_band_color and the colors proceed to alternate as
	// they normally would.
	HeaderColor *Color `json:"headerColor,omitempty"`

	// HeaderColorStyle: The color of the first row or column. If this field
	// is set, the first row or column is filled with this color and the
	// colors alternate between first_band_color and second_band_color
	// starting from the second row or column. Otherwise, the first row or
	// column is filled with first_band_color and the colors proceed to
	// alternate as they normally would. If header_color is also set, this
	// field takes precedence.
	HeaderColorStyle *ColorStyle `json:"headerColorStyle,omitempty"`

	// SecondBandColor: The second color that is alternating. (Required)
	SecondBandColor *Color `json:"secondBandColor,omitempty"`

	// SecondBandColorStyle: The second color that is alternating.
	// (Required) If second_band_color is also set, this field takes
	// precedence.
	SecondBandColorStyle *ColorStyle `json:"secondBandColorStyle,omitempty"`

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

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

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

// BaselineValueFormat: Formatting options for baseline value.
type BaselineValueFormat struct {
	// ComparisonType: The comparison type of key value with baseline value.
	//
	// Possible values:
	//   "COMPARISON_TYPE_UNDEFINED" - Default value, do not use.
	//   "ABSOLUTE_DIFFERENCE" - Use absolute difference between key and
	// baseline value.
	//   "PERCENTAGE_DIFFERENCE" - Use percentage difference between key and
	// baseline value.
	ComparisonType string `json:"comparisonType,omitempty"`

	// Description: Description which is appended after the baseline value.
	// This field is optional.
	Description string `json:"description,omitempty"`

	// NegativeColor: Color to be used, in case baseline value represents a
	// negative change for key value. This field is optional.
	NegativeColor *Color `json:"negativeColor,omitempty"`

	// NegativeColorStyle: Color to be used, in case baseline value
	// represents a negative change for key value. This field is optional.
	// If negative_color is also set, this field takes precedence.
	NegativeColorStyle *ColorStyle `json:"negativeColorStyle,omitempty"`

	// Position: Specifies the horizontal text positioning of baseline
	// value. This field is optional. If not specified, default positioning
	// is used.
	Position *TextPosition `json:"position,omitempty"`

	// PositiveColor: Color to be used, in case baseline value represents a
	// positive change for key value. This field is optional.
	PositiveColor *Color `json:"positiveColor,omitempty"`

	// PositiveColorStyle: Color to be used, in case baseline value
	// represents a positive change for key value. This field is optional.
	// If positive_color is also set, this field takes precedence.
	PositiveColorStyle *ColorStyle `json:"positiveColorStyle,omitempty"`

	// TextFormat: Text formatting options for baseline value.
	TextFormat *TextFormat `json:"textFormat,omitempty"`

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

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

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

// BasicChartAxis: An axis of the chart. A chart may not have more than
// one axis per axis position.
type BasicChartAxis struct {
	// Format: The format of the title. Only valid if the axis is not
	// associated with the domain.
	Format *TextFormat `json:"format,omitempty"`

	// Position: The position of this axis.
	//
	// Possible values:
	//   "BASIC_CHART_AXIS_POSITION_UNSPECIFIED" - Default value, do not
	// use.
	//   "BOTTOM_AXIS" - The axis rendered at the bottom of a chart. For
	// most charts, this is the standard major axis. For bar charts, this is
	// a minor axis.
	//   "LEFT_AXIS" - The axis rendered at the left of a chart. For most
	// charts, this is a minor axis. For bar charts, this is the standard
	// major axis.
	//   "RIGHT_AXIS" - The axis rendered at the right of a chart. For most
	// charts, this is a minor axis. For bar charts, this is an unusual
	// major axis.
	Position string `json:"position,omitempty"`

	// Title: The title of this axis. If set, this overrides any title
	// inferred from headers of the data.
	Title string `json:"title,omitempty"`

	// TitleTextPosition: The axis title text position.
	TitleTextPosition *TextPosition `json:"titleTextPosition,omitempty"`

	// ViewWindowOptions: The view window options for this axis.
	ViewWindowOptions *ChartAxisViewWindowOptions `json:"viewWindowOptions,omitempty"`

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

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

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

// BasicChartDomain: The domain of a chart. For example, if charting
// stock prices over time, this would be the date.
type BasicChartDomain struct {
	// Domain: The data of the domain. For example, if charting stock prices
	// over time, this is the data representing the dates.
	Domain *ChartData `json:"domain,omitempty"`

	// Reversed: True to reverse the order of the domain values (horizontal
	// axis).
	Reversed bool `json:"reversed,omitempty"`

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

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

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

// BasicChartSeries: A single series of data in a chart. For example, if
// charting stock prices over time, multiple series may exist, one for
// the "Open Price", "High Price", "Low Price" and "Close Price".
type BasicChartSeries struct {
	// Color: The color for elements (such as bars, lines, and points)
	// associated with this series. If empty, a default color is used.
	Color *Color `json:"color,omitempty"`

	// ColorStyle: The color for elements (such as bars, lines, and points)
	// associated with this series. If empty, a default color is used. If
	// color is also set, this field takes precedence.
	ColorStyle *ColorStyle `json:"colorStyle,omitempty"`

	// LineStyle: The line style of this series. Valid only if the chartType
	// is AREA, LINE, or SCATTER. COMBO charts are also supported if the
	// series chart type is AREA or LINE.
	LineStyle *LineStyle `json:"lineStyle,omitempty"`

	// Series: The data being visualized in this chart series.
	Series *ChartData `json:"series,omitempty"`

	// TargetAxis: The minor axis that will specify the range of values for
	// this series. For example, if charting stocks over time, the "Volume"
	// series may want to be pinned to the right with the prices pinned to
	// the left, because the scale of trading volume is different than the
	// scale of prices. It is an error to specify an axis that isn't a valid
	// minor axis for the chart's type.
	//
	// Possible values:
	//   "BASIC_CHART_AXIS_POSITION_UNSPECIFIED" - Default value, do not
	// use.
	//   "BOTTOM_AXIS" - The axis rendered at the bottom of a chart. For
	// most charts, this is the standard major axis. For bar charts, this is
	// a minor axis.
	//   "LEFT_AXIS" - The axis rendered at the left of a chart. For most
	// charts, this is a minor axis. For bar charts, this is the standard
	// major axis.
	//   "RIGHT_AXIS" - The axis rendered at the right of a chart. For most
	// charts, this is a minor axis. For bar charts, this is an unusual
	// major axis.
	TargetAxis string `json:"targetAxis,omitempty"`

	// Type: The type of this series. Valid only if the chartType is COMBO.
	// Different types will change the way the series is visualized. Only
	// LINE, AREA, and COLUMN are supported.
	//
	// Possible values:
	//   "BASIC_CHART_TYPE_UNSPECIFIED" - Default value, do not use.
	//   "BAR" - A bar chart.
	//   "LINE" - A line chart.
	//   "AREA" - An area chart.
	//   "COLUMN" - A column chart.
	//   "SCATTER" - A scatter chart.
	//   "COMBO" - A combo chart.
	//   "STEPPED_AREA" - A stepped area chart.
	Type string `json:"type,omitempty"`

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

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

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

// BasicChartSpec: The specification for a basic chart. See
// BasicChartType for the list of charts this supports.
type BasicChartSpec struct {
	// Axis: The axis on the chart.
	Axis []*BasicChartAxis `json:"axis,omitempty"`

	// ChartType: The type of the chart.
	//
	// Possible values:
	//   "BASIC_CHART_TYPE_UNSPECIFIED" - Default value, do not use.
	//   "BAR" - A bar chart.
	//   "LINE" - A line chart.
	//   "AREA" - An area chart.
	//   "COLUMN" - A column chart.
	//   "SCATTER" - A scatter chart.
	//   "COMBO" - A combo chart.
	//   "STEPPED_AREA" - A stepped area chart.
	ChartType string `json:"chartType,omitempty"`

	// CompareMode: The behavior of tooltips and data highlighting when
	// hovering on data and chart area.
	//
	// Possible values:
	//   "BASIC_CHART_COMPARE_MODE_UNSPECIFIED" - Default value, do not use.
	//   "DATUM" - Only the focused data element is highlighted and shown in
	// the tooltip.
	//   "CATEGORY" - All data elements with the same category (e.g., domain
	// value) are highlighted and shown in the tooltip.
	CompareMode string `json:"compareMode,omitempty"`

	// Domains: The domain of data this is charting. Only a single domain is
	// supported.
	Domains []*BasicChartDomain `json:"domains,omitempty"`

	// HeaderCount: The number of rows or columns in the data that are
	// "headers". If not set, Google Sheets will guess how many rows are
	// headers based on the data. (Note that BasicChartAxis.title may
	// override the axis title inferred from the header values.)
	HeaderCount int64 `json:"headerCount,omitempty"`

	// InterpolateNulls: If some values in a series are missing, gaps may
	// appear in the chart (e.g, segments of lines in a line chart will be
	// missing). To eliminate these gaps set this to true. Applies to Line,
	// Area, and Combo charts.
	InterpolateNulls bool `json:"interpolateNulls,omitempty"`

	// LegendPosition: The position of the chart legend.
	//
	// Possible values:
	//   "BASIC_CHART_LEGEND_POSITION_UNSPECIFIED" - Default value, do not
	// use.
	//   "BOTTOM_LEGEND" - The legend is rendered on the bottom of the
	// chart.
	//   "LEFT_LEGEND" - The legend is rendered on the left of the chart.
	//   "RIGHT_LEGEND" - The legend is rendered on the right of the chart.
	//   "TOP_LEGEND" - The legend is rendered on the top of the chart.
	//   "NO_LEGEND" - No legend is rendered.
	LegendPosition string `json:"legendPosition,omitempty"`

	// LineSmoothing: Gets whether all lines should be rendered smooth or
	// straight by default. Applies to Line charts.
	LineSmoothing bool `json:"lineSmoothing,omitempty"`

	// Series: The data this chart is visualizing.
	Series []*BasicChartSeries `json:"series,omitempty"`

	// StackedType: The stacked type for charts that support vertical
	// stacking. Applies to Area, Bar, Column, Combo, and Stepped Area
	// charts.
	//
	// Possible values:
	//   "BASIC_CHART_STACKED_TYPE_UNSPECIFIED" - Default value, do not use.
	//   "NOT_STACKED" - Series are not stacked.
	//   "STACKED" - Series values are stacked, each value is rendered
	// vertically beginning from the top of the value below it.
	//   "PERCENT_STACKED" - Vertical stacks are stretched to reach the top
	// of the chart, with values laid out as percentages of each other.
	StackedType string `json:"stackedType,omitempty"`

	// ThreeDimensional: True to make the chart 3D. Applies to Bar and
	// Column charts.
	ThreeDimensional bool `json:"threeDimensional,omitempty"`

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

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

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

// BasicFilter: The default filter associated with a sheet.
type BasicFilter struct {
	// Criteria: The criteria for showing/hiding values per column. The
	// map's key is the column index, and the value is the criteria for that
	// column.
	Criteria map[string]FilterCriteria `json:"criteria,omitempty"`

	// FilterSpecs: The filter criteria per column. Both criteria and
	// filter_specs are populated in responses. If both fields are specified
	// in an update request, this field takes precedence.
	FilterSpecs []*FilterSpec `json:"filterSpecs,omitempty"`

	// Range: The range the filter covers.
	Range *GridRange `json:"range,omitempty"`

	// SortSpecs: The sort order per column. Later specifications are used
	// when values are equal in the earlier specifications.
	SortSpecs []*SortSpec `json:"sortSpecs,omitempty"`

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

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

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

// BatchClearValuesByDataFilterRequest: The request for clearing more
// than one range selected by a DataFilter in a spreadsheet.
type BatchClearValuesByDataFilterRequest struct {
	// DataFilters: The DataFilters used to determine which ranges to clear.
	DataFilters []*DataFilter `json:"dataFilters,omitempty"`

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

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

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

// BatchClearValuesByDataFilterResponse: The response when clearing a
// range of values selected with DataFilters in a spreadsheet.
type BatchClearValuesByDataFilterResponse struct {
	// ClearedRanges: The ranges that were cleared, in A1 notation. If the
	// requests are for an unbounded range or a ranger larger than the
	// bounds of the sheet, this is the actual ranges that were cleared,
	// bounded to the sheet's limits.
	ClearedRanges []string `json:"clearedRanges,omitempty"`

	// SpreadsheetId: The spreadsheet the updates were applied to.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

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

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

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

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

// BatchClearValuesRequest: The request for clearing more than one range
// of values in a spreadsheet.
type BatchClearValuesRequest struct {
	// Ranges: The ranges to clear, in A1 notation.
	Ranges []string `json:"ranges,omitempty"`

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

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

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

// BatchClearValuesResponse: The response when clearing a range of
// values in a spreadsheet.
type BatchClearValuesResponse struct {
	// ClearedRanges: The ranges that were cleared, in A1 notation. If the
	// requests are for an unbounded range or a ranger larger than the
	// bounds of the sheet, this is the actual ranges that were cleared,
	// bounded to the sheet's limits.
	ClearedRanges []string `json:"clearedRanges,omitempty"`

	// SpreadsheetId: The spreadsheet the updates were applied to.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

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

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

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

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

// BatchGetValuesByDataFilterRequest: The request for retrieving a range
// of values in a spreadsheet selected by a set of DataFilters.
type BatchGetValuesByDataFilterRequest struct {
	// DataFilters: The data filters used to match the ranges of values to
	// retrieve. Ranges that match any of the specified data filters are
	// included in the response.
	DataFilters []*DataFilter `json:"dataFilters,omitempty"`

	// DateTimeRenderOption: How dates, times, and durations should be
	// represented in the output. This is ignored if value_render_option is
	// FORMATTED_VALUE. The default dateTime render option is
	// [DateTimeRenderOption.SERIAL_NUMBER].
	//
	// Possible values:
	//   "SERIAL_NUMBER" - Instructs date, time, datetime, and duration
	// fields to be output as doubles in "serial number" format, as
	// popularized by Lotus 1-2-3. The whole number portion of the value
	// (left of the decimal) counts the days since December 30th 1899. The
	// fractional portion (right of the decimal) counts the time as a
	// fraction of the day. For example, January 1st 1900 at noon would be
	// 2.5, 2 because it's 2 days after December 30st 1899, and .5 because
	// noon is half a day. February 1st 1900 at 3pm would be 33.625. This
	// correctly treats the year 1900 as not a leap year.
	//   "FORMATTED_STRING" - Instructs date, time, datetime, and duration
	// fields to be output as strings in their given number format (which is
	// dependent on the spreadsheet locale).
	DateTimeRenderOption string `json:"dateTimeRenderOption,omitempty"`

	// MajorDimension: The major dimension that results should use. For
	// example, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, then a
	// request that selects that range and sets `majorDimension=ROWS`
	// returns `[[1,2],[3,4]]`, whereas a request that sets
	// `majorDimension=COLUMNS` returns `[[1,3],[2,4]]`.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
	//   "ROWS" - Operates on the rows of a sheet.
	//   "COLUMNS" - Operates on the columns of a sheet.
	MajorDimension string `json:"majorDimension,omitempty"`

	// ValueRenderOption: How values should be represented in the output.
	// The default render option is ValueRenderOption.FORMATTED_VALUE.
	//
	// Possible values:
	//   "FORMATTED_VALUE" - Values will be calculated & formatted in the
	// reply according to the cell's formatting. Formatting is based on the
	// spreadsheet's locale, not the requesting user's locale. For example,
	// if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then
	// `A2` would return "$1.23".
	//   "UNFORMATTED_VALUE" - Values will be calculated, but not formatted
	// in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and
	// formatted as currency, then `A2` would return the number `1.23`.
	//   "FORMULA" - Values will not be calculated. The reply will include
	// the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and
	// formatted as currency, then A2 would return "=A1".
	ValueRenderOption string `json:"valueRenderOption,omitempty"`

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

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

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

// BatchGetValuesByDataFilterResponse: The response when retrieving more
// than one range of values in a spreadsheet selected by DataFilters.
type BatchGetValuesByDataFilterResponse struct {
	// SpreadsheetId: The ID of the spreadsheet the data was retrieved from.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ValueRanges: The requested values with the list of data filters that
	// matched them.
	ValueRanges []*MatchedValueRange `json:"valueRanges,omitempty"`

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

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

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

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

// BatchGetValuesResponse: The response when retrieving more than one
// range of values in a spreadsheet.
type BatchGetValuesResponse struct {
	// SpreadsheetId: The ID of the spreadsheet the data was retrieved from.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ValueRanges: The requested values. The order of the ValueRanges is
	// the same as the order of the requested ranges.
	ValueRanges []*ValueRange `json:"valueRanges,omitempty"`

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

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

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

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

// BatchUpdateSpreadsheetRequest: The request for updating any aspect of
// a spreadsheet.
type BatchUpdateSpreadsheetRequest struct {
	// IncludeSpreadsheetInResponse: Determines if the update response
	// should include the spreadsheet resource.
	IncludeSpreadsheetInResponse bool `json:"includeSpreadsheetInResponse,omitempty"`

	// Requests: A list of updates to apply to the spreadsheet. Requests
	// will be applied in the order they are specified. If any request is
	// not valid, no requests will be applied.
	Requests []*Request `json:"requests,omitempty"`

	// ResponseIncludeGridData: True if grid data should be returned.
	// Meaningful only if include_spreadsheet_in_response is 'true'. This
	// parameter is ignored if a field mask was set in the request.
	ResponseIncludeGridData bool `json:"responseIncludeGridData,omitempty"`

	// ResponseRanges: Limits the ranges included in the response
	// spreadsheet. Meaningful only if include_spreadsheet_in_response is
	// 'true'.
	ResponseRanges []string `json:"responseRanges,omitempty"`

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

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

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

// BatchUpdateSpreadsheetResponse: The reply for batch updating a
// spreadsheet.
type BatchUpdateSpreadsheetResponse struct {
	// Replies: The reply of the updates. This maps 1:1 with the updates,
	// although replies to some requests may be empty.
	Replies []*Response `json:"replies,omitempty"`

	// SpreadsheetId: The spreadsheet the updates were applied to.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// UpdatedSpreadsheet: The spreadsheet after updates were applied. This
	// is only set if
	// [BatchUpdateSpreadsheetRequest.include_spreadsheet_in_response] is
	// `true`.
	UpdatedSpreadsheet *Spreadsheet `json:"updatedSpreadsheet,omitempty"`

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

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

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

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

// BatchUpdateValuesByDataFilterRequest: The request for updating more
// than one range of values in a spreadsheet.
type BatchUpdateValuesByDataFilterRequest struct {
	// Data: The new values to apply to the spreadsheet. If more than one
	// range is matched by the specified DataFilter the specified values are
	// applied to all of those ranges.
	Data []*DataFilterValueRange `json:"data,omitempty"`

	// IncludeValuesInResponse: Determines if the update response should
	// include the values of the cells that were updated. By default,
	// responses do not include the updated values. The `updatedData` field
	// within each of the BatchUpdateValuesResponse.responses contains the
	// updated values. If the range to write was larger than the range
	// actually written, the response includes all values in the requested
	// range (excluding trailing empty rows and columns).
	IncludeValuesInResponse bool `json:"includeValuesInResponse,omitempty"`

	// ResponseDateTimeRenderOption: Determines how dates, times, and
	// durations in the response should be rendered. This is ignored if
	// response_value_render_option is FORMATTED_VALUE. The default dateTime
	// render option is DateTimeRenderOption.SERIAL_NUMBER.
	//
	// Possible values:
	//   "SERIAL_NUMBER" - Instructs date, time, datetime, and duration
	// fields to be output as doubles in "serial number" format, as
	// popularized by Lotus 1-2-3. The whole number portion of the value
	// (left of the decimal) counts the days since December 30th 1899. The
	// fractional portion (right of the decimal) counts the time as a
	// fraction of the day. For example, January 1st 1900 at noon would be
	// 2.5, 2 because it's 2 days after December 30st 1899, and .5 because
	// noon is half a day. February 1st 1900 at 3pm would be 33.625. This
	// correctly treats the year 1900 as not a leap year.
	//   "FORMATTED_STRING" - Instructs date, time, datetime, and duration
	// fields to be output as strings in their given number format (which is
	// dependent on the spreadsheet locale).
	ResponseDateTimeRenderOption string `json:"responseDateTimeRenderOption,omitempty"`

	// ResponseValueRenderOption: Determines how values in the response
	// should be rendered. The default render option is
	// ValueRenderOption.FORMATTED_VALUE.
	//
	// Possible values:
	//   "FORMATTED_VALUE" - Values will be calculated & formatted in the
	// reply according to the cell's formatting. Formatting is based on the
	// spreadsheet's locale, not the requesting user's locale. For example,
	// if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then
	// `A2` would return "$1.23".
	//   "UNFORMATTED_VALUE" - Values will be calculated, but not formatted
	// in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and
	// formatted as currency, then `A2` would return the number `1.23`.
	//   "FORMULA" - Values will not be calculated. The reply will include
	// the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and
	// formatted as currency, then A2 would return "=A1".
	ResponseValueRenderOption string `json:"responseValueRenderOption,omitempty"`

	// ValueInputOption: How the input data should be interpreted.
	//
	// Possible values:
	//   "INPUT_VALUE_OPTION_UNSPECIFIED" - Default input value. This value
	// must not be used.
	//   "RAW" - The values the user has entered will not be parsed and will
	// be stored as-is.
	//   "USER_ENTERED" - The values will be parsed as if the user typed
	// them into the UI. Numbers will stay as numbers, but strings may be
	// converted to numbers, dates, etc. following the same rules that are
	// applied when entering text into a cell via the Google Sheets UI.
	ValueInputOption string `json:"valueInputOption,omitempty"`

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

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

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

// BatchUpdateValuesByDataFilterResponse: The response when updating a
// range of values in a spreadsheet.
type BatchUpdateValuesByDataFilterResponse struct {
	// Responses: The response for each range updated.
	Responses []*UpdateValuesByDataFilterResponse `json:"responses,omitempty"`

	// SpreadsheetId: The spreadsheet the updates were applied to.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// TotalUpdatedCells: The total number of cells updated.
	TotalUpdatedCells int64 `json:"totalUpdatedCells,omitempty"`

	// TotalUpdatedColumns: The total number of columns where at least one
	// cell in the column was updated.
	TotalUpdatedColumns int64 `json:"totalUpdatedColumns,omitempty"`

	// TotalUpdatedRows: The total number of rows where at least one cell in
	// the row was updated.
	TotalUpdatedRows int64 `json:"totalUpdatedRows,omitempty"`

	// TotalUpdatedSheets: The total number of sheets where at least one
	// cell in the sheet was updated.
	TotalUpdatedSheets int64 `json:"totalUpdatedSheets,omitempty"`

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

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

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

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

// BatchUpdateValuesRequest: The request for updating more than one
// range of values in a spreadsheet.
type BatchUpdateValuesRequest struct {
	// Data: The new values to apply to the spreadsheet.
	Data []*ValueRange `json:"data,omitempty"`

	// IncludeValuesInResponse: Determines if the update response should
	// include the values of the cells that were updated. By default,
	// responses do not include the updated values. The `updatedData` field
	// within each of the BatchUpdateValuesResponse.responses contains the
	// updated values. If the range to write was larger than the range
	// actually written, the response includes all values in the requested
	// range (excluding trailing empty rows and columns).
	IncludeValuesInResponse bool `json:"includeValuesInResponse,omitempty"`

	// ResponseDateTimeRenderOption: Determines how dates, times, and
	// durations in the response should be rendered. This is ignored if
	// response_value_render_option is FORMATTED_VALUE. The default dateTime
	// render option is DateTimeRenderOption.SERIAL_NUMBER.
	//
	// Possible values:
	//   "SERIAL_NUMBER" - Instructs date, time, datetime, and duration
	// fields to be output as doubles in "serial number" format, as
	// popularized by Lotus 1-2-3. The whole number portion of the value
	// (left of the decimal) counts the days since December 30th 1899. The
	// fractional portion (right of the decimal) counts the time as a
	// fraction of the day. For example, January 1st 1900 at noon would be
	// 2.5, 2 because it's 2 days after December 30st 1899, and .5 because
	// noon is half a day. February 1st 1900 at 3pm would be 33.625. This
	// correctly treats the year 1900 as not a leap year.
	//   "FORMATTED_STRING" - Instructs date, time, datetime, and duration
	// fields to be output as strings in their given number format (which is
	// dependent on the spreadsheet locale).
	ResponseDateTimeRenderOption string `json:"responseDateTimeRenderOption,omitempty"`

	// ResponseValueRenderOption: Determines how values in the response
	// should be rendered. The default render option is
	// ValueRenderOption.FORMATTED_VALUE.
	//
	// Possible values:
	//   "FORMATTED_VALUE" - Values will be calculated & formatted in the
	// reply according to the cell's formatting. Formatting is based on the
	// spreadsheet's locale, not the requesting user's locale. For example,
	// if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then
	// `A2` would return "$1.23".
	//   "UNFORMATTED_VALUE" - Values will be calculated, but not formatted
	// in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and
	// formatted as currency, then `A2` would return the number `1.23`.
	//   "FORMULA" - Values will not be calculated. The reply will include
	// the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and
	// formatted as currency, then A2 would return "=A1".
	ResponseValueRenderOption string `json:"responseValueRenderOption,omitempty"`

	// ValueInputOption: How the input data should be interpreted.
	//
	// Possible values:
	//   "INPUT_VALUE_OPTION_UNSPECIFIED" - Default input value. This value
	// must not be used.
	//   "RAW" - The values the user has entered will not be parsed and will
	// be stored as-is.
	//   "USER_ENTERED" - The values will be parsed as if the user typed
	// them into the UI. Numbers will stay as numbers, but strings may be
	// converted to numbers, dates, etc. following the same rules that are
	// applied when entering text into a cell via the Google Sheets UI.
	ValueInputOption string `json:"valueInputOption,omitempty"`

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

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

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

// BatchUpdateValuesResponse: The response when updating a range of
// values in a spreadsheet.
type BatchUpdateValuesResponse struct {
	// Responses: One UpdateValuesResponse per requested range, in the same
	// order as the requests appeared.
	Responses []*UpdateValuesResponse `json:"responses,omitempty"`

	// SpreadsheetId: The spreadsheet the updates were applied to.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// TotalUpdatedCells: The total number of cells updated.
	TotalUpdatedCells int64 `json:"totalUpdatedCells,omitempty"`

	// TotalUpdatedColumns: The total number of columns where at least one
	// cell in the column was updated.
	TotalUpdatedColumns int64 `json:"totalUpdatedColumns,omitempty"`

	// TotalUpdatedRows: The total number of rows where at least one cell in
	// the row was updated.
	TotalUpdatedRows int64 `json:"totalUpdatedRows,omitempty"`

	// TotalUpdatedSheets: The total number of sheets where at least one
	// cell in the sheet was updated.
	TotalUpdatedSheets int64 `json:"totalUpdatedSheets,omitempty"`

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

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

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

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

// BigQueryDataSourceSpec: The specification of a BigQuery data source.
type BigQueryDataSourceSpec struct {
	// ProjectId: The ID of a BigQuery enabled GCP project with a billing
	// account attached. For any queries executed against the data source,
	// the project is charged.
	ProjectId string `json:"projectId,omitempty"`

	// QuerySpec: A BigQueryQuerySpec.
	QuerySpec *BigQueryQuerySpec `json:"querySpec,omitempty"`

	// TableSpec: A BigQueryTableSpec.
	TableSpec *BigQueryTableSpec `json:"tableSpec,omitempty"`

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

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

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

// BigQueryQuerySpec: Specifies a custom BigQuery query.
type BigQueryQuerySpec struct {
	// RawQuery: The raw query string.
	RawQuery string `json:"rawQuery,omitempty"`

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

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

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

// BigQueryTableSpec: Specifies a BigQuery table definition. Only native
// tables is allowed.
type BigQueryTableSpec struct {
	// DatasetId: The BigQuery dataset id.
	DatasetId string `json:"datasetId,omitempty"`

	// TableId: The BigQuery table id.
	TableId string `json:"tableId,omitempty"`

	// TableProjectId: The ID of a BigQuery project the table belongs to. If
	// not specified, the project_id is assumed.
	TableProjectId string `json:"tableProjectId,omitempty"`

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

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

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

// BooleanCondition: A condition that can evaluate to true or false.
// BooleanConditions are used by conditional formatting, data
// validation, and the criteria in filters.
type BooleanCondition struct {
	// Type: The type of condition.
	//
	// Possible values:
	//   "CONDITION_TYPE_UNSPECIFIED" - The default value, do not use.
	//   "NUMBER_GREATER" - The cell's value must be greater than the
	// condition's value. Supported by data validation, conditional
	// formatting and filters. Requires a single ConditionValue.
	//   "NUMBER_GREATER_THAN_EQ" - The cell's value must be greater than or
	// equal to the condition's value. Supported by data validation,
	// conditional formatting and filters. Requires a single ConditionValue.
	//   "NUMBER_LESS" - The cell's value must be less than the condition's
	// value. Supported by data validation, conditional formatting and
	// filters. Requires a single ConditionValue.
	//   "NUMBER_LESS_THAN_EQ" - The cell's value must be less than or equal
	// to the condition's value. Supported by data validation, conditional
	// formatting and filters. Requires a single ConditionValue.
	//   "NUMBER_EQ" - The cell's value must be equal to the condition's
	// value. Supported by data validation, conditional formatting and
	// filters. Requires a single ConditionValue.
	//   "NUMBER_NOT_EQ" - The cell's value must be not equal to the
	// condition's value. Supported by data validation, conditional
	// formatting and filters. Requires a single ConditionValue.
	//   "NUMBER_BETWEEN" - The cell's value must be between the two
	// condition values. Supported by data validation, conditional
	// formatting and filters. Requires exactly two ConditionValues.
	//   "NUMBER_NOT_BETWEEN" - The cell's value must not be between the two
	// condition values. Supported by data validation, conditional
	// formatting and filters. Requires exactly two ConditionValues.
	//   "TEXT_CONTAINS" - The cell's value must contain the condition's
	// value. Supported by data validation, conditional formatting and
	// filters. Requires a single ConditionValue.
	//   "TEXT_NOT_CONTAINS" - The cell's value must not contain the
	// condition's value. Supported by data validation, conditional
	// formatting and filters. Requires a single ConditionValue.
	//   "TEXT_STARTS_WITH" - The cell's value must start with the
	// condition's value. Supported by conditional formatting and filters.
	// Requires a single ConditionValue.
	//   "TEXT_ENDS_WITH" - The cell's value must end with the condition's
	// value. Supported by conditional formatting and filters. Requires a
	// single ConditionValue.
	//   "TEXT_EQ" - The cell's value must be exactly the condition's value.
	// Supported by data validation, conditional formatting and filters.
	// Requires a single ConditionValue.
	//   "TEXT_IS_EMAIL" - The cell's value must be a valid email address.
	// Supported by data validation. Requires no ConditionValues.
	//   "TEXT_IS_URL" - The cell's value must be a valid URL. Supported by
	// data validation. Requires no ConditionValues.
	//   "DATE_EQ" - The cell's value must be the same date as the
	// condition's value. Supported by data validation, conditional
	// formatting and filters. Requires a single ConditionValue.
	//   "DATE_BEFORE" - The cell's value must be before the date of the
	// condition's value. Supported by data validation, conditional
	// formatting and filters. Requires a single ConditionValue that may be
	// a relative date.
	//   "DATE_AFTER" - The cell's value must be after the date of the
	// condition's value. Supported by data validation, conditional
	// formatting and filters. Requires a single ConditionValue that may be
	// a relative date.
	//   "DATE_ON_OR_BEFORE" - The cell's value must be on or before the
	// date of the condition's value. Supported by data validation. Requires
	// a single ConditionValue that may be a relative date.
	//   "DATE_ON_OR_AFTER" - The cell's value must be on or after the date
	// of the condition's value. Supported by data validation. Requires a
	// single ConditionValue that may be a relative date.
	//   "DATE_BETWEEN" - The cell's value must be between the dates of the
	// two condition values. Supported by data validation. Requires exactly
	// two ConditionValues.
	//   "DATE_NOT_BETWEEN" - The cell's value must be outside the dates of
	// the two condition values. Supported by data validation. Requires
	// exactly two ConditionValues.
	//   "DATE_IS_VALID" - The cell's value must be a date. Supported by
	// data validation. Requires no ConditionValues.
	//   "ONE_OF_RANGE" - The cell's value must be listed in the grid in
	// condition value's range. Supported by data validation. Requires a
	// single ConditionValue, and the value must be a valid range in A1
	// notation.
	//   "ONE_OF_LIST" - The cell's value must be in the list of condition
	// values. Supported by data validation. Supports any number of
	// condition values, one per item in the list. Formulas are not
	// supported in the values.
	//   "BLANK" - The cell's value must be empty. Supported by conditional
	// formatting and filters. Requires no ConditionValues.
	//   "NOT_BLANK" - The cell's value must not be empty. Supported by
	// conditional formatting and filters. Requires no ConditionValues.
	//   "CUSTOM_FORMULA" - The condition's formula must evaluate to true.
	// Supported by data validation, conditional formatting and filters.
	// Requires a single ConditionValue.
	//   "BOOLEAN" - The cell's value must be TRUE/FALSE or in the list of
	// condition values. Supported by data validation. Renders as a cell
	// checkbox. Supports zero, one or two ConditionValues. No values
	// indicates the cell must be TRUE or FALSE, where TRUE renders as
	// checked and FALSE renders as unchecked. One value indicates the cell
	// will render as checked when it contains that value and unchecked when
	// it is blank. Two values indicate that the cell will render as checked
	// when it contains the first value and unchecked when it contains the
	// second value. For example, ["Yes","No"] indicates that the cell will
	// render a checked box when it has the value "Yes" and an unchecked box
	// when it has the value "No".
	//   "TEXT_NOT_EQ" - The cell's value must be exactly not the
	// condition's value. Supported by filters on data source objects.
	// Requires at least one ConditionValue.
	//   "DATE_NOT_EQ" - The cell's value must be exactly not the
	// condition's value. Supported by filters on data source objects.
	// Requires at least one ConditionValue.
	Type string `json:"type,omitempty"`

	// Values: The values of the condition. The number of supported values
	// depends on the condition type. Some support zero values, others one
	// or two values, and ConditionType.ONE_OF_LIST supports an arbitrary
	// number of values.
	Values []*ConditionValue `json:"values,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 *BooleanCondition) MarshalJSON() ([]byte, error) {
	type NoMethod BooleanCondition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BooleanRule: A rule that may or may not match, depending on the
// condition.
type BooleanRule struct {
	// Condition: The condition of the rule. If the condition evaluates to
	// true, the format is applied.
	Condition *BooleanCondition `json:"condition,omitempty"`

	// Format: The format to apply. Conditional formatting can only apply a
	// subset of formatting: bold, italic, strikethrough, foreground color &
	// background color.
	Format *CellFormat `json:"format,omitempty"`

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

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

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

// Border: A border along a cell.
type Border struct {
	// Color: The color of the border.
	Color *Color `json:"color,omitempty"`

	// ColorStyle: The color of the border. If color is also set, this field
	// takes precedence.
	ColorStyle *ColorStyle `json:"colorStyle,omitempty"`

	// Style: The style of the border.
	//
	// Possible values:
	//   "STYLE_UNSPECIFIED" - The style is not specified. Do not use this.
	//   "DOTTED" - The border is dotted.
	//   "DASHED" - The border is dashed.
	//   "SOLID" - The border is a thin solid line.
	//   "SOLID_MEDIUM" - The border is a medium solid line.
	//   "SOLID_THICK" - The border is a thick solid line.
	//   "NONE" - No border. Used only when updating a border in order to
	// erase it.
	//   "DOUBLE" - The border is two solid lines.
	Style string `json:"style,omitempty"`

	// Width: The width of the border, in pixels. Deprecated; the width is
	// determined by the "style" field.
	Width int64 `json:"width,omitempty"`

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

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

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

// Borders: The borders of the cell.
type Borders struct {
	// Bottom: The bottom border of the cell.
	Bottom *Border `json:"bottom,omitempty"`

	// Left: The left border of the cell.
	Left *Border `json:"left,omitempty"`

	// Right: The right border of the cell.
	Right *Border `json:"right,omitempty"`

	// Top: The top border of the cell.
	Top *Border `json:"top,omitempty"`

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

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

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

// BubbleChartSpec: A bubble chart.
type BubbleChartSpec struct {
	// BubbleBorderColor: The bubble border color.
	BubbleBorderColor *Color `json:"bubbleBorderColor,omitempty"`

	// BubbleBorderColorStyle: The bubble border color. If
	// bubble_border_color is also set, this field takes precedence.
	BubbleBorderColorStyle *ColorStyle `json:"bubbleBorderColorStyle,omitempty"`

	// BubbleLabels: The data containing the bubble labels. These do not
	// need to be unique.
	BubbleLabels *ChartData `json:"bubbleLabels,omitempty"`

	// BubbleMaxRadiusSize: The max radius size of the bubbles, in pixels.
	// If specified, the field must be a positive value.
	BubbleMaxRadiusSize int64 `json:"bubbleMaxRadiusSize,omitempty"`

	// BubbleMinRadiusSize: The minimum radius size of the bubbles, in
	// pixels. If specific, the field must be a positive value.
	BubbleMinRadiusSize int64 `json:"bubbleMinRadiusSize,omitempty"`

	// BubbleOpacity: The opacity of the bubbles between 0 and 1.0. 0 is
	// fully transparent and 1 is fully opaque.
	BubbleOpacity float64 `json:"bubbleOpacity,omitempty"`

	// BubbleSizes: The data contianing the bubble sizes. Bubble sizes are
	// used to draw the bubbles at different sizes relative to each other.
	// If specified, group_ids must also be specified. This field is
	// optional.
	BubbleSizes *ChartData `json:"bubbleSizes,omitempty"`

	// BubbleTextStyle: The format of the text inside the bubbles. Underline
	// and Strikethrough are not supported.
	BubbleTextStyle *TextFormat `json:"bubbleTextStyle,omitempty"`

	// Domain: The data containing the bubble x-values. These values locate
	// the bubbles in the chart horizontally.
	Domain *ChartData `json:"domain,omitempty"`

	// GroupIds: The data containing the bubble group IDs. All bubbles with
	// the same group ID are drawn in the same color. If bubble_sizes is
	// specified then this field must also be specified but may contain
	// blank values. This field is optional.
	GroupIds *ChartData `json:"groupIds,omitempty"`

	// LegendPosition: Where the legend of the chart should be drawn.
	//
	// Possible values:
	//   "BUBBLE_CHART_LEGEND_POSITION_UNSPECIFIED" - Default value, do not
	// use.
	//   "BOTTOM_LEGEND" - The legend is rendered on the bottom of the
	// chart.
	//   "LEFT_LEGEND" - The legend is rendered on the left of the chart.
	//   "RIGHT_LEGEND" - The legend is rendered on the right of the chart.
	//   "TOP_LEGEND" - The legend is rendered on the top of the chart.
	//   "NO_LEGEND" - No legend is rendered.
	//   "INSIDE_LEGEND" - The legend is rendered inside the chart area.
	LegendPosition string `json:"legendPosition,omitempty"`

	// Series: The data contianing the bubble y-values. These values locate
	// the bubbles in the chart vertically.
	Series *ChartData `json:"series,omitempty"`

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

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

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

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

// CandlestickChartSpec: A candlestick chart.
type CandlestickChartSpec struct {
	// Data: The Candlestick chart data. Only one CandlestickData is
	// supported.
	Data []*CandlestickData `json:"data,omitempty"`

	// Domain: The domain data (horizontal axis) for the candlestick chart.
	// String data will be treated as discrete labels, other data will be
	// treated as continuous values.
	Domain *CandlestickDomain `json:"domain,omitempty"`

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

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

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

// CandlestickData: The Candlestick chart data, each containing the low,
// open, close, and high values for a series.
type CandlestickData struct {
	// CloseSeries: The range data (vertical axis) for the close/final value
	// for each candle. This is the top of the candle body. If greater than
	// the open value the candle will be filled. Otherwise the candle will
	// be hollow.
	CloseSeries *CandlestickSeries `json:"closeSeries,omitempty"`

	// HighSeries: The range data (vertical axis) for the high/maximum value
	// for each candle. This is the top of the candle's center line.
	HighSeries *CandlestickSeries `json:"highSeries,omitempty"`

	// LowSeries: The range data (vertical axis) for the low/minimum value
	// for each candle. This is the bottom of the candle's center line.
	LowSeries *CandlestickSeries `json:"lowSeries,omitempty"`

	// OpenSeries: The range data (vertical axis) for the open/initial value
	// for each candle. This is the bottom of the candle body. If less than
	// the close value the candle will be filled. Otherwise the candle will
	// be hollow.
	OpenSeries *CandlestickSeries `json:"openSeries,omitempty"`

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

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

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

// CandlestickDomain: The domain of a CandlestickChart.
type CandlestickDomain struct {
	// Data: The data of the CandlestickDomain.
	Data *ChartData `json:"data,omitempty"`

	// Reversed: True to reverse the order of the domain values (horizontal
	// axis).
	Reversed bool `json:"reversed,omitempty"`

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

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

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

// CandlestickSeries: The series of a CandlestickData.
type CandlestickSeries struct {
	// Data: The data of the CandlestickSeries.
	Data *ChartData `json:"data,omitempty"`

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

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

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

// CellData: Data about a specific cell.
type CellData struct {
	// DataSourceFormula: Output only. Information about a data source
	// formula on the cell. The field is set if user_entered_value is a
	// formula referencing some [SheetType.DATA_SOURCE] sheet, e.g
	// `=SUM(DataSheet!Column)`.
	DataSourceFormula *DataSourceFormula `json:"dataSourceFormula,omitempty"`

	// DataSourceTable: A data source table anchored at this cell. The size
	// of data source table itself is computed dynamically based on its
	// configuration. Only the first cell of the data source table contains
	// the data source table definition. The other cells will contain the
	// display values of the data source table result in their
	// effective_value fields.
	DataSourceTable *DataSourceTable `json:"dataSourceTable,omitempty"`

	// DataValidation: A data validation rule on the cell, if any. When
	// writing, the new data validation rule will overwrite any prior rule.
	DataValidation *DataValidationRule `json:"dataValidation,omitempty"`

	// EffectiveFormat: The effective format being used by the cell. This
	// includes the results of applying any conditional formatting and, if
	// the cell contains a formula, the computed number format. If the
	// effective format is the default format, effective format will not be
	// written. This field is read-only.
	EffectiveFormat *CellFormat `json:"effectiveFormat,omitempty"`

	// EffectiveValue: The effective value of the cell. For cells with
	// formulas, this is the calculated value. For cells with literals, this
	// is the same as the user_entered_value. This field is read-only.
	EffectiveValue *ExtendedValue `json:"effectiveValue,omitempty"`

	// FormattedValue: The formatted value of the cell. This is the value as
	// it's shown to the user. This field is read-only.
	FormattedValue string `json:"formattedValue,omitempty"`

	// Hyperlink: A hyperlink this cell points to, if any. This field is
	// read-only. (To set it, use a `=HYPERLINK` formula in the
	// userEnteredValue.formulaValue field.)
	Hyperlink string `json:"hyperlink,omitempty"`

	// Note: Any note on the cell.
	Note string `json:"note,omitempty"`

	// PivotTable: A pivot table anchored at this cell. The size of pivot
	// table itself is computed dynamically based on its data, grouping,
	// filters, values, etc. Only the top-left cell of the pivot table
	// contains the pivot table definition. The other cells will contain the
	// calculated values of the results of the pivot in their
	// effective_value fields.
	PivotTable *PivotTable `json:"pivotTable,omitempty"`

	// TextFormatRuns: Runs of rich text applied to subsections of the cell.
	// Runs are only valid on user entered strings, not formulas, bools, or
	// numbers. Runs start at specific indexes in the text and continue
	// until the next run. Properties of a run will continue unless
	// explicitly changed in a subsequent run (and properties of the first
	// run will continue the properties of the cell unless explicitly
	// changed). When writing, the new runs will overwrite any prior runs.
	// When writing a new user_entered_value, previous runs are erased.
	TextFormatRuns []*TextFormatRun `json:"textFormatRuns,omitempty"`

	// UserEnteredFormat: The format the user entered for the cell. When
	// writing, the new format will be merged with the existing format.
	UserEnteredFormat *CellFormat `json:"userEnteredFormat,omitempty"`

	// UserEnteredValue: The value the user entered in the cell. e.g,
	// `1234`, `'Hello'`, or `=NOW()` Note: Dates, Times and DateTimes are
	// represented as doubles in serial number format.
	UserEnteredValue *ExtendedValue `json:"userEnteredValue,omitempty"`

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

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

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

// CellFormat: The format of a cell.
type CellFormat struct {
	// BackgroundColor: The background color of the cell.
	BackgroundColor *Color `json:"backgroundColor,omitempty"`

	// BackgroundColorStyle: The background color of the cell. If
	// background_color is also set, this field takes precedence.
	BackgroundColorStyle *ColorStyle `json:"backgroundColorStyle,omitempty"`

	// Borders: The borders of the cell.
	Borders *Borders `json:"borders,omitempty"`

	// HorizontalAlignment: The horizontal alignment of the value in the
	// cell.
	//
	// Possible values:
	//   "HORIZONTAL_ALIGN_UNSPECIFIED" - The horizontal alignment is not
	// specified. Do not use this.
	//   "LEFT" - The text is explicitly aligned to the left of the cell.
	//   "CENTER" - The text is explicitly aligned to the center of the
	// cell.
	//   "RIGHT" - The text is explicitly aligned to the right of the cell.
	HorizontalAlignment string `json:"horizontalAlignment,omitempty"`

	// HyperlinkDisplayType: How a hyperlink, if it exists, should be
	// displayed in the cell.
	//
	// Possible values:
	//   "HYPERLINK_DISPLAY_TYPE_UNSPECIFIED" - The default value: the
	// hyperlink is rendered. Do not use this.
	//   "LINKED" - A hyperlink should be explicitly rendered.
	//   "PLAIN_TEXT" - A hyperlink should not be rendered.
	HyperlinkDisplayType string `json:"hyperlinkDisplayType,omitempty"`

	// NumberFormat: A format describing how number values should be
	// represented to the user.
	NumberFormat *NumberFormat `json:"numberFormat,omitempty"`

	// Padding: The padding of the cell.
	Padding *Padding `json:"padding,omitempty"`

	// TextDirection: The direction of the text in the cell.
	//
	// Possible values:
	//   "TEXT_DIRECTION_UNSPECIFIED" - The text direction is not specified.
	// Do not use this.
	//   "LEFT_TO_RIGHT" - The text direction of left-to-right was set by
	// the user.
	//   "RIGHT_TO_LEFT" - The text direction of right-to-left was set by
	// the user.
	TextDirection string `json:"textDirection,omitempty"`

	// TextFormat: The format of the text in the cell (unless overridden by
	// a format run).
	TextFormat *TextFormat `json:"textFormat,omitempty"`

	// TextRotation: The rotation applied to text in a cell
	TextRotation *TextRotation `json:"textRotation,omitempty"`

	// VerticalAlignment: The vertical alignment of the value in the cell.
	//
	// Possible values:
	//   "VERTICAL_ALIGN_UNSPECIFIED" - The vertical alignment is not
	// specified. Do not use this.
	//   "TOP" - The text is explicitly aligned to the top of the cell.
	//   "MIDDLE" - The text is explicitly aligned to the middle of the
	// cell.
	//   "BOTTOM" - The text is explicitly aligned to the bottom of the
	// cell.
	VerticalAlignment string `json:"verticalAlignment,omitempty"`

	// WrapStrategy: The wrap strategy for the value in the cell.
	//
	// Possible values:
	//   "WRAP_STRATEGY_UNSPECIFIED" - The default value, do not use.
	//   "OVERFLOW_CELL" - Lines that are longer than the cell width will be
	// written in the next cell over, so long as that cell is empty. If the
	// next cell over is non-empty, this behaves the same as CLIP. The text
	// will never wrap to the next line unless the user manually inserts a
	// new line. Example: | First sentence. | | Manual newline that is very
	// long. <- Text continues into next cell | Next newline. |
	//   "LEGACY_WRAP" - This wrap strategy represents the old Google Sheets
	// wrap strategy where words that are longer than a line are clipped
	// rather than broken. This strategy is not supported on all platforms
	// and is being phased out. Example: | Cell has a | | loooooooooo| <-
	// Word is clipped. | word. |
	//   "CLIP" - Lines that are longer than the cell width will be clipped.
	// The text will never wrap to the next line unless the user manually
	// inserts a new line. Example: | First sentence. | | Manual newline t|
	// <- Text is clipped | Next newline. |
	//   "WRAP" - Words that are longer than a line are wrapped at the
	// character level rather than clipped. Example: | Cell has a | |
	// loooooooooo| <- Word is broken. | ong word. |
	WrapStrategy string `json:"wrapStrategy,omitempty"`

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

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

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

// ChartAxisViewWindowOptions: The options that define a "view window"
// for a chart (such as the visible values in an axis).
type ChartAxisViewWindowOptions struct {
	// ViewWindowMax: The maximum numeric value to be shown in this view
	// window. If unset, will automatically determine a maximum value that
	// looks good for the data.
	ViewWindowMax float64 `json:"viewWindowMax,omitempty"`

	// ViewWindowMin: The minimum numeric value to be shown in this view
	// window. If unset, will automatically determine a minimum value that
	// looks good for the data.
	ViewWindowMin float64 `json:"viewWindowMin,omitempty"`

	// ViewWindowMode: The view window's mode.
	//
	// Possible values:
	//   "DEFAULT_VIEW_WINDOW_MODE" - The default view window mode used in
	// the Sheets editor for this chart type. In most cases, if set, the
	// default mode is equivalent to `PRETTY`.
	//   "VIEW_WINDOW_MODE_UNSUPPORTED" - Do not use. Represents that the
	// currently set mode is not supported by the API.
	//   "EXPLICIT" - Follows the min and max exactly if specified. If a
	// value is unspecified, it will fall back to the `PRETTY` value.
	//   "PRETTY" - Chooses a min and max that make the chart look good.
	// Both min and max are ignored in this mode.
	ViewWindowMode string `json:"viewWindowMode,omitempty"`

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

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

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

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

// ChartCustomNumberFormatOptions: Custom number formatting options for
// chart attributes.
type ChartCustomNumberFormatOptions struct {
	// Prefix: Custom prefix to be prepended to the chart attribute. This
	// field is optional.
	Prefix string `json:"prefix,omitempty"`

	// Suffix: Custom suffix to be appended to the chart attribute. This
	// field is optional.
	Suffix string `json:"suffix,omitempty"`

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

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

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

// ChartData: The data included in a domain or series.
type ChartData struct {
	// AggregateType: The aggregation type for the series of a data source
	// chart. Not supported for regular charts.
	//
	// Possible values:
	//   "CHART_AGGREGATE_TYPE_UNSPECIFIED" - Default value, do not use.
	//   "AVERAGE" - Average aggregate function.
	//   "COUNT" - Count aggregate function.
	//   "MAX" - Maximum aggregate function.
	//   "MEDIAN" - Median aggregate function.
	//   "MIN" - Minimum aggregate function.
	//   "SUM" - Sum aggregate function.
	AggregateType string `json:"aggregateType,omitempty"`

	// ColumnReference: The reference to the data source column that the
	// data reads from.
	ColumnReference *DataSourceColumnReference `json:"columnReference,omitempty"`

	// GroupRule: The rule to group the data by if the ChartData backs the
	// domain of a data source chart. Not supported for regular charts.
	GroupRule *ChartGroupRule `json:"groupRule,omitempty"`

	// SourceRange: The source ranges of the data.
	SourceRange *ChartSourceRange `json:"sourceRange,omitempty"`

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

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

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

// ChartDateTimeRule: Allows you to organize the date-time values in a
// source data column into buckets based on selected parts of their date
// or time values.
type ChartDateTimeRule struct {
	// Type: The type of date-time grouping to apply.
	//
	// Possible values:
	//   "CHART_DATE_TIME_RULE_TYPE_UNSPECIFIED" - The default type, do not
	// use.
	//   "SECOND" - Group dates by second, from 0 to 59.
	//   "MINUTE" - Group dates by minute, from 0 to 59.
	//   "HOUR" - Group dates by hour using a 24-hour system, from 0 to 23.
	//   "HOUR_MINUTE" - Group dates by hour and minute using a 24-hour
	// system, for example 19:45.
	//   "HOUR_MINUTE_AMPM" - Group dates by hour and minute using a 12-hour
	// system, for example 7:45 PM. The AM/PM designation is translated
	// based on the spreadsheet locale.
	//   "DAY_OF_WEEK" - Group dates by day of week, for example Sunday. The
	// days of the week will be translated based on the spreadsheet locale.
	//   "DAY_OF_YEAR" - Group dates by day of year, from 1 to 366. Note
	// that dates after Feb. 29 fall in different buckets in leap years than
	// in non-leap years.
	//   "DAY_OF_MONTH" - Group dates by day of month, from 1 to 31.
	//   "DAY_MONTH" - Group dates by day and month, for example 22-Nov. The
	// month is translated based on the spreadsheet locale.
	//   "MONTH" - Group dates by month, for example Nov. The month is
	// translated based on the spreadsheet locale.
	//   "QUARTER" - Group dates by quarter, for example Q1 (which
	// represents Jan-Mar).
	//   "YEAR" - Group dates by year, for example 2008.
	//   "YEAR_MONTH" - Group dates by year and month, for example 2008-Nov.
	// The month is translated based on the spreadsheet locale.
	//   "YEAR_QUARTER" - Group dates by year and quarter, for example 2008
	// Q4.
	//   "YEAR_MONTH_DAY" - Group dates by year, month, and day, for example
	// 2008-11-22.
	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 *ChartDateTimeRule) MarshalJSON() ([]byte, error) {
	type NoMethod ChartDateTimeRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ChartGroupRule: An optional setting on the ChartData of the domain of
// a data source chart that defines buckets for the values in the domain
// rather than breaking out each individual value. For example, when
// plotting a data source chart, you can specify a histogram rule on the
// domain (it should only contain numeric values), grouping its values
// into buckets. Any values of a chart series that fall into the same
// bucket are aggregated based on the aggregate_type.
type ChartGroupRule struct {
	// DateTimeRule: A ChartDateTimeRule.
	DateTimeRule *ChartDateTimeRule `json:"dateTimeRule,omitempty"`

	// HistogramRule: A ChartHistogramRule
	HistogramRule *ChartHistogramRule `json:"histogramRule,omitempty"`

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

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

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

// ChartHistogramRule: Allows you to organize numeric values in a source
// data column into buckets of constant size.
type ChartHistogramRule struct {
	// IntervalSize: The size of the buckets that are created. Must be
	// positive.
	IntervalSize float64 `json:"intervalSize,omitempty"`

	// MaxValue: The maximum value at which items are placed into buckets.
	// Values greater than the maximum are grouped into a single bucket. If
	// omitted, it is determined by the maximum item value.
	MaxValue float64 `json:"maxValue,omitempty"`

	// MinValue: The minimum value at which items are placed into buckets.
	// Values that are less than the minimum are grouped into a single
	// bucket. If omitted, it is determined by the minimum item value.
	MinValue float64 `json:"minValue,omitempty"`

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

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

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

func (s *ChartHistogramRule) UnmarshalJSON(data []byte) error {
	type NoMethod ChartHistogramRule
	var s1 struct {
		IntervalSize gensupport.JSONFloat64 `json:"intervalSize"`
		MaxValue     gensupport.JSONFloat64 `json:"maxValue"`
		MinValue     gensupport.JSONFloat64 `json:"minValue"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.IntervalSize = float64(s1.IntervalSize)
	s.MaxValue = float64(s1.MaxValue)
	s.MinValue = float64(s1.MinValue)
	return nil
}

// ChartSourceRange: Source ranges for a chart.
type ChartSourceRange struct {
	// Sources: The ranges of data for a series or domain. Exactly one
	// dimension must have a length of 1, and all sources in the list must
	// have the same dimension with length 1. The domain (if it exists) &
	// all series must have the same number of source ranges. If using more
	// than one source range, then the source range at a given offset must
	// be in order and contiguous across the domain and series. For example,
	// these are valid configurations: domain sources: A1:A5 series1
	// sources: B1:B5 series2 sources: D6:D10 domain sources: A1:A5, C10:C12
	// series1 sources: B1:B5, D10:D12 series2 sources: C1:C5, E10:E12
	Sources []*GridRange `json:"sources,omitempty"`

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

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

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

// ChartSpec: The specifications of a chart.
type ChartSpec struct {
	// AltText: The alternative text that describes the chart. This is often
	// used for accessibility.
	AltText string `json:"altText,omitempty"`

	// BackgroundColor: The background color of the entire chart. Not
	// applicable to Org charts.
	BackgroundColor *Color `json:"backgroundColor,omitempty"`

	// BackgroundColorStyle: The background color of the entire chart. Not
	// applicable to Org charts. If background_color is also set, this field
	// takes precedence.
	BackgroundColorStyle *ColorStyle `json:"backgroundColorStyle,omitempty"`

	// BasicChart: A basic chart specification, can be one of many kinds of
	// charts. See BasicChartType for the list of all charts this supports.
	BasicChart *BasicChartSpec `json:"basicChart,omitempty"`

	// BubbleChart: A bubble chart specification.
	BubbleChart *BubbleChartSpec `json:"bubbleChart,omitempty"`

	// CandlestickChart: A candlestick chart specification.
	CandlestickChart *CandlestickChartSpec `json:"candlestickChart,omitempty"`

	// DataSourceChartProperties: If present, the field contains data source
	// chart specific properties.
	DataSourceChartProperties *DataSourceChartProperties `json:"dataSourceChartProperties,omitempty"`

	// FilterSpecs: The filters applied to the source data of the chart.
	// Only supported for data source charts.
	FilterSpecs []*FilterSpec `json:"filterSpecs,omitempty"`

	// FontName: The name of the font to use by default for all chart text
	// (e.g. title, axis labels, legend). If a font is specified for a
	// specific part of the chart it will override this font name.
	FontName string `json:"fontName,omitempty"`

	// HiddenDimensionStrategy: Determines how the charts will use hidden
	// rows or columns.
	//
	// Possible values:
	//   "CHART_HIDDEN_DIMENSION_STRATEGY_UNSPECIFIED" - Default value, do
	// not use.
	//   "SKIP_HIDDEN_ROWS_AND_COLUMNS" - Charts will skip hidden rows and
	// columns.
	//   "SKIP_HIDDEN_ROWS" - Charts will skip hidden rows only.
	//   "SKIP_HIDDEN_COLUMNS" - Charts will skip hidden columns only.
	//   "SHOW_ALL" - Charts will not skip any hidden rows or columns.
	HiddenDimensionStrategy string `json:"hiddenDimensionStrategy,omitempty"`

	// HistogramChart: A histogram chart specification.
	HistogramChart *HistogramChartSpec `json:"histogramChart,omitempty"`

	// Maximized: True to make a chart fill the entire space in which it's
	// rendered with minimum padding. False to use the default padding. (Not
	// applicable to Geo and Org charts.)
	Maximized bool `json:"maximized,omitempty"`

	// OrgChart: An org chart specification.
	OrgChart *OrgChartSpec `json:"orgChart,omitempty"`

	// PieChart: A pie chart specification.
	PieChart *PieChartSpec `json:"pieChart,omitempty"`

	// ScorecardChart: A scorecard chart specification.
	ScorecardChart *ScorecardChartSpec `json:"scorecardChart,omitempty"`

	// SortSpecs: The order to sort the chart data by. Only a single sort
	// spec is supported. Only supported for data source charts.
	SortSpecs []*SortSpec `json:"sortSpecs,omitempty"`

	// Subtitle: The subtitle of the chart.
	Subtitle string `json:"subtitle,omitempty"`

	// SubtitleTextFormat: The subtitle text format. Strikethrough and
	// underline are not supported.
	SubtitleTextFormat *TextFormat `json:"subtitleTextFormat,omitempty"`

	// SubtitleTextPosition: The subtitle text position. This field is
	// optional.
	SubtitleTextPosition *TextPosition `json:"subtitleTextPosition,omitempty"`

	// Title: The title of the chart.
	Title string `json:"title,omitempty"`

	// TitleTextFormat: The title text format. Strikethrough and underline
	// are not supported.
	TitleTextFormat *TextFormat `json:"titleTextFormat,omitempty"`

	// TitleTextPosition: The title text position. This field is optional.
	TitleTextPosition *TextPosition `json:"titleTextPosition,omitempty"`

	// TreemapChart: A treemap chart specification.
	TreemapChart *TreemapChartSpec `json:"treemapChart,omitempty"`

	// WaterfallChart: A waterfall chart specification.
	WaterfallChart *WaterfallChartSpec `json:"waterfallChart,omitempty"`

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

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

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

// ClearBasicFilterRequest: Clears the basic filter, if any exists on
// the sheet.
type ClearBasicFilterRequest struct {
	// SheetId: The sheet ID on which the basic filter should be cleared.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// ClearValuesRequest: The request for clearing a range of values in a
// spreadsheet.
type ClearValuesRequest struct {
}

// ClearValuesResponse: The response when clearing a range of values in
// a spreadsheet.
type ClearValuesResponse struct {
	// ClearedRange: The range (in A1 notation) that was cleared. (If the
	// request was for an unbounded range or a ranger larger than the bounds
	// of the sheet, this will be the actual range that was cleared, bounded
	// to the sheet's limits.)
	ClearedRange string `json:"clearedRange,omitempty"`

	// SpreadsheetId: The spreadsheet the updates were applied to.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

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

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

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

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

// Color: Represents a color in the RGBA color space. This
// representation is designed for simplicity of conversion to/from color
// representations in various languages over compactness; for example,
// the fields of this representation can be trivially provided to the
// constructor of "java.awt.Color" in Java; it can also be trivially
// provided to UIColor's "+colorWithRed:green:blue:alpha" method in iOS;
// and, with just a little work, it can be easily formatted into a CSS
// "rgba()" string in JavaScript, as well. Note: this proto does not
// carry information about the absolute color space that should be used
// to interpret the RGB value (e.g. sRGB, Adobe RGB, DCI-P3, BT.2020,
// etc.). By default, applications SHOULD assume the sRGB color space.
// Note: when color equality needs to be decided, implementations,
// unless documented otherwise, will treat two colors to be equal if all
// their red, green, blue and alpha values each differ by at most 1e-5.
// Example (Java): import com.google.type.Color; // ... public static
// java.awt.Color fromProto(Color protocolor) { float alpha =
// protocolor.hasAlpha() ? protocolor.getAlpha().getValue() : 1.0;
// return new java.awt.Color( protocolor.getRed(),
// protocolor.getGreen(), protocolor.getBlue(), alpha); } public static
// Color toProto(java.awt.Color color) { float red = (float)
// color.getRed(); float green = (float) color.getGreen(); float blue =
// (float) color.getBlue(); float denominator = 255.0; Color.Builder
// resultBuilder = Color .newBuilder() .setRed(red / denominator)
// .setGreen(green / denominator) .setBlue(blue / denominator); int
// alpha = color.getAlpha(); if (alpha != 255) { result.setAlpha(
// FloatValue .newBuilder() .setValue(((float) alpha) / denominator)
// .build()); } return resultBuilder.build(); } // ... Example (iOS /
// Obj-C): // ... static UIColor* fromProto(Color* protocolor) { float
// red = [protocolor red]; float green = [protocolor green]; float blue
// = [protocolor blue]; FloatValue* alpha_wrapper = [protocolor alpha];
// float alpha = 1.0; if (alpha_wrapper != nil) { alpha = [alpha_wrapper
// value]; } return [UIColor colorWithRed:red green:green blue:blue
// alpha:alpha]; } static Color* toProto(UIColor* color) { CGFloat red,
// green, blue, alpha; if (![color getRed:&red green:&green blue:&blue
// alpha:&alpha]) { return nil; } Color* result = [[Color alloc] init];
// [result setRed:red]; [result setGreen:green]; [result setBlue:blue];
// if (alpha <= 0.9999) { [result
// setAlpha:floatWrapperWithValue(alpha)]; } [result autorelease];
// return result; } // ... Example (JavaScript): // ... var
// protoToCssColor = function(rgb_color) { var redFrac = rgb_color.red
// || 0.0; var greenFrac = rgb_color.green || 0.0; var blueFrac =
// rgb_color.blue || 0.0; var red = Math.floor(redFrac * 255); var green
// = Math.floor(greenFrac * 255); var blue = Math.floor(blueFrac * 255);
// if (!('alpha' in rgb_color)) { return rgbToCssColor_(red, green,
// blue); } var alphaFrac = rgb_color.alpha.value || 0.0; var rgbParams
// = [red, green, blue].join(','); return ['rgba(', rgbParams, ',',
// alphaFrac, ')'].join(''); }; var rgbToCssColor_ = function(red,
// green, blue) { var rgbNumber = new Number((red << 16) | (green << 8)
// | blue); var hexString = rgbNumber.toString(16); var missingZeros = 6
// - hexString.length; var resultBuilder = ['#']; for (var i = 0; i <
// missingZeros; i++) { resultBuilder.push('0'); }
// resultBuilder.push(hexString); return resultBuilder.join(''); }; //
// ...
type Color struct {
	// Alpha: The fraction of this color that should be applied to the
	// pixel. That is, the final pixel color is defined by the equation:
	// pixel color = alpha * (this color) + (1.0 - alpha) * (background
	// color) This means that a value of 1.0 corresponds to a solid color,
	// whereas a value of 0.0 corresponds to a completely transparent color.
	// This uses a wrapper message rather than a simple float scalar so that
	// it is possible to distinguish between a default value and the value
	// being unset. If omitted, this color object is to be rendered as a
	// solid color (as if the alpha value had been explicitly given with a
	// value of 1.0).
	Alpha float64 `json:"alpha,omitempty"`

	// Blue: The amount of blue in the color as a value in the interval [0,
	// 1].
	Blue float64 `json:"blue,omitempty"`

	// Green: The amount of green in the color as a value in the interval
	// [0, 1].
	Green float64 `json:"green,omitempty"`

	// Red: The amount of red in the color as a value in the interval [0,
	// 1].
	Red float64 `json:"red,omitempty"`

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

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

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

func (s *Color) UnmarshalJSON(data []byte) error {
	type NoMethod Color
	var s1 struct {
		Alpha gensupport.JSONFloat64 `json:"alpha"`
		Blue  gensupport.JSONFloat64 `json:"blue"`
		Green gensupport.JSONFloat64 `json:"green"`
		Red   gensupport.JSONFloat64 `json:"red"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Alpha = float64(s1.Alpha)
	s.Blue = float64(s1.Blue)
	s.Green = float64(s1.Green)
	s.Red = float64(s1.Red)
	return nil
}

// ColorStyle: A color value.
type ColorStyle struct {
	// RgbColor: RGB color.
	RgbColor *Color `json:"rgbColor,omitempty"`

	// ThemeColor: Theme color.
	//
	// Possible values:
	//   "THEME_COLOR_TYPE_UNSPECIFIED" - Unspecified theme color
	//   "TEXT" - Represents the primary text color
	//   "BACKGROUND" - Represents the primary background color
	//   "ACCENT1" - Represents the first accent color
	//   "ACCENT2" - Represents the second accent color
	//   "ACCENT3" - Represents the third accent color
	//   "ACCENT4" - Represents the fourth accent color
	//   "ACCENT5" - Represents the fifth accent color
	//   "ACCENT6" - Represents the sixth accent color
	//   "LINK" - Represents the color to use for hyperlinks
	ThemeColor string `json:"themeColor,omitempty"`

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

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

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

// ConditionValue: The value of the condition.
type ConditionValue struct {
	// RelativeDate: A relative date (based on the current date). Valid only
	// if the type is DATE_BEFORE, DATE_AFTER, DATE_ON_OR_BEFORE or
	// DATE_ON_OR_AFTER. Relative dates are not supported in data
	// validation. They are supported only in conditional formatting and
	// conditional filters.
	//
	// Possible values:
	//   "RELATIVE_DATE_UNSPECIFIED" - Default value, do not use.
	//   "PAST_YEAR" - The value is one year before today.
	//   "PAST_MONTH" - The value is one month before today.
	//   "PAST_WEEK" - The value is one week before today.
	//   "YESTERDAY" - The value is yesterday.
	//   "TODAY" - The value is today.
	//   "TOMORROW" - The value is tomorrow.
	RelativeDate string `json:"relativeDate,omitempty"`

	// UserEnteredValue: A value the condition is based on. The value is
	// parsed as if the user typed into a cell. Formulas are supported (and
	// must begin with an `=` or a '+').
	UserEnteredValue string `json:"userEnteredValue,omitempty"`

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

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

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

// ConditionalFormatRule: A rule describing a conditional format.
type ConditionalFormatRule struct {
	// BooleanRule: The formatting is either "on" or "off" according to the
	// rule.
	BooleanRule *BooleanRule `json:"booleanRule,omitempty"`

	// GradientRule: The formatting will vary based on the gradients in the
	// rule.
	GradientRule *GradientRule `json:"gradientRule,omitempty"`

	// Ranges: The ranges that are formatted if the condition is true. All
	// the ranges must be on the same grid.
	Ranges []*GridRange `json:"ranges,omitempty"`

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

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

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

// CopyPasteRequest: Copies data from the source to the destination.
type CopyPasteRequest struct {
	// Destination: The location to paste to. If the range covers a span
	// that's a multiple of the source's height or width, then the data will
	// be repeated to fill in the destination range. If the range is smaller
	// than the source range, the entire source data will still be copied
	// (beyond the end of the destination range).
	Destination *GridRange `json:"destination,omitempty"`

	// PasteOrientation: How that data should be oriented when pasting.
	//
	// Possible values:
	//   "NORMAL" - Paste normally.
	//   "TRANSPOSE" - Paste transposed, where all rows become columns and
	// vice versa.
	PasteOrientation string `json:"pasteOrientation,omitempty"`

	// PasteType: What kind of data to paste.
	//
	// Possible values:
	//   "PASTE_NORMAL" - Paste values, formulas, formats, and merges.
	//   "PASTE_VALUES" - Paste the values ONLY without formats, formulas,
	// or merges.
	//   "PASTE_FORMAT" - Paste the format and data validation only.
	//   "PASTE_NO_BORDERS" - Like PASTE_NORMAL but without borders.
	//   "PASTE_FORMULA" - Paste the formulas only.
	//   "PASTE_DATA_VALIDATION" - Paste the data validation only.
	//   "PASTE_CONDITIONAL_FORMATTING" - Paste the conditional formatting
	// rules only.
	PasteType string `json:"pasteType,omitempty"`

	// Source: The source range to copy.
	Source *GridRange `json:"source,omitempty"`

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

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

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

// CopySheetToAnotherSpreadsheetRequest: The request to copy a sheet
// across spreadsheets.
type CopySheetToAnotherSpreadsheetRequest struct {
	// DestinationSpreadsheetId: The ID of the spreadsheet to copy the sheet
	// to.
	DestinationSpreadsheetId string `json:"destinationSpreadsheetId,omitempty"`

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

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

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

// CreateDeveloperMetadataRequest: A request to create developer
// metadata.
type CreateDeveloperMetadataRequest struct {
	// DeveloperMetadata: The developer metadata to create.
	DeveloperMetadata *DeveloperMetadata `json:"developerMetadata,omitempty"`

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

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

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

// CreateDeveloperMetadataResponse: The response from creating developer
// metadata.
type CreateDeveloperMetadataResponse struct {
	// DeveloperMetadata: The developer metadata that was created.
	DeveloperMetadata *DeveloperMetadata `json:"developerMetadata,omitempty"`

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

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

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

// CutPasteRequest: Moves data from the source to the destination.
type CutPasteRequest struct {
	// Destination: The top-left coordinate where the data should be pasted.
	Destination *GridCoordinate `json:"destination,omitempty"`

	// PasteType: What kind of data to paste. All the source data will be
	// cut, regardless of what is pasted.
	//
	// Possible values:
	//   "PASTE_NORMAL" - Paste values, formulas, formats, and merges.
	//   "PASTE_VALUES" - Paste the values ONLY without formats, formulas,
	// or merges.
	//   "PASTE_FORMAT" - Paste the format and data validation only.
	//   "PASTE_NO_BORDERS" - Like PASTE_NORMAL but without borders.
	//   "PASTE_FORMULA" - Paste the formulas only.
	//   "PASTE_DATA_VALIDATION" - Paste the data validation only.
	//   "PASTE_CONDITIONAL_FORMATTING" - Paste the conditional formatting
	// rules only.
	PasteType string `json:"pasteType,omitempty"`

	// Source: The source data to cut.
	Source *GridRange `json:"source,omitempty"`

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

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

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

// DataExecutionStatus: The data execution status.
type DataExecutionStatus struct {
	// ErrorCode: The error code.
	//
	// Possible values:
	//   "DATA_EXECUTION_ERROR_CODE_UNSPECIFIED" - Default value, do not
	// use.
	//   "TIMED_OUT" - The data execution timed out.
	//   "TOO_MANY_ROWS" - The data execution returns more rows than the
	// limit.
	//   "TOO_MANY_CELLS" - The data execution returns more cells than the
	// limit.
	//   "ENGINE" - Error is received from the backend data execution engine
	// (e.g. BigQuery). Check error_message for details.
	//   "PARAMETER_INVALID" - One or some of the provided data source
	// parameters are invalid.
	//   "UNSUPPORTED_DATA_TYPE" - The data execution returns an unsupported
	// data type.
	//   "DUPLICATE_COLUMN_NAMES" - The data execution returns duplicate
	// column names or aliases.
	//   "INTERRUPTED" - The data execution is interrupted. Please refresh
	// later.
	//   "CONCURRENT_QUERY" - The data execution is currently in progress,
	// can not be refreshed until it completes.
	//   "OTHER" - Other errors.
	//   "TOO_MANY_CHARS_PER_CELL" - The data execution returns values that
	// exceed the maximum characters allowed in a single cell.
	//   "DATA_NOT_FOUND" - The database referenced by the data source is
	// not found. */
	//   "PERMISSION_DENIED" - The user does not have access to the database
	// referenced by the data source.
	//   "MISSING_COLUMN_ALIAS" - The data execution returns columns with
	// missing aliases.
	//   "OBJECT_NOT_FOUND" - The data source object does not exist.
	//   "OBJECT_IN_ERROR_STATE" - The data source object is currently in
	// error state. To force refresh, set force in RefreshDataSourceRequest.
	//   "OBJECT_SPEC_INVALID" - The data source object specification is
	// invalid.
	ErrorCode string `json:"errorCode,omitempty"`

	// ErrorMessage: The error message, which may be empty.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// LastRefreshTime: Gets the time the data last successfully refreshed.
	LastRefreshTime string `json:"lastRefreshTime,omitempty"`

	// State: The state of the data execution.
	//
	// Possible values:
	//   "DATA_EXECUTION_STATE_UNSPECIFIED" - Default value, do not use.
	//   "NOT_STARTED" - The data execution has not started.
	//   "RUNNING" - The data execution has started and is running.
	//   "SUCCEEDED" - The data execution has completed successfully.
	//   "FAILED" - The data execution has completed with errors.
	State string `json:"state,omitempty"`

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

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

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

// DataFilter: Filter that describes what data should be selected or
// returned from a request.
type DataFilter struct {
	// A1Range: Selects data that matches the specified A1 range.
	A1Range string `json:"a1Range,omitempty"`

	// DeveloperMetadataLookup: Selects data associated with the developer
	// metadata matching the criteria described by this
	// DeveloperMetadataLookup.
	DeveloperMetadataLookup *DeveloperMetadataLookup `json:"developerMetadataLookup,omitempty"`

	// GridRange: Selects data that matches the range described by the
	// GridRange.
	GridRange *GridRange `json:"gridRange,omitempty"`

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

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

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

// DataFilterValueRange: A range of values whose location is specified
// by a DataFilter.
type DataFilterValueRange struct {
	// DataFilter: The data filter describing the location of the values in
	// the spreadsheet.
	DataFilter *DataFilter `json:"dataFilter,omitempty"`

	// MajorDimension: The major dimension of the values.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
	//   "ROWS" - Operates on the rows of a sheet.
	//   "COLUMNS" - Operates on the columns of a sheet.
	MajorDimension string `json:"majorDimension,omitempty"`

	// Values: The data to be written. If the provided values exceed any of
	// the ranges matched by the data filter then the request fails. If the
	// provided values are less than the matched ranges only the specified
	// values are written, existing values in the matched ranges remain
	// unaffected.
	Values [][]interface{} `json:"values,omitempty"`

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

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

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

// DataSource: Information about an external data source in the
// spreadsheet.
type DataSource struct {
	// CalculatedColumns: All calculated columns in the data source.
	CalculatedColumns []*DataSourceColumn `json:"calculatedColumns,omitempty"`

	// DataSourceId: The spreadsheet-scoped unique ID that identifies the
	// data source.
	DataSourceId string `json:"dataSourceId,omitempty"`

	// SheetId: The ID of the Sheet connected with the data source. The
	// field cannot be changed once set. When creating a data source, an
	// associated SheetType.DATA_SOURCE sheet is also created, if the field
	// is not specified, the ID of the created sheet will be randomly
	// generated.
	SheetId int64 `json:"sheetId,omitempty"`

	// Spec: The DataSourceSpec.
	Spec *DataSourceSpec `json:"spec,omitempty"`

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

	// NullFields is a list of field names (e.g. "CalculatedColumns") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field 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)
}

// DataSourceChartProperties: Properties of a data source chart.
type DataSourceChartProperties struct {
	// DataExecutionStatus: Output only. The data execution status.
	DataExecutionStatus *DataExecutionStatus `json:"dataExecutionStatus,omitempty"`

	// DataSourceId: ID of the data source that the chart is associated
	// with.
	DataSourceId string `json:"dataSourceId,omitempty"`

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

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

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

// DataSourceColumn: A data source column.
type DataSourceColumn struct {
	// Formula: The formula of the calculated column.
	Formula string `json:"formula,omitempty"`

	// Reference: The column reference.
	Reference *DataSourceColumnReference `json:"reference,omitempty"`

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

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

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

// DataSourceColumnReference: An unique identifier that references to a
// data source column.
type DataSourceColumnReference struct {
	// Name: The display name of the column. It should be unique within a
	// data source.
	Name string `json:"name,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 *DataSourceColumnReference) MarshalJSON() ([]byte, error) {
	type NoMethod DataSourceColumnReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DataSourceFormula: A data source formula.
type DataSourceFormula struct {
	// DataExecutionStatus: Output only. The data execution status.
	DataExecutionStatus *DataExecutionStatus `json:"dataExecutionStatus,omitempty"`

	// DataSourceId: The ID of the data source the formula is associated
	// with.
	DataSourceId string `json:"dataSourceId,omitempty"`

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

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

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

// DataSourceObjectReference: Reference to a data source object.
type DataSourceObjectReference struct {
	// ChartId: References to a DataSourceChart.
	ChartId int64 `json:"chartId,omitempty"`

	// DataSourceFormulaCell: References to a cell containing
	// DataSourceFormula.
	DataSourceFormulaCell *GridCoordinate `json:"dataSourceFormulaCell,omitempty"`

	// DataSourcePivotTableAnchorCell: References to a data source
	// PivotTable anchored at the cell.
	DataSourcePivotTableAnchorCell *GridCoordinate `json:"dataSourcePivotTableAnchorCell,omitempty"`

	// DataSourceTableAnchorCell: References to a DataSourceTable anchored
	// at the cell.
	DataSourceTableAnchorCell *GridCoordinate `json:"dataSourceTableAnchorCell,omitempty"`

	// SheetId: References to a SheetType.DATA_SOURCE sheet.
	SheetId string `json:"sheetId,omitempty"`

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

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

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

// DataSourceObjectReferences: A list of references to data source
// objects.
type DataSourceObjectReferences struct {
	// References: The references.
	References []*DataSourceObjectReference `json:"references,omitempty"`

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

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

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

// DataSourceParameter: A parameter in a data source's query. The
// parameter allows user to pass in values from the spreadsheet into a
// query.
type DataSourceParameter struct {
	// Name: Named parameter. Must be a legitimate identifier for the
	// DataSource that supports it. For example, BigQuery identifier
	Name string `json:"name,omitempty"`

	// NamedRangeId: ID of a NamedRange. Its size must be 1x1.
	NamedRangeId string `json:"namedRangeId,omitempty"`

	// Range: A range that contains the value of the parameter. Its size
	// must be 1x1.
	Range *GridRange `json:"range,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 *DataSourceParameter) MarshalJSON() ([]byte, error) {
	type NoMethod DataSourceParameter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DataSourceRefreshDailySchedule: Schedule refreshes in a time interval
// everyday.
type DataSourceRefreshDailySchedule struct {
	// StartTime: The start time of a time interval in which a data source
	// refresh is scheduled. Only `hours` part is used. The time interval
	// size defaults to that in the Sheets editor.
	StartTime *TimeOfDay `json:"startTime,omitempty"`

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

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

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

// DataSourceRefreshMonthlySchedule: Schedule refreshes in a time
// interval on specified days in a month and repeats monthly.
type DataSourceRefreshMonthlySchedule struct {
	// DaysOfMonth: Days of the month to refresh. Only 1-28 are supported,
	// mapping to the 1st to the 28th day. At lesat one day must be
	// specified.
	DaysOfMonth []int64 `json:"daysOfMonth,omitempty"`

	// StartTime: The start time of a time interval in which a data source
	// refresh is scheduled. Only `hours` part is used. The time interval
	// size defaults to that in the Sheets editor.
	StartTime *TimeOfDay `json:"startTime,omitempty"`

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

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

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

// DataSourceRefreshSchedule: The data source refresh schedule. All data
// sources in the spreadsheet are scheduled to refresh in a future time
// interval. The time interval size defaults to the one defined in the
// Sheets editor. For example, if a daily schedule at start time of 8am
// is scheduled, and the time interval is 4 hours, the scheduled refresh
// will happen between 8am and 12pm every day.
type DataSourceRefreshSchedule struct {
	// DailySchedule: Daily refresh schedule.
	DailySchedule *DataSourceRefreshDailySchedule `json:"dailySchedule,omitempty"`

	// Enabled: True if the refresh schedule is enabled, or false otherwise.
	Enabled bool `json:"enabled,omitempty"`

	// MonthlySchedule: Monthly refresh schedule.
	MonthlySchedule *DataSourceRefreshMonthlySchedule `json:"monthlySchedule,omitempty"`

	// NextRun: Output only. The time interval of the next run.
	NextRun *Interval `json:"nextRun,omitempty"`

	// RefreshScope: The scope of the refresh.
	//
	// Possible values:
	//   "DATA_SOURCE_REFRESH_SCOPE_UNSPECIFIED" - Default value; Do not
	// use.
	//   "ALL_DATA_SOURCES" - Refreshes all data sources and their
	// associated data source objects in the spreadsheet.
	RefreshScope string `json:"refreshScope,omitempty"`

	// WeeklySchedule: Weekly refresh schedule.
	WeeklySchedule *DataSourceRefreshWeeklySchedule `json:"weeklySchedule,omitempty"`

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

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

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

// DataSourceRefreshWeeklySchedule: Schedule refreshes in a time
// interval on specified days in a week and repeats weekly.
type DataSourceRefreshWeeklySchedule struct {
	// DaysOfWeek: Days of the week to refresh. At least one day must be
	// specified.
	//
	// Possible values:
	//   "DAY_OF_WEEK_UNSPECIFIED" - The day of the week is unspecified.
	//   "MONDAY" - Monday
	//   "TUESDAY" - Tuesday
	//   "WEDNESDAY" - Wednesday
	//   "THURSDAY" - Thursday
	//   "FRIDAY" - Friday
	//   "SATURDAY" - Saturday
	//   "SUNDAY" - Sunday
	DaysOfWeek []string `json:"daysOfWeek,omitempty"`

	// StartTime: The start time of a time interval in which a data source
	// refresh is scheduled. Only `hours` part is used. The time interval
	// size defaults to that in the Sheets editor.
	StartTime *TimeOfDay `json:"startTime,omitempty"`

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

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

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

// DataSourceSheetDimensionRange: A range along a single dimension on a
// DataSource sheet.
type DataSourceSheetDimensionRange struct {
	// ColumnReferences: The columns on the data source sheet.
	ColumnReferences []*DataSourceColumnReference `json:"columnReferences,omitempty"`

	// SheetId: The ID of the data source sheet the range is on.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// DataSourceSheetProperties: Additional properties of a
// SheetType.DATA_SOURCE sheet.
type DataSourceSheetProperties struct {
	// Columns: The columns displayed on the sheet, corresponding to the
	// values in RowData.
	Columns []*DataSourceColumn `json:"columns,omitempty"`

	// DataExecutionStatus: The data execution status.
	DataExecutionStatus *DataExecutionStatus `json:"dataExecutionStatus,omitempty"`

	// DataSourceId: ID of the DataSource the sheet connected with.
	DataSourceId string `json:"dataSourceId,omitempty"`

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

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

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

// DataSourceSpec: The specification of a data source.
type DataSourceSpec struct {
	// BigQuery: A BigQueryDataSourceSpec.
	BigQuery *BigQueryDataSourceSpec `json:"bigQuery,omitempty"`

	// Parameters: The parameters of the data source.
	Parameters []*DataSourceParameter `json:"parameters,omitempty"`

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

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

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

// DataSourceTable: A data source table, allowing to import a static
// table of data from the DataSource into Sheets. This is also known as
// "Extract" in the Sheets editor.
type DataSourceTable struct {
	// ColumnSelectionType: The type to select columns for the data source
	// table. Defaults to SELECTED.
	//
	// Possible values:
	//   "DATA_SOURCE_TABLE_COLUMN_SELECTION_TYPE_UNSPECIFIED" - The default
	// column selection type, do not use.
	//   "SELECTED" - Select columns specified by columns field.
	//   "SYNC_ALL" - Sync all current and future columns in the data
	// source. If set, the data source table fetches all the columns in the
	// data source at the time of refresh.
	ColumnSelectionType string `json:"columnSelectionType,omitempty"`

	// Columns: Columns selected for the data source table. The
	// column_selection_type must be SELECTED.
	Columns []*DataSourceColumnReference `json:"columns,omitempty"`

	// DataExecutionStatus: Output only. The data execution status.
	DataExecutionStatus *DataExecutionStatus `json:"dataExecutionStatus,omitempty"`

	// DataSourceId: The ID of the data source the data source table is
	// associated with.
	DataSourceId string `json:"dataSourceId,omitempty"`

	// FilterSpecs: Filter specifications in the data source table.
	FilterSpecs []*FilterSpec `json:"filterSpecs,omitempty"`

	// RowLimit: The limit of rows to return. If not set, a default limit is
	// applied. Please refer to the Sheets editor for the default and max
	// limit.
	RowLimit int64 `json:"rowLimit,omitempty"`

	// SortSpecs: Sort specifications in the data source table. The result
	// of the data source table is sorted based on the sort specifications
	// in order.
	SortSpecs []*SortSpec `json:"sortSpecs,omitempty"`

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

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

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

// DataValidationRule: A data validation rule.
type DataValidationRule struct {
	// Condition: The condition that data in the cell must match.
	Condition *BooleanCondition `json:"condition,omitempty"`

	// InputMessage: A message to show the user when adding data to the
	// cell.
	InputMessage string `json:"inputMessage,omitempty"`

	// ShowCustomUi: True if the UI should be customized based on the kind
	// of condition. If true, "List" conditions will show a dropdown.
	ShowCustomUi bool `json:"showCustomUi,omitempty"`

	// Strict: True if invalid data should be rejected.
	Strict bool `json:"strict,omitempty"`

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

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

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

// DateTimeRule: Allows you to organize the date-time values in a source
// data column into buckets based on selected parts of their date or
// time values. For example, consider a pivot table showing sales
// transactions by date: +----------+--------------+ | Date | SUM of
// Sales | +----------+--------------+ | 1/1/2017 | $621.14 | | 2/3/2017
// | $708.84 | | 5/8/2017 | $326.84 | ... +----------+--------------+
// Applying a date-time group rule with a DateTimeRuleType of YEAR_MONTH
// results in the following pivot table. +--------------+--------------+
// | Grouped Date | SUM of Sales | +--------------+--------------+ |
// 2017-Jan | $53,731.78 | | 2017-Feb | $83,475.32 | | 2017-Mar |
// $94,385.05 | ... +--------------+--------------+
type DateTimeRule struct {
	// Type: The type of date-time grouping to apply.
	//
	// Possible values:
	//   "DATE_TIME_RULE_TYPE_UNSPECIFIED" - The default type, do not use.
	//   "SECOND" - Group dates by second, from 0 to 59.
	//   "MINUTE" - Group dates by minute, from 0 to 59.
	//   "HOUR" - Group dates by hour using a 24-hour system, from 0 to 23.
	//   "HOUR_MINUTE" - Group dates by hour and minute using a 24-hour
	// system, for example 19:45.
	//   "HOUR_MINUTE_AMPM" - Group dates by hour and minute using a 12-hour
	// system, for example 7:45 PM. The AM/PM designation is translated
	// based on the spreadsheet locale.
	//   "DAY_OF_WEEK" - Group dates by day of week, for example Sunday. The
	// days of the week will be translated based on the spreadsheet locale.
	//   "DAY_OF_YEAR" - Group dates by day of year, from 1 to 366. Note
	// that dates after Feb. 29 fall in different buckets in leap years than
	// in non-leap years.
	//   "DAY_OF_MONTH" - Group dates by day of month, from 1 to 31.
	//   "DAY_MONTH" - Group dates by day and month, for example 22-Nov. The
	// month is translated based on the spreadsheet locale.
	//   "MONTH" - Group dates by month, for example Nov. The month is
	// translated based on the spreadsheet locale.
	//   "QUARTER" - Group dates by quarter, for example Q1 (which
	// represents Jan-Mar).
	//   "YEAR" - Group dates by year, for example 2008.
	//   "YEAR_MONTH" - Group dates by year and month, for example 2008-Nov.
	// The month is translated based on the spreadsheet locale.
	//   "YEAR_QUARTER" - Group dates by year and quarter, for example 2008
	// Q4.
	//   "YEAR_MONTH_DAY" - Group dates by year, month, and day, for example
	// 2008-11-22.
	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 *DateTimeRule) MarshalJSON() ([]byte, error) {
	type NoMethod DateTimeRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteBandingRequest: Removes the banded range with the given ID from
// the spreadsheet.
type DeleteBandingRequest struct {
	// BandedRangeId: The ID of the banded range to delete.
	BandedRangeId int64 `json:"bandedRangeId,omitempty"`

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

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

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

// DeleteConditionalFormatRuleRequest: Deletes a conditional format rule
// at the given index. All subsequent rules' indexes are decremented.
type DeleteConditionalFormatRuleRequest struct {
	// Index: The zero-based index of the rule to be deleted.
	Index int64 `json:"index,omitempty"`

	// SheetId: The sheet the rule is being deleted from.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// DeleteConditionalFormatRuleResponse: The result of deleting a
// conditional format rule.
type DeleteConditionalFormatRuleResponse struct {
	// Rule: The rule that was deleted.
	Rule *ConditionalFormatRule `json:"rule,omitempty"`

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

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

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

// DeleteDataSourceRequest: Deletes a data source. The request also
// deletes the associated data source sheet, and unlinks all associated
// data source objects.
type DeleteDataSourceRequest struct {
	// DataSourceId: The ID of the data source to delete.
	DataSourceId string `json:"dataSourceId,omitempty"`

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

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

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

// DeleteDeveloperMetadataRequest: A request to delete developer
// metadata.
type DeleteDeveloperMetadataRequest struct {
	// DataFilter: The data filter describing the criteria used to select
	// which developer metadata entry to delete.
	DataFilter *DataFilter `json:"dataFilter,omitempty"`

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

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

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

// DeleteDeveloperMetadataResponse: The response from deleting developer
// metadata.
type DeleteDeveloperMetadataResponse struct {
	// DeletedDeveloperMetadata: The metadata that was deleted.
	DeletedDeveloperMetadata []*DeveloperMetadata `json:"deletedDeveloperMetadata,omitempty"`

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

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

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

// DeleteDimensionGroupRequest: Deletes a group over the specified range
// by decrementing the depth of the dimensions in the range. For
// example, assume the sheet has a depth-1 group over B:E and a depth-2
// group over C:D. Deleting a group over D:E leaves the sheet with a
// depth-1 group over B:D and a depth-2 group over C:C.
type DeleteDimensionGroupRequest struct {
	// Range: The range of the group to be deleted.
	Range *DimensionRange `json:"range,omitempty"`

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

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

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

// DeleteDimensionGroupResponse: The result of deleting a group.
type DeleteDimensionGroupResponse struct {
	// DimensionGroups: All groups of a dimension after deleting a group
	// from that dimension.
	DimensionGroups []*DimensionGroup `json:"dimensionGroups,omitempty"`

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

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

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

// DeleteDimensionRequest: Deletes the dimensions from the sheet.
type DeleteDimensionRequest struct {
	// Range: The dimensions to delete from the sheet.
	Range *DimensionRange `json:"range,omitempty"`

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

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

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

// DeleteDuplicatesRequest: Removes rows within this range that contain
// values in the specified columns that are duplicates of values in any
// previous row. Rows with identical values but different letter cases,
// formatting, or formulas are considered to be duplicates. This request
// also removes duplicate rows hidden from view (for example, due to a
// filter). When removing duplicates, the first instance of each
// duplicate row scanning from the top downwards is kept in the
// resulting range. Content outside of the specified range isn't
// removed, and rows considered duplicates do not have to be adjacent to
// each other in the range.
type DeleteDuplicatesRequest struct {
	// ComparisonColumns: The columns in the range to analyze for duplicate
	// values. If no columns are selected then all columns are analyzed for
	// duplicates.
	ComparisonColumns []*DimensionRange `json:"comparisonColumns,omitempty"`

	// Range: The range to remove duplicates rows from.
	Range *GridRange `json:"range,omitempty"`

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

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

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

// DeleteDuplicatesResponse: The result of removing duplicates in a
// range.
type DeleteDuplicatesResponse struct {
	// DuplicatesRemovedCount: The number of duplicate rows removed.
	DuplicatesRemovedCount int64 `json:"duplicatesRemovedCount,omitempty"`

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

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

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

// DeleteEmbeddedObjectRequest: Deletes the embedded object with the
// given ID.
type DeleteEmbeddedObjectRequest struct {
	// ObjectId: The ID of the embedded object to delete.
	ObjectId int64 `json:"objectId,omitempty"`

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

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

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

// DeleteFilterViewRequest: Deletes a particular filter view.
type DeleteFilterViewRequest struct {
	// FilterId: The ID of the filter to delete.
	FilterId int64 `json:"filterId,omitempty"`

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

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

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

// DeleteNamedRangeRequest: Removes the named range with the given ID
// from the spreadsheet.
type DeleteNamedRangeRequest struct {
	// NamedRangeId: The ID of the named range to delete.
	NamedRangeId string `json:"namedRangeId,omitempty"`

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

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

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

// DeleteProtectedRangeRequest: Deletes the protected range with the
// given ID.
type DeleteProtectedRangeRequest struct {
	// ProtectedRangeId: The ID of the protected range to delete.
	ProtectedRangeId int64 `json:"protectedRangeId,omitempty"`

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

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

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

// DeleteRangeRequest: Deletes a range of cells, shifting other cells
// into the deleted area.
type DeleteRangeRequest struct {
	// Range: The range of cells to delete.
	Range *GridRange `json:"range,omitempty"`

	// ShiftDimension: The dimension from which deleted cells will be
	// replaced with. If ROWS, existing cells will be shifted upward to
	// replace the deleted cells. If COLUMNS, existing cells will be shifted
	// left to replace the deleted cells.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
	//   "ROWS" - Operates on the rows of a sheet.
	//   "COLUMNS" - Operates on the columns of a sheet.
	ShiftDimension string `json:"shiftDimension,omitempty"`

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

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

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

// DeleteSheetRequest: Deletes the requested sheet.
type DeleteSheetRequest struct {
	// SheetId: The ID of the sheet to delete.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// DeveloperMetadata: Developer metadata associated with a location or
// object in a spreadsheet. Developer metadata may be used to associate
// arbitrary data with various parts of a spreadsheet and will remain
// associated at those locations as they move around and the spreadsheet
// is edited. For example, if developer metadata is associated with row
// 5 and another row is then subsequently inserted above row 5, that
// original metadata will still be associated with the row it was first
// associated with (what is now row 6). If the associated object is
// deleted its metadata is deleted too.
type DeveloperMetadata struct {
	// Location: The location where the metadata is associated.
	Location *DeveloperMetadataLocation `json:"location,omitempty"`

	// MetadataId: The spreadsheet-scoped unique ID that identifies the
	// metadata. IDs may be specified when metadata is created, otherwise
	// one will be randomly generated and assigned. Must be positive.
	MetadataId int64 `json:"metadataId,omitempty"`

	// MetadataKey: The metadata key. There may be multiple metadata in a
	// spreadsheet with the same key. Developer metadata must always have a
	// key specified.
	MetadataKey string `json:"metadataKey,omitempty"`

	// MetadataValue: Data associated with the metadata's key.
	MetadataValue string `json:"metadataValue,omitempty"`

	// Visibility: The metadata visibility. Developer metadata must always
	// have a visibility specified.
	//
	// Possible values:
	//   "DEVELOPER_METADATA_VISIBILITY_UNSPECIFIED" - Default value.
	//   "DOCUMENT" - Document-visible metadata is accessible from any
	// developer project with access to the document.
	//   "PROJECT" - Project-visible metadata is only visible to and
	// accessible by the developer project that created the metadata.
	Visibility string `json:"visibility,omitempty"`

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

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

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

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

// DeveloperMetadataLocation: A location where metadata may be
// associated in a spreadsheet.
type DeveloperMetadataLocation struct {
	// DimensionRange: Represents the row or column when metadata is
	// associated with a dimension. The specified DimensionRange must
	// represent a single row or column; it cannot be unbounded or span
	// multiple rows or columns.
	DimensionRange *DimensionRange `json:"dimensionRange,omitempty"`

	// LocationType: The type of location this object represents. This field
	// is read-only.
	//
	// Possible values:
	//   "DEVELOPER_METADATA_LOCATION_TYPE_UNSPECIFIED" - Default value.
	//   "ROW" - Developer metadata associated on an entire row dimension.
	//   "COLUMN" - Developer metadata associated on an entire column
	// dimension.
	//   "SHEET" - Developer metadata associated on an entire sheet.
	//   "SPREADSHEET" - Developer metadata associated on the entire
	// spreadsheet.
	LocationType string `json:"locationType,omitempty"`

	// SheetId: The ID of the sheet when metadata is associated with an
	// entire sheet.
	SheetId int64 `json:"sheetId,omitempty"`

	// Spreadsheet: True when metadata is associated with an entire
	// spreadsheet.
	Spreadsheet bool `json:"spreadsheet,omitempty"`

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

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

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

// DeveloperMetadataLookup: Selects DeveloperMetadata that matches all
// of the specified fields. For example, if only a metadata ID is
// specified this considers the DeveloperMetadata with that particular
// unique ID. If a metadata key is specified, this considers all
// developer metadata with that key. If a key, visibility, and location
// type are all specified, this considers all developer metadata with
// that key and visibility that are associated with a location of that
// type. In general, this selects all DeveloperMetadata that matches the
// intersection of all the specified fields; any field or combination of
// fields may be specified.
type DeveloperMetadataLookup struct {
	// LocationMatchingStrategy: Determines how this lookup matches the
	// location. If this field is specified as EXACT, only developer
	// metadata associated on the exact location specified is matched. If
	// this field is specified to INTERSECTING, developer metadata
	// associated on intersecting locations is also matched. If left
	// unspecified, this field assumes a default value of INTERSECTING. If
	// this field is specified, a metadataLocation must also be specified.
	//
	// Possible values:
	//   "DEVELOPER_METADATA_LOCATION_MATCHING_STRATEGY_UNSPECIFIED" -
	// Default value. This value must not be used.
	//   "EXACT_LOCATION" - Indicates that a specified location should be
	// matched exactly. For example, if row three were specified as a
	// location this matching strategy would only match developer metadata
	// also associated on row three. Metadata associated on other locations
	// would not be considered.
	//   "INTERSECTING_LOCATION" - Indicates that a specified location
	// should match that exact location as well as any intersecting
	// locations. For example, if row three were specified as a location
	// this matching strategy would match developer metadata associated on
	// row three as well as metadata associated on locations that intersect
	// row three. If, for instance, there was developer metadata associated
	// on column B, this matching strategy would also match that location
	// because column B intersects row three.
	LocationMatchingStrategy string `json:"locationMatchingStrategy,omitempty"`

	// LocationType: Limits the selected developer metadata to those entries
	// which are associated with locations of the specified type. For
	// example, when this field is specified as ROW this lookup only
	// considers developer metadata associated on rows. If the field is left
	// unspecified, all location types are considered. This field cannot be
	// specified as SPREADSHEET when the locationMatchingStrategy is
	// specified as INTERSECTING or when the metadataLocation is specified
	// as a non-spreadsheet location: spreadsheet metadata cannot intersect
	// any other developer metadata location. This field also must be left
	// unspecified when the locationMatchingStrategy is specified as EXACT.
	//
	// Possible values:
	//   "DEVELOPER_METADATA_LOCATION_TYPE_UNSPECIFIED" - Default value.
	//   "ROW" - Developer metadata associated on an entire row dimension.
	//   "COLUMN" - Developer metadata associated on an entire column
	// dimension.
	//   "SHEET" - Developer metadata associated on an entire sheet.
	//   "SPREADSHEET" - Developer metadata associated on the entire
	// spreadsheet.
	LocationType string `json:"locationType,omitempty"`

	// MetadataId: Limits the selected developer metadata to that which has
	// a matching DeveloperMetadata.metadata_id.
	MetadataId int64 `json:"metadataId,omitempty"`

	// MetadataKey: Limits the selected developer metadata to that which has
	// a matching DeveloperMetadata.metadata_key.
	MetadataKey string `json:"metadataKey,omitempty"`

	// MetadataLocation: Limits the selected developer metadata to those
	// entries associated with the specified location. This field either
	// matches exact locations or all intersecting locations according the
	// specified locationMatchingStrategy.
	MetadataLocation *DeveloperMetadataLocation `json:"metadataLocation,omitempty"`

	// MetadataValue: Limits the selected developer metadata to that which
	// has a matching DeveloperMetadata.metadata_value.
	MetadataValue string `json:"metadataValue,omitempty"`

	// Visibility: Limits the selected developer metadata to that which has
	// a matching DeveloperMetadata.visibility. If left unspecified, all
	// developer metadata visibile to the requesting project is considered.
	//
	// Possible values:
	//   "DEVELOPER_METADATA_VISIBILITY_UNSPECIFIED" - Default value.
	//   "DOCUMENT" - Document-visible metadata is accessible from any
	// developer project with access to the document.
	//   "PROJECT" - Project-visible metadata is only visible to and
	// accessible by the developer project that created the metadata.
	Visibility string `json:"visibility,omitempty"`

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

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

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

// DimensionGroup: A group over an interval of rows or columns on a
// sheet, which can contain or be contained within other groups. A group
// can be collapsed or expanded as a unit on the sheet.
type DimensionGroup struct {
	// Collapsed: This field is true if this group is collapsed. A collapsed
	// group remains collapsed if an overlapping group at a shallower depth
	// is expanded. A true value does not imply that all dimensions within
	// the group are hidden, since a dimension's visibility can change
	// independently from this group property. However, when this property
	// is updated, all dimensions within it are set to hidden if this field
	// is true, or set to visible if this field is false.
	Collapsed bool `json:"collapsed,omitempty"`

	// Depth: The depth of the group, representing how many groups have a
	// range that wholly contains the range of this group.
	Depth int64 `json:"depth,omitempty"`

	// Range: The range over which this group exists.
	Range *DimensionRange `json:"range,omitempty"`

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

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

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

// DimensionProperties: Properties about a dimension.
type DimensionProperties struct {
	// DataSourceColumnReference: Output only. If set, this is a column in a
	// data source sheet.
	DataSourceColumnReference *DataSourceColumnReference `json:"dataSourceColumnReference,omitempty"`

	// DeveloperMetadata: The developer metadata associated with a single
	// row or column.
	DeveloperMetadata []*DeveloperMetadata `json:"developerMetadata,omitempty"`

	// HiddenByFilter: True if this dimension is being filtered. This field
	// is read-only.
	HiddenByFilter bool `json:"hiddenByFilter,omitempty"`

	// HiddenByUser: True if this dimension is explicitly hidden.
	HiddenByUser bool `json:"hiddenByUser,omitempty"`

	// PixelSize: The height (if a row) or width (if a column) of the
	// dimension in pixels.
	PixelSize int64 `json:"pixelSize,omitempty"`

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

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

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

// DimensionRange: A range along a single dimension on a sheet. All
// indexes are zero-based. Indexes are half open: the start index is
// inclusive and the end index is exclusive. Missing indexes indicate
// the range is unbounded on that side.
type DimensionRange struct {
	// Dimension: The dimension of the span.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
	//   "ROWS" - Operates on the rows of a sheet.
	//   "COLUMNS" - Operates on the columns of a sheet.
	Dimension string `json:"dimension,omitempty"`

	// EndIndex: The end (exclusive) of the span, or not set if unbounded.
	EndIndex int64 `json:"endIndex,omitempty"`

	// SheetId: The sheet this span is on.
	SheetId int64 `json:"sheetId,omitempty"`

	// StartIndex: The start (inclusive) of the span, or not set if
	// unbounded.
	StartIndex int64 `json:"startIndex,omitempty"`

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

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

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

// DuplicateFilterViewRequest: Duplicates a particular filter view.
type DuplicateFilterViewRequest struct {
	// FilterId: The ID of the filter being duplicated.
	FilterId int64 `json:"filterId,omitempty"`

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

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

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

// DuplicateFilterViewResponse: The result of a filter view being
// duplicated.
type DuplicateFilterViewResponse struct {
	// Filter: The newly created filter.
	Filter *FilterView `json:"filter,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 *DuplicateFilterViewResponse) MarshalJSON() ([]byte, error) {
	type NoMethod DuplicateFilterViewResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DuplicateSheetRequest: Duplicates the contents of a sheet.
type DuplicateSheetRequest struct {
	// InsertSheetIndex: The zero-based index where the new sheet should be
	// inserted. The index of all sheets after this are incremented.
	InsertSheetIndex int64 `json:"insertSheetIndex,omitempty"`

	// NewSheetId: If set, the ID of the new sheet. If not set, an ID is
	// chosen. If set, the ID must not conflict with any existing sheet ID.
	// If set, it must be non-negative.
	NewSheetId int64 `json:"newSheetId,omitempty"`

	// NewSheetName: The name of the new sheet. If empty, a new name is
	// chosen for you.
	NewSheetName string `json:"newSheetName,omitempty"`

	// SourceSheetId: The sheet to duplicate.
	SourceSheetId int64 `json:"sourceSheetId,omitempty"`

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

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

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

// DuplicateSheetResponse: The result of duplicating a sheet.
type DuplicateSheetResponse struct {
	// Properties: The properties of the duplicate sheet.
	Properties *SheetProperties `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 *DuplicateSheetResponse) MarshalJSON() ([]byte, error) {
	type NoMethod DuplicateSheetResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Editors: The editors of a protected range.
type Editors struct {
	// DomainUsersCanEdit: True if anyone in the document's domain has edit
	// access to the protected range. Domain protection is only supported on
	// documents within a domain.
	DomainUsersCanEdit bool `json:"domainUsersCanEdit,omitempty"`

	// Groups: The email addresses of groups with edit access to the
	// protected range.
	Groups []string `json:"groups,omitempty"`

	// Users: The email addresses of users with edit access to the protected
	// range.
	Users []string `json:"users,omitempty"`

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

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

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

// EmbeddedChart: A chart embedded in a sheet.
type EmbeddedChart struct {
	// ChartId: The ID of the chart.
	ChartId int64 `json:"chartId,omitempty"`

	// Position: The position of the chart.
	Position *EmbeddedObjectPosition `json:"position,omitempty"`

	// Spec: The specification of the chart.
	Spec *ChartSpec `json:"spec,omitempty"`

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

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

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

// EmbeddedObjectPosition: The position of an embedded object such as a
// chart.
type EmbeddedObjectPosition struct {
	// NewSheet: If true, the embedded object is put on a new sheet whose ID
	// is chosen for you. Used only when writing.
	NewSheet bool `json:"newSheet,omitempty"`

	// OverlayPosition: The position at which the object is overlaid on top
	// of a grid.
	OverlayPosition *OverlayPosition `json:"overlayPosition,omitempty"`

	// SheetId: The sheet this is on. Set only if the embedded object is on
	// its own sheet. Must be non-negative.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// ErrorValue: An error in a cell.
type ErrorValue struct {
	// Message: A message with more information about the error (in the
	// spreadsheet's locale).
	Message string `json:"message,omitempty"`

	// Type: The type of error.
	//
	// Possible values:
	//   "ERROR_TYPE_UNSPECIFIED" - The default error type, do not use this.
	//   "ERROR" - Corresponds to the `#ERROR!` error.
	//   "NULL_VALUE" - Corresponds to the `#NULL!` error.
	//   "DIVIDE_BY_ZERO" - Corresponds to the `#DIV/0` error.
	//   "VALUE" - Corresponds to the `#VALUE!` error.
	//   "REF" - Corresponds to the `#REF!` error.
	//   "NAME" - Corresponds to the `#NAME?` error.
	//   "NUM" - Corresponds to the `#NUM!` error.
	//   "N_A" - Corresponds to the `#N/A` error.
	//   "LOADING" - Corresponds to the `Loading...` state.
	Type string `json:"type,omitempty"`

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

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

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

// ExtendedValue: The kinds of value that a cell in a spreadsheet can
// have.
type ExtendedValue struct {
	// BoolValue: Represents a boolean value.
	BoolValue *bool `json:"boolValue,omitempty"`

	// ErrorValue: Represents an error. This field is read-only.
	ErrorValue *ErrorValue `json:"errorValue,omitempty"`

	// FormulaValue: Represents a formula.
	FormulaValue *string `json:"formulaValue,omitempty"`

	// NumberValue: Represents a double value. Note: Dates, Times and
	// DateTimes are represented as doubles in "serial number" format.
	NumberValue *float64 `json:"numberValue,omitempty"`

	// StringValue: Represents a string value. Leading single quotes are not
	// included. For example, if the user typed `'123` into the UI, this
	// would be represented as a `stringValue` of "123".
	StringValue *string `json:"stringValue,omitempty"`

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

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

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

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

// FilterCriteria: Criteria for showing/hiding rows in a filter or
// filter view.
type FilterCriteria struct {
	// Condition: A condition that must be true for values to be shown.
	// (This does not override hidden_values -- if a value is listed there,
	// it will still be hidden.)
	Condition *BooleanCondition `json:"condition,omitempty"`

	// HiddenValues: Values that should be hidden.
	HiddenValues []string `json:"hiddenValues,omitempty"`

	// VisibleBackgroundColor: The background fill color to filter by; only
	// cells with this fill color are shown. Mutually exclusive with
	// visible_foreground_color.
	VisibleBackgroundColor *Color `json:"visibleBackgroundColor,omitempty"`

	// VisibleBackgroundColorStyle: The background fill color to filter by;
	// only cells with this fill color are shown. This field is mutually
	// exclusive with visible_foreground_color, and must be set to an
	// RGB-type color. If visible_background_color is also set, this field
	// takes precedence.
	VisibleBackgroundColorStyle *ColorStyle `json:"visibleBackgroundColorStyle,omitempty"`

	// VisibleForegroundColor: The foreground color to filter by; only cells
	// with this foreground color are shown. Mutually exclusive with
	// visible_background_color.
	VisibleForegroundColor *Color `json:"visibleForegroundColor,omitempty"`

	// VisibleForegroundColorStyle: The foreground color to filter by; only
	// cells with this foreground color are shown. This field is mutually
	// exclusive with visible_background_color, and must be set to an
	// RGB-type color. If visible_foreground_color is also set, this field
	// takes precedence.
	VisibleForegroundColorStyle *ColorStyle `json:"visibleForegroundColorStyle,omitempty"`

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

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

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

// FilterSpec: The filter criteria associated with a specific column.
type FilterSpec struct {
	// ColumnIndex: The column index.
	ColumnIndex int64 `json:"columnIndex,omitempty"`

	// DataSourceColumnReference: Reference to a data source column.
	DataSourceColumnReference *DataSourceColumnReference `json:"dataSourceColumnReference,omitempty"`

	// FilterCriteria: The criteria for the column.
	FilterCriteria *FilterCriteria `json:"filterCriteria,omitempty"`

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

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

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

// FilterView: A filter view.
type FilterView struct {
	// Criteria: The criteria for showing/hiding values per column. The
	// map's key is the column index, and the value is the criteria for that
	// column.
	Criteria map[string]FilterCriteria `json:"criteria,omitempty"`

	// FilterSpecs: The filter criteria for showing/hiding values per
	// column. Both criteria and filter_specs are populated in responses. If
	// both fields are specified in an update request, this field takes
	// precedence.
	FilterSpecs []*FilterSpec `json:"filterSpecs,omitempty"`

	// FilterViewId: The ID of the filter view.
	FilterViewId int64 `json:"filterViewId,omitempty"`

	// NamedRangeId: The named range this filter view is backed by, if any.
	// When writing, only one of range or named_range_id may be set.
	NamedRangeId string `json:"namedRangeId,omitempty"`

	// Range: The range this filter view covers. When writing, only one of
	// range or named_range_id may be set.
	Range *GridRange `json:"range,omitempty"`

	// SortSpecs: The sort order per column. Later specifications are used
	// when values are equal in the earlier specifications.
	SortSpecs []*SortSpec `json:"sortSpecs,omitempty"`

	// Title: The name of the filter view.
	Title string `json:"title,omitempty"`

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

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

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

// FindReplaceRequest: Finds and replaces data in cells over a range,
// sheet, or all sheets.
type FindReplaceRequest struct {
	// AllSheets: True to find/replace over all sheets.
	AllSheets bool `json:"allSheets,omitempty"`

	// Find: The value to search.
	Find string `json:"find,omitempty"`

	// IncludeFormulas: True if the search should include cells with
	// formulas. False to skip cells with formulas.
	IncludeFormulas bool `json:"includeFormulas,omitempty"`

	// MatchCase: True if the search is case sensitive.
	MatchCase bool `json:"matchCase,omitempty"`

	// MatchEntireCell: True if the find value should match the entire cell.
	MatchEntireCell bool `json:"matchEntireCell,omitempty"`

	// Range: The range to find/replace over.
	Range *GridRange `json:"range,omitempty"`

	// Replacement: The value to use as the replacement.
	Replacement string `json:"replacement,omitempty"`

	// SearchByRegex: True if the find value is a regex. The regular
	// expression and replacement should follow Java regex rules at
	// https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html. The replacement string is allowed to refer to capturing groups. For example, if one cell has the contents "Google Sheets" and another has "Google Docs", then searching for "o.* (.*)" with a replacement of "$1 Rocks" would change the contents of the cells to "GSheets Rocks" and "GDocs Rocks"
	// respectively.
	SearchByRegex bool `json:"searchByRegex,omitempty"`

	// SheetId: The sheet to find/replace over.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// FindReplaceResponse: The result of the find/replace.
type FindReplaceResponse struct {
	// FormulasChanged: The number of formula cells changed.
	FormulasChanged int64 `json:"formulasChanged,omitempty"`

	// OccurrencesChanged: The number of occurrences (possibly multiple
	// within a cell) changed. For example, if replacing "e" with "o" in
	// "Google Sheets", this would be "3" because "Google Sheets" ->
	// "Googlo Shoots".
	OccurrencesChanged int64 `json:"occurrencesChanged,omitempty"`

	// RowsChanged: The number of rows changed.
	RowsChanged int64 `json:"rowsChanged,omitempty"`

	// SheetsChanged: The number of sheets changed.
	SheetsChanged int64 `json:"sheetsChanged,omitempty"`

	// ValuesChanged: The number of non-formula cells changed.
	ValuesChanged int64 `json:"valuesChanged,omitempty"`

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

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

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

// GetSpreadsheetByDataFilterRequest: The request for retrieving a
// Spreadsheet.
type GetSpreadsheetByDataFilterRequest struct {
	// DataFilters: The DataFilters used to select which ranges to retrieve
	// from the spreadsheet.
	DataFilters []*DataFilter `json:"dataFilters,omitempty"`

	// IncludeGridData: True if grid data should be returned. This parameter
	// is ignored if a field mask was set in the request.
	IncludeGridData bool `json:"includeGridData,omitempty"`

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

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

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

// GradientRule: A rule that applies a gradient color scale format,
// based on the interpolation points listed. The format of a cell will
// vary based on its contents as compared to the values of the
// interpolation points.
type GradientRule struct {
	// Maxpoint: The final interpolation point.
	Maxpoint *InterpolationPoint `json:"maxpoint,omitempty"`

	// Midpoint: An optional midway interpolation point.
	Midpoint *InterpolationPoint `json:"midpoint,omitempty"`

	// Minpoint: The starting interpolation point.
	Minpoint *InterpolationPoint `json:"minpoint,omitempty"`

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

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

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

// GridCoordinate: A coordinate in a sheet. All indexes are zero-based.
type GridCoordinate struct {
	// ColumnIndex: The column index of the coordinate.
	ColumnIndex int64 `json:"columnIndex,omitempty"`

	// RowIndex: The row index of the coordinate.
	RowIndex int64 `json:"rowIndex,omitempty"`

	// SheetId: The sheet this coordinate is on.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// GridData: Data in the grid, as well as metadata about the dimensions.
type GridData struct {
	// ColumnMetadata: Metadata about the requested columns in the grid,
	// starting with the column in start_column.
	ColumnMetadata []*DimensionProperties `json:"columnMetadata,omitempty"`

	// RowData: The data in the grid, one entry per row, starting with the
	// row in startRow. The values in RowData will correspond to columns
	// starting at start_column.
	RowData []*RowData `json:"rowData,omitempty"`

	// RowMetadata: Metadata about the requested rows in the grid, starting
	// with the row in start_row.
	RowMetadata []*DimensionProperties `json:"rowMetadata,omitempty"`

	// StartColumn: The first column this GridData refers to, zero-based.
	StartColumn int64 `json:"startColumn,omitempty"`

	// StartRow: The first row this GridData refers to, zero-based.
	StartRow int64 `json:"startRow,omitempty"`

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

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

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

// GridProperties: Properties of a grid.
type GridProperties struct {
	// ColumnCount: The number of columns in the grid.
	ColumnCount int64 `json:"columnCount,omitempty"`

	// ColumnGroupControlAfter: True if the column grouping control toggle
	// is shown after the group.
	ColumnGroupControlAfter bool `json:"columnGroupControlAfter,omitempty"`

	// FrozenColumnCount: The number of columns that are frozen in the grid.
	FrozenColumnCount int64 `json:"frozenColumnCount,omitempty"`

	// FrozenRowCount: The number of rows that are frozen in the grid.
	FrozenRowCount int64 `json:"frozenRowCount,omitempty"`

	// HideGridlines: True if the grid isn't showing gridlines in the UI.
	HideGridlines bool `json:"hideGridlines,omitempty"`

	// RowCount: The number of rows in the grid.
	RowCount int64 `json:"rowCount,omitempty"`

	// RowGroupControlAfter: True if the row grouping control toggle is
	// shown after the group.
	RowGroupControlAfter bool `json:"rowGroupControlAfter,omitempty"`

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

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

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

// GridRange: A range on a sheet. All indexes are zero-based. Indexes
// are half open, i.e. the start index is inclusive and the end index is
// exclusive -- [start_index, end_index). Missing indexes indicate the
// range is unbounded on that side. For example, if "Sheet1" is sheet
// ID 0, then: `Sheet1!A1:A1 == sheet_id: 0, start_row_index: 0,
// end_row_index: 1, start_column_index: 0, end_column_index: 1`
// `Sheet1!A3:B4 == sheet_id: 0, start_row_index: 2, end_row_index: 4,
// start_column_index: 0, end_column_index: 2` `Sheet1!A:B == sheet_id:
// 0, start_column_index: 0, end_column_index: 2` `Sheet1!A5:B ==
// sheet_id: 0, start_row_index: 4, start_column_index: 0,
// end_column_index: 2` `Sheet1 == sheet_id:0` The start index must
// always be less than or equal to the end index. If the start index
// equals the end index, then the range is empty. Empty ranges are
// typically not meaningful and are usually rendered in the UI as
// `#REF!`.
type GridRange struct {
	// EndColumnIndex: The end column (exclusive) of the range, or not set
	// if unbounded.
	EndColumnIndex int64 `json:"endColumnIndex,omitempty"`

	// EndRowIndex: The end row (exclusive) of the range, or not set if
	// unbounded.
	EndRowIndex int64 `json:"endRowIndex,omitempty"`

	// SheetId: The sheet this range is on.
	SheetId int64 `json:"sheetId,omitempty"`

	// StartColumnIndex: The start column (inclusive) of the range, or not
	// set if unbounded.
	StartColumnIndex int64 `json:"startColumnIndex,omitempty"`

	// StartRowIndex: The start row (inclusive) of the range, or not set if
	// unbounded.
	StartRowIndex int64 `json:"startRowIndex,omitempty"`

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

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

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

// HistogramChartSpec: A histogram chart. A histogram chart groups data
// items into bins, displaying each bin as a column of stacked items.
// Histograms are used to display the distribution of a dataset. Each
// column of items represents a range into which those items fall. The
// number of bins can be chosen automatically or specified explicitly.
type HistogramChartSpec struct {
	// BucketSize: By default the bucket size (the range of values stacked
	// in a single column) is chosen automatically, but it may be overridden
	// here. E.g., A bucket size of 1.5 results in buckets from 0 - 1.5, 1.5
	// - 3.0, etc. Cannot be negative. This field is optional.
	BucketSize float64 `json:"bucketSize,omitempty"`

	// LegendPosition: The position of the chart legend.
	//
	// Possible values:
	//   "HISTOGRAM_CHART_LEGEND_POSITION_UNSPECIFIED" - Default value, do
	// not use.
	//   "BOTTOM_LEGEND" - The legend is rendered on the bottom of the
	// chart.
	//   "LEFT_LEGEND" - The legend is rendered on the left of the chart.
	//   "RIGHT_LEGEND" - The legend is rendered on the right of the chart.
	//   "TOP_LEGEND" - The legend is rendered on the top of the chart.
	//   "NO_LEGEND" - No legend is rendered.
	//   "INSIDE_LEGEND" - The legend is rendered inside the chart area.
	LegendPosition string `json:"legendPosition,omitempty"`

	// OutlierPercentile: The outlier percentile is used to ensure that
	// outliers do not adversely affect the calculation of bucket sizes. For
	// example, setting an outlier percentile of 0.05 indicates that the top
	// and bottom 5% of values when calculating buckets. The values are
	// still included in the chart, they will be added to the first or last
	// buckets instead of their own buckets. Must be between 0.0 and 0.5.
	OutlierPercentile float64 `json:"outlierPercentile,omitempty"`

	// Series: The series for a histogram may be either a single series of
	// values to be bucketed or multiple series, each of the same length,
	// containing the name of the series followed by the values to be
	// bucketed for that series.
	Series []*HistogramSeries `json:"series,omitempty"`

	// ShowItemDividers: Whether horizontal divider lines should be
	// displayed between items in each column.
	ShowItemDividers bool `json:"showItemDividers,omitempty"`

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

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

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

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

// HistogramRule: Allows you to organize the numeric values in a source
// data column into buckets of a constant size. All values from
// HistogramRule.start to HistogramRule.end are placed into groups of
// size HistogramRule.interval. In addition, all values below
// HistogramRule.start are placed in one group, and all values above
// HistogramRule.end are placed in another. Only HistogramRule.interval
// is required, though if HistogramRule.start and HistogramRule.end are
// both provided, HistogramRule.start must be less than
// HistogramRule.end. For example, a pivot table showing average
// purchase amount by age that has 50+ rows: +-----+-------------------+
// | Age | AVERAGE of Amount | +-----+-------------------+ | 16 | $27.13
// | | 17 | $5.24 | | 18 | $20.15 | ... +-----+-------------------+
// could be turned into a pivot table that looks like the one below by
// applying a histogram group rule with a HistogramRule.start of 25, an
// HistogramRule.interval of 20, and an HistogramRule.end of 65.
// +-------------+-------------------+ | Grouped Age | AVERAGE of Amount
// | +-------------+-------------------+ | < 25 | $19.34 | | 25-45 |
// $31.43 | | 45-65 | $35.87 | | > 65 | $27.55 |
// +-------------+-------------------+ | Grand Total | $29.12 |
// +-------------+-------------------+
type HistogramRule struct {
	// End: The maximum value at which items are placed into buckets of
	// constant size. Values above end are lumped into a single bucket. This
	// field is optional.
	End float64 `json:"end,omitempty"`

	// Interval: The size of the buckets that are created. Must be positive.
	Interval float64 `json:"interval,omitempty"`

	// Start: The minimum value at which items are placed into buckets of
	// constant size. Values below start are lumped into a single bucket.
	// This field is optional.
	Start float64 `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 *HistogramRule) MarshalJSON() ([]byte, error) {
	type NoMethod HistogramRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *HistogramRule) UnmarshalJSON(data []byte) error {
	type NoMethod HistogramRule
	var s1 struct {
		End      gensupport.JSONFloat64 `json:"end"`
		Interval gensupport.JSONFloat64 `json:"interval"`
		Start    gensupport.JSONFloat64 `json:"start"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.End = float64(s1.End)
	s.Interval = float64(s1.Interval)
	s.Start = float64(s1.Start)
	return nil
}

// HistogramSeries: A histogram series containing the series color and
// data.
type HistogramSeries struct {
	// BarColor: The color of the column representing this series in each
	// bucket. This field is optional.
	BarColor *Color `json:"barColor,omitempty"`

	// BarColorStyle: The color of the column representing this series in
	// each bucket. This field is optional. If bar_color is also set, this
	// field takes precedence.
	BarColorStyle *ColorStyle `json:"barColorStyle,omitempty"`

	// Data: The data for this histogram series.
	Data *ChartData `json:"data,omitempty"`

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

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

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

// InsertDimensionRequest: Inserts rows or columns in a sheet at a
// particular index.
type InsertDimensionRequest struct {
	// InheritFromBefore: Whether dimension properties should be extended
	// from the dimensions before or after the newly inserted dimensions.
	// True to inherit from the dimensions before (in which case the start
	// index must be greater than 0), and false to inherit from the
	// dimensions after. For example, if row index 0 has red background and
	// row index 1 has a green background, then inserting 2 rows at index 1
	// can inherit either the green or red background. If
	// `inheritFromBefore` is true, the two new rows will be red (because
	// the row before the insertion point was red), whereas if
	// `inheritFromBefore` is false, the two new rows will be green (because
	// the row after the insertion point was green).
	InheritFromBefore bool `json:"inheritFromBefore,omitempty"`

	// Range: The dimensions to insert. Both the start and end indexes must
	// be bounded.
	Range *DimensionRange `json:"range,omitempty"`

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

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

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

// InsertRangeRequest: Inserts cells into a range, shifting the existing
// cells over or down.
type InsertRangeRequest struct {
	// Range: The range to insert new cells into.
	Range *GridRange `json:"range,omitempty"`

	// ShiftDimension: The dimension which will be shifted when inserting
	// cells. If ROWS, existing cells will be shifted down. If COLUMNS,
	// existing cells will be shifted right.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
	//   "ROWS" - Operates on the rows of a sheet.
	//   "COLUMNS" - Operates on the columns of a sheet.
	ShiftDimension string `json:"shiftDimension,omitempty"`

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

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

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

// InterpolationPoint: A single interpolation point on a gradient
// conditional format. These pin the gradient color scale according to
// the color, type and value chosen.
type InterpolationPoint struct {
	// Color: The color this interpolation point should use.
	Color *Color `json:"color,omitempty"`

	// ColorStyle: The color this interpolation point should use. If color
	// is also set, this field takes precedence.
	ColorStyle *ColorStyle `json:"colorStyle,omitempty"`

	// Type: How the value should be interpreted.
	//
	// Possible values:
	//   "INTERPOLATION_POINT_TYPE_UNSPECIFIED" - The default value, do not
	// use.
	//   "MIN" - The interpolation point uses the minimum value in the cells
	// over the range of the conditional format.
	//   "MAX" - The interpolation point uses the maximum value in the cells
	// over the range of the conditional format.
	//   "NUMBER" - The interpolation point uses exactly the value in
	// InterpolationPoint.value.
	//   "PERCENT" - The interpolation point is the given percentage over
	// all the cells in the range of the conditional format. This is
	// equivalent to NUMBER if the value was: `=(MAX(FLATTEN(range)) *
	// (value / 100)) + (MIN(FLATTEN(range)) * (1 - (value / 100)))` (where
	// errors in the range are ignored when flattening).
	//   "PERCENTILE" - The interpolation point is the given percentile over
	// all the cells in the range of the conditional format. This is
	// equivalent to NUMBER if the value was: `=PERCENTILE(FLATTEN(range),
	// value / 100)` (where errors in the range are ignored when
	// flattening).
	Type string `json:"type,omitempty"`

	// Value: The value this interpolation point uses. May be a formula.
	// Unused if type is MIN or MAX.
	Value string `json:"value,omitempty"`

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

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

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

// Interval: Represents a time interval, encoded as a Timestamp start
// (inclusive) and a Timestamp end (exclusive). The start must be less
// than or equal to the end. When the start equals the end, the interval
// is empty (matches no time). When both start and end are unspecified,
// the interval matches any time.
type Interval struct {
	// EndTime: Optional. Exclusive end of the interval. If specified, a
	// Timestamp matching this interval will have to be before the end.
	EndTime string `json:"endTime,omitempty"`

	// StartTime: Optional. Inclusive start of the interval. If specified, a
	// Timestamp matching this interval will have to be the same or after
	// the start.
	StartTime string `json:"startTime,omitempty"`

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

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

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

// IterativeCalculationSettings: Settings to control how circular
// dependencies are resolved with iterative calculation.
type IterativeCalculationSettings struct {
	// ConvergenceThreshold: When iterative calculation is enabled and
	// successive results differ by less than this threshold value, the
	// calculation rounds stop.
	ConvergenceThreshold float64 `json:"convergenceThreshold,omitempty"`

	// MaxIterations: When iterative calculation is enabled, the maximum
	// number of calculation rounds to perform.
	MaxIterations int64 `json:"maxIterations,omitempty"`

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

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

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

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

// KeyValueFormat: Formatting options for key value.
type KeyValueFormat struct {
	// Position: Specifies the horizontal text positioning of key value.
	// This field is optional. If not specified, default positioning is
	// used.
	Position *TextPosition `json:"position,omitempty"`

	// TextFormat: Text formatting options for key value.
	TextFormat *TextFormat `json:"textFormat,omitempty"`

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

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

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

// LineStyle: Properties that describe the style of a line.
type LineStyle struct {
	// Type: The dash type of the line.
	//
	// Possible values:
	//   "LINE_DASH_TYPE_UNSPECIFIED" - Default value, do not use.
	//   "INVISIBLE" - No dash type, which is equivalent to a non-visible
	// line.
	//   "CUSTOM" - A custom dash for a line. Modifying the exact custom
	// dash style is currently unsupported.
	//   "SOLID" - A solid line.
	//   "DOTTED" - A dotted line.
	//   "MEDIUM_DASHED" - A dashed line where the dashes have "medium"
	// length.
	//   "MEDIUM_DASHED_DOTTED" - A line that alternates between a "medium"
	// dash and a dot.
	//   "LONG_DASHED" - A dashed line where the dashes have "long" length.
	//   "LONG_DASHED_DOTTED" - A line that alternates between a "long" dash
	// and a dot.
	Type string `json:"type,omitempty"`

	// Width: The thickness of the line, in px.
	Width int64 `json:"width,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 *LineStyle) MarshalJSON() ([]byte, error) {
	type NoMethod LineStyle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ManualRule: Allows you to manually organize the values in a source
// data column into buckets with names of your choosing. For example, a
// pivot table that aggregates population by state:
// +-------+-------------------+ | State | SUM of Population |
// +-------+-------------------+ | AK | 0.7 | | AL | 4.8 | | AR | 2.9 |
// ... +-------+-------------------+ could be turned into a pivot table
// that aggregates population by time zone by providing a list of groups
// (for example, groupName = 'Central', items = ['AL', 'AR', 'IA', ...])
// to a manual group rule. Note that a similar effect could be achieved
// by adding a time zone column to the source data and adjusting the
// pivot table. +-----------+-------------------+ | Time Zone | SUM of
// Population | +-----------+-------------------+ | Central | 106.3 | |
// Eastern | 151.9 | | Mountain | 17.4 | ...
// +-----------+-------------------+
type ManualRule struct {
	// Groups: The list of group names and the corresponding items from the
	// source data that map to each group name.
	Groups []*ManualRuleGroup `json:"groups,omitempty"`

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

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

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

// ManualRuleGroup: A group name and a list of items from the source
// data that should be placed in the group with this name.
type ManualRuleGroup struct {
	// GroupName: The group name, which must be a string. Each group in a
	// given ManualRule must have a unique group name.
	GroupName *ExtendedValue `json:"groupName,omitempty"`

	// Items: The items in the source data that should be placed into this
	// group. Each item may be a string, number, or boolean. Items may
	// appear in at most one group within a given ManualRule. Items that do
	// not appear in any group will appear on their own.
	Items []*ExtendedValue `json:"items,omitempty"`

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

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

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

// MatchedDeveloperMetadata: A developer metadata entry and the data
// filters specified in the original request that matched it.
type MatchedDeveloperMetadata struct {
	// DataFilters: All filters matching the returned developer metadata.
	DataFilters []*DataFilter `json:"dataFilters,omitempty"`

	// DeveloperMetadata: The developer metadata matching the specified
	// filters.
	DeveloperMetadata *DeveloperMetadata `json:"developerMetadata,omitempty"`

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

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

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

// MatchedValueRange: A value range that was matched by one or more data
// filers.
type MatchedValueRange struct {
	// DataFilters: The DataFilters from the request that matched the range
	// of values.
	DataFilters []*DataFilter `json:"dataFilters,omitempty"`

	// ValueRange: The values matched by the DataFilter.
	ValueRange *ValueRange `json:"valueRange,omitempty"`

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

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

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

// MergeCellsRequest: Merges all cells in the range.
type MergeCellsRequest struct {
	// MergeType: How the cells should be merged.
	//
	// Possible values:
	//   "MERGE_ALL" - Create a single merge from the range
	//   "MERGE_COLUMNS" - Create a merge for each column in the range
	//   "MERGE_ROWS" - Create a merge for each row in the range
	MergeType string `json:"mergeType,omitempty"`

	// Range: The range of cells to merge.
	Range *GridRange `json:"range,omitempty"`

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

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

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

// MoveDimensionRequest: Moves one or more rows or columns.
type MoveDimensionRequest struct {
	// DestinationIndex: The zero-based start index of where to move the
	// source data to, based on the coordinates *before* the source data is
	// removed from the grid. Existing data will be shifted down or right
	// (depending on the dimension) to make room for the moved dimensions.
	// The source dimensions are removed from the grid, so the the data may
	// end up in a different index than specified. For example, given
	// `A1..A5` of `0, 1, 2, 3, 4` and wanting to move "1" and "2" to
	// between "3" and "4", the source would be `ROWS [1..3)`,and the
	// destination index would be "4" (the zero-based index of row 5). The
	// end result would be `A1..A5` of `0, 3, 1, 2, 4`.
	DestinationIndex int64 `json:"destinationIndex,omitempty"`

	// Source: The source dimensions to move.
	Source *DimensionRange `json:"source,omitempty"`

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

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

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

// NamedRange: A named range.
type NamedRange struct {
	// Name: The name of the named range.
	Name string `json:"name,omitempty"`

	// NamedRangeId: The ID of the named range.
	NamedRangeId string `json:"namedRangeId,omitempty"`

	// Range: The range this represents.
	Range *GridRange `json:"range,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 *NamedRange) MarshalJSON() ([]byte, error) {
	type NoMethod NamedRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NumberFormat: The number format of a cell.
type NumberFormat struct {
	// Pattern: Pattern string used for formatting. If not set, a default
	// pattern based on the user's locale will be used if necessary for the
	// given type. See the [Date and Number Formats
	// guide](/sheets/api/guides/formats) for more information about the
	// supported patterns.
	Pattern string `json:"pattern,omitempty"`

	// Type: The type of the number format. When writing, this field must be
	// set.
	//
	// Possible values:
	//   "NUMBER_FORMAT_TYPE_UNSPECIFIED" - The number format is not
	// specified and is based on the contents of the cell. Do not explicitly
	// use this.
	//   "TEXT" - Text formatting, e.g `1000.12`
	//   "NUMBER" - Number formatting, e.g, `1,000.12`
	//   "PERCENT" - Percent formatting, e.g `10.12%`
	//   "CURRENCY" - Currency formatting, e.g `$1,000.12`
	//   "DATE" - Date formatting, e.g `9/26/2008`
	//   "TIME" - Time formatting, e.g `3:59:00 PM`
	//   "DATE_TIME" - Date+Time formatting, e.g `9/26/08 15:59:00`
	//   "SCIENTIFIC" - Scientific number formatting, e.g `1.01E+03`
	Type string `json:"type,omitempty"`

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

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

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

// OrgChartSpec: An org chart. Org charts require a unique set of labels
// in labels and may optionally include parent_labels and tooltips.
// parent_labels contain, for each node, the label identifying the
// parent node. tooltips contain, for each node, an optional tooltip.
// For example, to describe an OrgChart with Alice as the CEO, Bob as
// the President (reporting to Alice) and Cathy as VP of Sales (also
// reporting to Alice), have labels contain "Alice", "Bob", "Cathy",
// parent_labels contain "", "Alice", "Alice" and tooltips contain
// "CEO", "President", "VP Sales".
type OrgChartSpec struct {
	// Labels: The data containing the labels for all the nodes in the
	// chart. Labels must be unique.
	Labels *ChartData `json:"labels,omitempty"`

	// NodeColor: The color of the org chart nodes.
	NodeColor *Color `json:"nodeColor,omitempty"`

	// NodeColorStyle: The color of the org chart nodes. If node_color is
	// also set, this field takes precedence.
	NodeColorStyle *ColorStyle `json:"nodeColorStyle,omitempty"`

	// NodeSize: The size of the org chart nodes.
	//
	// Possible values:
	//   "ORG_CHART_LABEL_SIZE_UNSPECIFIED" - Default value, do not use.
	//   "SMALL" - The small org chart node size.
	//   "MEDIUM" - The medium org chart node size.
	//   "LARGE" - The large org chart node size.
	NodeSize string `json:"nodeSize,omitempty"`

	// ParentLabels: The data containing the label of the parent for the
	// corresponding node. A blank value indicates that the node has no
	// parent and is a top-level node. This field is optional.
	ParentLabels *ChartData `json:"parentLabels,omitempty"`

	// SelectedNodeColor: The color of the selected org chart nodes.
	SelectedNodeColor *Color `json:"selectedNodeColor,omitempty"`

	// SelectedNodeColorStyle: The color of the selected org chart nodes. If
	// selected_node_color is also set, this field takes precedence.
	SelectedNodeColorStyle *ColorStyle `json:"selectedNodeColorStyle,omitempty"`

	// Tooltips: The data containing the tooltip for the corresponding node.
	// A blank value results in no tooltip being displayed for the node.
	// This field is optional.
	Tooltips *ChartData `json:"tooltips,omitempty"`

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

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

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

// OverlayPosition: The location an object is overlaid on top of a grid.
type OverlayPosition struct {
	// AnchorCell: The cell the object is anchored to.
	AnchorCell *GridCoordinate `json:"anchorCell,omitempty"`

	// HeightPixels: The height of the object, in pixels. Defaults to 371.
	HeightPixels int64 `json:"heightPixels,omitempty"`

	// OffsetXPixels: The horizontal offset, in pixels, that the object is
	// offset from the anchor cell.
	OffsetXPixels int64 `json:"offsetXPixels,omitempty"`

	// OffsetYPixels: The vertical offset, in pixels, that the object is
	// offset from the anchor cell.
	OffsetYPixels int64 `json:"offsetYPixels,omitempty"`

	// WidthPixels: The width of the object, in pixels. Defaults to 600.
	WidthPixels int64 `json:"widthPixels,omitempty"`

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

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

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

// Padding: The amount of padding around the cell, in pixels. When
// updating padding, every field must be specified.
type Padding struct {
	// Bottom: The bottom padding of the cell.
	Bottom int64 `json:"bottom,omitempty"`

	// Left: The left padding of the cell.
	Left int64 `json:"left,omitempty"`

	// Right: The right padding of the cell.
	Right int64 `json:"right,omitempty"`

	// Top: The top padding of the cell.
	Top int64 `json:"top,omitempty"`

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

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

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

// PasteDataRequest: Inserts data into the spreadsheet starting at the
// specified coordinate.
type PasteDataRequest struct {
	// Coordinate: The coordinate at which the data should start being
	// inserted.
	Coordinate *GridCoordinate `json:"coordinate,omitempty"`

	// Data: The data to insert.
	Data string `json:"data,omitempty"`

	// Delimiter: The delimiter in the data.
	Delimiter string `json:"delimiter,omitempty"`

	// Html: True if the data is HTML.
	Html bool `json:"html,omitempty"`

	// Type: How the data should be pasted.
	//
	// Possible values:
	//   "PASTE_NORMAL" - Paste values, formulas, formats, and merges.
	//   "PASTE_VALUES" - Paste the values ONLY without formats, formulas,
	// or merges.
	//   "PASTE_FORMAT" - Paste the format and data validation only.
	//   "PASTE_NO_BORDERS" - Like PASTE_NORMAL but without borders.
	//   "PASTE_FORMULA" - Paste the formulas only.
	//   "PASTE_DATA_VALIDATION" - Paste the data validation only.
	//   "PASTE_CONDITIONAL_FORMATTING" - Paste the conditional formatting
	// rules only.
	Type string `json:"type,omitempty"`

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

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

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

// PieChartSpec: A pie chart.
type PieChartSpec struct {
	// Domain: The data that covers the domain of the pie chart.
	Domain *ChartData `json:"domain,omitempty"`

	// LegendPosition: Where the legend of the pie chart should be drawn.
	//
	// Possible values:
	//   "PIE_CHART_LEGEND_POSITION_UNSPECIFIED" - Default value, do not
	// use.
	//   "BOTTOM_LEGEND" - The legend is rendered on the bottom of the
	// chart.
	//   "LEFT_LEGEND" - The legend is rendered on the left of the chart.
	//   "RIGHT_LEGEND" - The legend is rendered on the right of the chart.
	//   "TOP_LEGEND" - The legend is rendered on the top of the chart.
	//   "NO_LEGEND" - No legend is rendered.
	//   "LABELED_LEGEND" - Each pie slice has a label attached to it.
	LegendPosition string `json:"legendPosition,omitempty"`

	// PieHole: The size of the hole in the pie chart.
	PieHole float64 `json:"pieHole,omitempty"`

	// Series: The data that covers the one and only series of the pie
	// chart.
	Series *ChartData `json:"series,omitempty"`

	// ThreeDimensional: True if the pie is three dimensional.
	ThreeDimensional bool `json:"threeDimensional,omitempty"`

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

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

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

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

// PivotFilterCriteria: Criteria for showing/hiding rows in a pivot
// table.
type PivotFilterCriteria struct {
	// VisibleValues: Values that should be included. Values not listed here
	// are excluded.
	VisibleValues []string `json:"visibleValues,omitempty"`

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

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

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

// PivotFilterSpec: The pivot table filter criteria associated with a
// specific source column offset.
type PivotFilterSpec struct {
	// ColumnOffsetIndex: The column offset of the source range.
	ColumnOffsetIndex int64 `json:"columnOffsetIndex,omitempty"`

	// DataSourceColumnReference: The reference to the data source column.
	DataSourceColumnReference *DataSourceColumnReference `json:"dataSourceColumnReference,omitempty"`

	// FilterCriteria: The criteria for the column.
	FilterCriteria *PivotFilterCriteria `json:"filterCriteria,omitempty"`

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

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

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

// PivotGroup: A single grouping (either row or column) in a pivot
// table.
type PivotGroup struct {
	// DataSourceColumnReference: The reference to the data source column
	// this grouping is based on.
	DataSourceColumnReference *DataSourceColumnReference `json:"dataSourceColumnReference,omitempty"`

	// GroupLimit: The count limit on rows or columns to apply to this pivot
	// group.
	GroupLimit *PivotGroupLimit `json:"groupLimit,omitempty"`

	// GroupRule: The group rule to apply to this row/column group.
	GroupRule *PivotGroupRule `json:"groupRule,omitempty"`

	// Label: The labels to use for the row/column groups which can be
	// customized. For example, in the following pivot table, the row label
	// is `Region` (which could be renamed to `State`) and the column label
	// is `Product` (which could be renamed `Item`). Pivot tables created
	// before December 2017 do not have header labels. If you'd like to add
	// header labels to an existing pivot table, please delete the existing
	// pivot table and then create a new pivot table with same parameters.
	// +--------------+---------+-------+ | SUM of Units | Product | | |
	// Region | Pen | Paper | +--------------+---------+-------+ | New York
	// | 345 | 98 | | Oregon | 234 | 123 | | Tennessee | 531 | 415 |
	// +--------------+---------+-------+ | Grand Total | 1110 | 636 |
	// +--------------+---------+-------+
	Label string `json:"label,omitempty"`

	// RepeatHeadings: True if the headings in this pivot group should be
	// repeated. This is only valid for row groupings and is ignored by
	// columns. By default, we minimize repitition of headings by not
	// showing higher level headings where they are the same. For example,
	// even though the third row below corresponds to "Q1 Mar", "Q1" is not
	// shown because it is redundant with previous rows. Setting
	// repeat_headings to true would cause "Q1" to be repeated for "Feb" and
	// "Mar". +--------------+ | Q1 | Jan | | | Feb | | | Mar |
	// +--------+-----+ | Q1 Total | +--------------+
	RepeatHeadings bool `json:"repeatHeadings,omitempty"`

	// ShowTotals: True if the pivot table should include the totals for
	// this grouping.
	ShowTotals bool `json:"showTotals,omitempty"`

	// SortOrder: The order the values in this group should be sorted.
	//
	// Possible values:
	//   "SORT_ORDER_UNSPECIFIED" - Default value, do not use this.
	//   "ASCENDING" - Sort ascending.
	//   "DESCENDING" - Sort descending.
	SortOrder string `json:"sortOrder,omitempty"`

	// SourceColumnOffset: The column offset of the source range that this
	// grouping is based on. For example, if the source was `C10:E15`, a
	// `sourceColumnOffset` of `0` means this group refers to column `C`,
	// whereas the offset `1` would refer to column `D`.
	SourceColumnOffset int64 `json:"sourceColumnOffset,omitempty"`

	// ValueBucket: The bucket of the opposite pivot group to sort by. If
	// not specified, sorting is alphabetical by this group's values.
	ValueBucket *PivotGroupSortValueBucket `json:"valueBucket,omitempty"`

	// ValueMetadata: Metadata about values in the grouping.
	ValueMetadata []*PivotGroupValueMetadata `json:"valueMetadata,omitempty"`

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

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

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

// PivotGroupLimit: The count limit on rows or columns in the pivot
// group.
type PivotGroupLimit struct {
	// ApplyOrder: The order in which the group limit is applied to the
	// pivot table. Pivot group limits are applied from lower to higher
	// order number. Order numbers are normalized to consecutive integers
	// from 0. For write request, to fully customize the applying orders,
	// all pivot group limits should have this field set with an unique
	// number. Otherwise, the order is determined by the index in the
	// PivotTable.rows list and then the PivotTable.columns list.
	ApplyOrder int64 `json:"applyOrder,omitempty"`

	// CountLimit: The count limit.
	CountLimit int64 `json:"countLimit,omitempty"`

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

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

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

// PivotGroupRule: An optional setting on a PivotGroup that defines
// buckets for the values in the source data column rather than breaking
// out each individual value. Only one PivotGroup with a group rule may
// be added for each column in the source data, though on any given
// column you may add both a PivotGroup that has a rule and a PivotGroup
// that does not.
type PivotGroupRule struct {
	// DateTimeRule: A DateTimeRule.
	DateTimeRule *DateTimeRule `json:"dateTimeRule,omitempty"`

	// HistogramRule: A HistogramRule.
	HistogramRule *HistogramRule `json:"histogramRule,omitempty"`

	// ManualRule: A ManualRule.
	ManualRule *ManualRule `json:"manualRule,omitempty"`

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

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

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

// PivotGroupSortValueBucket: Information about which values in a pivot
// group should be used for sorting.
type PivotGroupSortValueBucket struct {
	// Buckets: Determines the bucket from which values are chosen to sort.
	// For example, in a pivot table with one row group & two column groups,
	// the row group can list up to two values. The first value corresponds
	// to a value within the first column group, and the second value
	// corresponds to a value in the second column group. If no values are
	// listed, this would indicate that the row should be sorted according
	// to the "Grand Total" over the column groups. If a single value is
	// listed, this would correspond to using the "Total" of that bucket.
	Buckets []*ExtendedValue `json:"buckets,omitempty"`

	// ValuesIndex: The offset in the PivotTable.values list which the
	// values in this grouping should be sorted by.
	ValuesIndex int64 `json:"valuesIndex,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 *PivotGroupSortValueBucket) MarshalJSON() ([]byte, error) {
	type NoMethod PivotGroupSortValueBucket
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PivotGroupValueMetadata: Metadata about a value in a pivot grouping.
type PivotGroupValueMetadata struct {
	// Collapsed: True if the data corresponding to the value is collapsed.
	Collapsed bool `json:"collapsed,omitempty"`

	// Value: The calculated value the metadata corresponds to. (Note that
	// formulaValue is not valid, because the values will be calculated.)
	Value *ExtendedValue `json:"value,omitempty"`

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

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

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

// PivotTable: A pivot table.
type PivotTable struct {
	// Columns: Each column grouping in the pivot table.
	Columns []*PivotGroup `json:"columns,omitempty"`

	// Criteria: An optional mapping of filters per source column offset.
	// The filters are applied before aggregating data into the pivot table.
	// The map's key is the column offset of the source range that you want
	// to filter, and the value is the criteria for that column. For
	// example, if the source was `C10:E15`, a key of `0` will have the
	// filter for column `C`, whereas the key `1` is for column `D`.
	Criteria map[string]PivotFilterCriteria `json:"criteria,omitempty"`

	// DataExecutionStatus: Output only. The data execution status for data
	// source pivot tables.
	DataExecutionStatus *DataExecutionStatus `json:"dataExecutionStatus,omitempty"`

	// DataSourceId: The ID of the data source the pivot table is reading
	// data from.
	DataSourceId string `json:"dataSourceId,omitempty"`

	// FilterSpecs: The filters applied to the source columns before
	// aggregating data for the pivot table. Both criteria and filter_specs
	// are populated in responses. If both fields are specified in an update
	// request, this field takes precedence.
	FilterSpecs []*PivotFilterSpec `json:"filterSpecs,omitempty"`

	// Rows: Each row grouping in the pivot table.
	Rows []*PivotGroup `json:"rows,omitempty"`

	// Source: The range the pivot table is reading data from.
	Source *GridRange `json:"source,omitempty"`

	// ValueLayout: Whether values should be listed horizontally (as
	// columns) or vertically (as rows).
	//
	// Possible values:
	//   "HORIZONTAL" - Values are laid out horizontally (as columns).
	//   "VERTICAL" - Values are laid out vertically (as rows).
	ValueLayout string `json:"valueLayout,omitempty"`

	// Values: A list of values to include in the pivot table.
	Values []*PivotValue `json:"values,omitempty"`

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

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

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

// PivotValue: The definition of how a value in a pivot table should be
// calculated.
type PivotValue struct {
	// CalculatedDisplayType: If specified, indicates that pivot values
	// should be displayed as the result of a calculation with another pivot
	// value. For example, if calculated_display_type is specified as
	// PERCENT_OF_GRAND_TOTAL, all the pivot values are displayed as the
	// percentage of the grand total. In the Sheets editor, this is referred
	// to as "Show As" in the value section of a pivot table.
	//
	// Possible values:
	//   "PIVOT_VALUE_CALCULATED_DISPLAY_TYPE_UNSPECIFIED" - Default value,
	// do not use.
	//   "PERCENT_OF_ROW_TOTAL" - Shows the pivot values as percentage of
	// the row total values.
	//   "PERCENT_OF_COLUMN_TOTAL" - Shows the pivot values as percentage of
	// the column total values.
	//   "PERCENT_OF_GRAND_TOTAL" - Shows the pivot values as percentage of
	// the grand total values.
	CalculatedDisplayType string `json:"calculatedDisplayType,omitempty"`

	// DataSourceColumnReference: The reference to the data source column
	// that this value reads from.
	DataSourceColumnReference *DataSourceColumnReference `json:"dataSourceColumnReference,omitempty"`

	// Formula: A custom formula to calculate the value. The formula must
	// start with an `=` character.
	Formula string `json:"formula,omitempty"`

	// Name: A name to use for the value.
	Name string `json:"name,omitempty"`

	// SourceColumnOffset: The column offset of the source range that this
	// value reads from. For example, if the source was `C10:E15`, a
	// `sourceColumnOffset` of `0` means this value refers to column `C`,
	// whereas the offset `1` would refer to column `D`.
	SourceColumnOffset int64 `json:"sourceColumnOffset,omitempty"`

	// SummarizeFunction: A function to summarize the value. If formula is
	// set, the only supported values are SUM and CUSTOM. If
	// sourceColumnOffset is set, then `CUSTOM` is not supported.
	//
	// Possible values:
	//   "PIVOT_STANDARD_VALUE_FUNCTION_UNSPECIFIED" - The default, do not
	// use.
	//   "SUM" - Corresponds to the `SUM` function.
	//   "COUNTA" - Corresponds to the `COUNTA` function.
	//   "COUNT" - Corresponds to the `COUNT` function.
	//   "COUNTUNIQUE" - Corresponds to the `COUNTUNIQUE` function.
	//   "AVERAGE" - Corresponds to the `AVERAGE` function.
	//   "MAX" - Corresponds to the `MAX` function.
	//   "MIN" - Corresponds to the `MIN` function.
	//   "MEDIAN" - Corresponds to the `MEDIAN` function.
	//   "PRODUCT" - Corresponds to the `PRODUCT` function.
	//   "STDEV" - Corresponds to the `STDEV` function.
	//   "STDEVP" - Corresponds to the `STDEVP` function.
	//   "VAR" - Corresponds to the `VAR` function.
	//   "VARP" - Corresponds to the `VARP` function.
	//   "CUSTOM" - Indicates the formula should be used as-is. Only valid
	// if PivotValue.formula was set.
	SummarizeFunction string `json:"summarizeFunction,omitempty"`

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

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

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

// ProtectedRange: A protected range.
type ProtectedRange struct {
	// Description: The description of this protected range.
	Description string `json:"description,omitempty"`

	// Editors: The users and groups with edit access to the protected
	// range. This field is only visible to users with edit access to the
	// protected range and the document. Editors are not supported with
	// warning_only protection.
	Editors *Editors `json:"editors,omitempty"`

	// NamedRangeId: The named range this protected range is backed by, if
	// any. When writing, only one of range or named_range_id may be set.
	NamedRangeId string `json:"namedRangeId,omitempty"`

	// ProtectedRangeId: The ID of the protected range. This field is
	// read-only.
	ProtectedRangeId int64 `json:"protectedRangeId,omitempty"`

	// Range: The range that is being protected. The range may be fully
	// unbounded, in which case this is considered a protected sheet. When
	// writing, only one of range or named_range_id may be set.
	Range *GridRange `json:"range,omitempty"`

	// RequestingUserCanEdit: True if the user who requested this protected
	// range can edit the protected area. This field is read-only.
	RequestingUserCanEdit bool `json:"requestingUserCanEdit,omitempty"`

	// UnprotectedRanges: The list of unprotected ranges within a protected
	// sheet. Unprotected ranges are only supported on protected sheets.
	UnprotectedRanges []*GridRange `json:"unprotectedRanges,omitempty"`

	// WarningOnly: True if this protected range will show a warning when
	// editing. Warning-based protection means that every user can edit data
	// in the protected range, except editing will prompt a warning asking
	// the user to confirm the edit. When writing: if this field is true,
	// then editors is ignored. Additionally, if this field is changed from
	// true to false and the `editors` field is not set (nor included in the
	// field mask), then the editors will be set to all the editors in the
	// document.
	WarningOnly bool `json:"warningOnly,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 *ProtectedRange) MarshalJSON() ([]byte, error) {
	type NoMethod ProtectedRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RandomizeRangeRequest: Randomizes the order of the rows in a range.
type RandomizeRangeRequest struct {
	// Range: The range to randomize.
	Range *GridRange `json:"range,omitempty"`

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

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

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

// RefreshDataSourceObjectExecutionStatus: The execution status of
// refreshing one data source object.
type RefreshDataSourceObjectExecutionStatus struct {
	// DataExecutionStatus: The data execution status.
	DataExecutionStatus *DataExecutionStatus `json:"dataExecutionStatus,omitempty"`

	// Reference: Reference to a data source object being refreshed.
	Reference *DataSourceObjectReference `json:"reference,omitempty"`

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

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

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

// RefreshDataSourceRequest: Refreshes one or multiple data source
// objects in the spreadsheet by the specified references. The request
// requires an additional bigquery.readonly OAuth scope. If there're
// multiple refresh requests referencing the same data source objects in
// one batch, only the last refresh request is processed, and all those
// requests will have the same response accordingly.
type RefreshDataSourceRequest struct {
	// DataSourceId: Reference to a DataSource. If specified, refreshes all
	// associated data source objects for the data source.
	DataSourceId string `json:"dataSourceId,omitempty"`

	// Force: Refreshes the data source objects regardless of the current
	// state. If not set and a referenced data source object was in error
	// state, the refresh will fail immediately.
	Force bool `json:"force,omitempty"`

	// IsAll: Refreshes all existing data source objects in the spreadsheet.
	IsAll bool `json:"isAll,omitempty"`

	// References: References to data source objects to refresh.
	References *DataSourceObjectReferences `json:"references,omitempty"`

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

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

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

// RefreshDataSourceResponse: The response from refreshing one or
// multiple data source objects.
type RefreshDataSourceResponse struct {
	// Statuses: All the refresh status for the data source object
	// references specified in the request. If is_all is specified, the
	// field contains only those in failure status.
	Statuses []*RefreshDataSourceObjectExecutionStatus `json:"statuses,omitempty"`

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

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

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

// RepeatCellRequest: Updates all cells in the range to the values in
// the given Cell object. Only the fields listed in the fields field are
// updated; others are unchanged. If writing a cell with a formula, the
// formula's ranges will automatically increment for each field in the
// range. For example, if writing a cell with formula `=A1` into range
// B2:C4, B2 would be `=A1`, B3 would be `=A2`, B4 would be `=A3`, C2
// would be `=B1`, C3 would be `=B2`, C4 would be `=B3`. To keep the
// formula's ranges static, use the `$` indicator. For example, use the
// formula `=$A$1` to prevent both the row and the column from
// incrementing.
type RepeatCellRequest struct {
	// Cell: The data to write.
	Cell *CellData `json:"cell,omitempty"`

	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `cell` is implied and should not be specified. A
	// single "*" can be used as short-hand for listing every field.
	Fields string `json:"fields,omitempty"`

	// Range: The range to repeat the cell in.
	Range *GridRange `json:"range,omitempty"`

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

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

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

// Request: A single kind of update to apply to a spreadsheet.
type Request struct {
	// AddBanding: Adds a new banded range
	AddBanding *AddBandingRequest `json:"addBanding,omitempty"`

	// AddChart: Adds a chart.
	AddChart *AddChartRequest `json:"addChart,omitempty"`

	// AddConditionalFormatRule: Adds a new conditional format rule.
	AddConditionalFormatRule *AddConditionalFormatRuleRequest `json:"addConditionalFormatRule,omitempty"`

	// AddDataSource: Adds a data source.
	AddDataSource *AddDataSourceRequest `json:"addDataSource,omitempty"`

	// AddDimensionGroup: Creates a group over the specified range.
	AddDimensionGroup *AddDimensionGroupRequest `json:"addDimensionGroup,omitempty"`

	// AddFilterView: Adds a filter view.
	AddFilterView *AddFilterViewRequest `json:"addFilterView,omitempty"`

	// AddNamedRange: Adds a named range.
	AddNamedRange *AddNamedRangeRequest `json:"addNamedRange,omitempty"`

	// AddProtectedRange: Adds a protected range.
	AddProtectedRange *AddProtectedRangeRequest `json:"addProtectedRange,omitempty"`

	// AddSheet: Adds a sheet.
	AddSheet *AddSheetRequest `json:"addSheet,omitempty"`

	// AddSlicer: Adds a slicer.
	AddSlicer *AddSlicerRequest `json:"addSlicer,omitempty"`

	// AppendCells: Appends cells after the last row with data in a sheet.
	AppendCells *AppendCellsRequest `json:"appendCells,omitempty"`

	// AppendDimension: Appends dimensions to the end of a sheet.
	AppendDimension *AppendDimensionRequest `json:"appendDimension,omitempty"`

	// AutoFill: Automatically fills in more data based on existing data.
	AutoFill *AutoFillRequest `json:"autoFill,omitempty"`

	// AutoResizeDimensions: Automatically resizes one or more dimensions
	// based on the contents of the cells in that dimension.
	AutoResizeDimensions *AutoResizeDimensionsRequest `json:"autoResizeDimensions,omitempty"`

	// ClearBasicFilter: Clears the basic filter on a sheet.
	ClearBasicFilter *ClearBasicFilterRequest `json:"clearBasicFilter,omitempty"`

	// CopyPaste: Copies data from one area and pastes it to another.
	CopyPaste *CopyPasteRequest `json:"copyPaste,omitempty"`

	// CreateDeveloperMetadata: Creates new developer metadata
	CreateDeveloperMetadata *CreateDeveloperMetadataRequest `json:"createDeveloperMetadata,omitempty"`

	// CutPaste: Cuts data from one area and pastes it to another.
	CutPaste *CutPasteRequest `json:"cutPaste,omitempty"`

	// DeleteBanding: Removes a banded range
	DeleteBanding *DeleteBandingRequest `json:"deleteBanding,omitempty"`

	// DeleteConditionalFormatRule: Deletes an existing conditional format
	// rule.
	DeleteConditionalFormatRule *DeleteConditionalFormatRuleRequest `json:"deleteConditionalFormatRule,omitempty"`

	// DeleteDataSource: Deletes a data source.
	DeleteDataSource *DeleteDataSourceRequest `json:"deleteDataSource,omitempty"`

	// DeleteDeveloperMetadata: Deletes developer metadata
	DeleteDeveloperMetadata *DeleteDeveloperMetadataRequest `json:"deleteDeveloperMetadata,omitempty"`

	// DeleteDimension: Deletes rows or columns in a sheet.
	DeleteDimension *DeleteDimensionRequest `json:"deleteDimension,omitempty"`

	// DeleteDimensionGroup: Deletes a group over the specified range.
	DeleteDimensionGroup *DeleteDimensionGroupRequest `json:"deleteDimensionGroup,omitempty"`

	// DeleteDuplicates: Removes rows containing duplicate values in
	// specified columns of a cell range.
	DeleteDuplicates *DeleteDuplicatesRequest `json:"deleteDuplicates,omitempty"`

	// DeleteEmbeddedObject: Deletes an embedded object (e.g, chart, image)
	// in a sheet.
	DeleteEmbeddedObject *DeleteEmbeddedObjectRequest `json:"deleteEmbeddedObject,omitempty"`

	// DeleteFilterView: Deletes a filter view from a sheet.
	DeleteFilterView *DeleteFilterViewRequest `json:"deleteFilterView,omitempty"`

	// DeleteNamedRange: Deletes a named range.
	DeleteNamedRange *DeleteNamedRangeRequest `json:"deleteNamedRange,omitempty"`

	// DeleteProtectedRange: Deletes a protected range.
	DeleteProtectedRange *DeleteProtectedRangeRequest `json:"deleteProtectedRange,omitempty"`

	// DeleteRange: Deletes a range of cells from a sheet, shifting the
	// remaining cells.
	DeleteRange *DeleteRangeRequest `json:"deleteRange,omitempty"`

	// DeleteSheet: Deletes a sheet.
	DeleteSheet *DeleteSheetRequest `json:"deleteSheet,omitempty"`

	// DuplicateFilterView: Duplicates a filter view.
	DuplicateFilterView *DuplicateFilterViewRequest `json:"duplicateFilterView,omitempty"`

	// DuplicateSheet: Duplicates a sheet.
	DuplicateSheet *DuplicateSheetRequest `json:"duplicateSheet,omitempty"`

	// FindReplace: Finds and replaces occurrences of some text with other
	// text.
	FindReplace *FindReplaceRequest `json:"findReplace,omitempty"`

	// InsertDimension: Inserts new rows or columns in a sheet.
	InsertDimension *InsertDimensionRequest `json:"insertDimension,omitempty"`

	// InsertRange: Inserts new cells in a sheet, shifting the existing
	// cells.
	InsertRange *InsertRangeRequest `json:"insertRange,omitempty"`

	// MergeCells: Merges cells together.
	MergeCells *MergeCellsRequest `json:"mergeCells,omitempty"`

	// MoveDimension: Moves rows or columns to another location in a sheet.
	MoveDimension *MoveDimensionRequest `json:"moveDimension,omitempty"`

	// PasteData: Pastes data (HTML or delimited) into a sheet.
	PasteData *PasteDataRequest `json:"pasteData,omitempty"`

	// RandomizeRange: Randomizes the order of the rows in a range.
	RandomizeRange *RandomizeRangeRequest `json:"randomizeRange,omitempty"`

	// RefreshDataSource: Refreshs one or multiple data sources and
	// associated dbobjects.
	RefreshDataSource *RefreshDataSourceRequest `json:"refreshDataSource,omitempty"`

	// RepeatCell: Repeats a single cell across a range.
	RepeatCell *RepeatCellRequest `json:"repeatCell,omitempty"`

	// SetBasicFilter: Sets the basic filter on a sheet.
	SetBasicFilter *SetBasicFilterRequest `json:"setBasicFilter,omitempty"`

	// SetDataValidation: Sets data validation for one or more cells.
	SetDataValidation *SetDataValidationRequest `json:"setDataValidation,omitempty"`

	// SortRange: Sorts data in a range.
	SortRange *SortRangeRequest `json:"sortRange,omitempty"`

	// TextToColumns: Converts a column of text into many columns of text.
	TextToColumns *TextToColumnsRequest `json:"textToColumns,omitempty"`

	// TrimWhitespace: Trims cells of whitespace (such as spaces, tabs, or
	// new lines).
	TrimWhitespace *TrimWhitespaceRequest `json:"trimWhitespace,omitempty"`

	// UnmergeCells: Unmerges merged cells.
	UnmergeCells *UnmergeCellsRequest `json:"unmergeCells,omitempty"`

	// UpdateBanding: Updates a banded range
	UpdateBanding *UpdateBandingRequest `json:"updateBanding,omitempty"`

	// UpdateBorders: Updates the borders in a range of cells.
	UpdateBorders *UpdateBordersRequest `json:"updateBorders,omitempty"`

	// UpdateCells: Updates many cells at once.
	UpdateCells *UpdateCellsRequest `json:"updateCells,omitempty"`

	// UpdateChartSpec: Updates a chart's specifications.
	UpdateChartSpec *UpdateChartSpecRequest `json:"updateChartSpec,omitempty"`

	// UpdateConditionalFormatRule: Updates an existing conditional format
	// rule.
	UpdateConditionalFormatRule *UpdateConditionalFormatRuleRequest `json:"updateConditionalFormatRule,omitempty"`

	// UpdateDataSource: Updates a data source.
	UpdateDataSource *UpdateDataSourceRequest `json:"updateDataSource,omitempty"`

	// UpdateDeveloperMetadata: Updates an existing developer metadata entry
	UpdateDeveloperMetadata *UpdateDeveloperMetadataRequest `json:"updateDeveloperMetadata,omitempty"`

	// UpdateDimensionGroup: Updates the state of the specified group.
	UpdateDimensionGroup *UpdateDimensionGroupRequest `json:"updateDimensionGroup,omitempty"`

	// UpdateDimensionProperties: Updates dimensions' properties.
	UpdateDimensionProperties *UpdateDimensionPropertiesRequest `json:"updateDimensionProperties,omitempty"`

	// UpdateEmbeddedObjectPosition: Updates an embedded object's (e.g.
	// chart, image) position.
	UpdateEmbeddedObjectPosition *UpdateEmbeddedObjectPositionRequest `json:"updateEmbeddedObjectPosition,omitempty"`

	// UpdateFilterView: Updates the properties of a filter view.
	UpdateFilterView *UpdateFilterViewRequest `json:"updateFilterView,omitempty"`

	// UpdateNamedRange: Updates a named range.
	UpdateNamedRange *UpdateNamedRangeRequest `json:"updateNamedRange,omitempty"`

	// UpdateProtectedRange: Updates a protected range.
	UpdateProtectedRange *UpdateProtectedRangeRequest `json:"updateProtectedRange,omitempty"`

	// UpdateSheetProperties: Updates a sheet's properties.
	UpdateSheetProperties *UpdateSheetPropertiesRequest `json:"updateSheetProperties,omitempty"`

	// UpdateSlicerSpec: Updates a slicer's specifications.
	UpdateSlicerSpec *UpdateSlicerSpecRequest `json:"updateSlicerSpec,omitempty"`

	// UpdateSpreadsheetProperties: Updates the spreadsheet's properties.
	UpdateSpreadsheetProperties *UpdateSpreadsheetPropertiesRequest `json:"updateSpreadsheetProperties,omitempty"`

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

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

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

// Response: A single response from an update.
type Response struct {
	// AddBanding: A reply from adding a banded range.
	AddBanding *AddBandingResponse `json:"addBanding,omitempty"`

	// AddChart: A reply from adding a chart.
	AddChart *AddChartResponse `json:"addChart,omitempty"`

	// AddDataSource: A reply from adding a data source.
	AddDataSource *AddDataSourceResponse `json:"addDataSource,omitempty"`

	// AddDimensionGroup: A reply from adding a dimension group.
	AddDimensionGroup *AddDimensionGroupResponse `json:"addDimensionGroup,omitempty"`

	// AddFilterView: A reply from adding a filter view.
	AddFilterView *AddFilterViewResponse `json:"addFilterView,omitempty"`

	// AddNamedRange: A reply from adding a named range.
	AddNamedRange *AddNamedRangeResponse `json:"addNamedRange,omitempty"`

	// AddProtectedRange: A reply from adding a protected range.
	AddProtectedRange *AddProtectedRangeResponse `json:"addProtectedRange,omitempty"`

	// AddSheet: A reply from adding a sheet.
	AddSheet *AddSheetResponse `json:"addSheet,omitempty"`

	// AddSlicer: A reply from adding a slicer.
	AddSlicer *AddSlicerResponse `json:"addSlicer,omitempty"`

	// CreateDeveloperMetadata: A reply from creating a developer metadata
	// entry.
	CreateDeveloperMetadata *CreateDeveloperMetadataResponse `json:"createDeveloperMetadata,omitempty"`

	// DeleteConditionalFormatRule: A reply from deleting a conditional
	// format rule.
	DeleteConditionalFormatRule *DeleteConditionalFormatRuleResponse `json:"deleteConditionalFormatRule,omitempty"`

	// DeleteDeveloperMetadata: A reply from deleting a developer metadata
	// entry.
	DeleteDeveloperMetadata *DeleteDeveloperMetadataResponse `json:"deleteDeveloperMetadata,omitempty"`

	// DeleteDimensionGroup: A reply from deleting a dimension group.
	DeleteDimensionGroup *DeleteDimensionGroupResponse `json:"deleteDimensionGroup,omitempty"`

	// DeleteDuplicates: A reply from removing rows containing duplicate
	// values.
	DeleteDuplicates *DeleteDuplicatesResponse `json:"deleteDuplicates,omitempty"`

	// DuplicateFilterView: A reply from duplicating a filter view.
	DuplicateFilterView *DuplicateFilterViewResponse `json:"duplicateFilterView,omitempty"`

	// DuplicateSheet: A reply from duplicating a sheet.
	DuplicateSheet *DuplicateSheetResponse `json:"duplicateSheet,omitempty"`

	// FindReplace: A reply from doing a find/replace.
	FindReplace *FindReplaceResponse `json:"findReplace,omitempty"`

	// RefreshDataSource: A reply from refreshing data source objects.
	RefreshDataSource *RefreshDataSourceResponse `json:"refreshDataSource,omitempty"`

	// TrimWhitespace: A reply from trimming whitespace.
	TrimWhitespace *TrimWhitespaceResponse `json:"trimWhitespace,omitempty"`

	// UpdateConditionalFormatRule: A reply from updating a conditional
	// format rule.
	UpdateConditionalFormatRule *UpdateConditionalFormatRuleResponse `json:"updateConditionalFormatRule,omitempty"`

	// UpdateDataSource: A reply from updating a data source.
	UpdateDataSource *UpdateDataSourceResponse `json:"updateDataSource,omitempty"`

	// UpdateDeveloperMetadata: A reply from updating a developer metadata
	// entry.
	UpdateDeveloperMetadata *UpdateDeveloperMetadataResponse `json:"updateDeveloperMetadata,omitempty"`

	// UpdateEmbeddedObjectPosition: A reply from updating an embedded
	// object's position.
	UpdateEmbeddedObjectPosition *UpdateEmbeddedObjectPositionResponse `json:"updateEmbeddedObjectPosition,omitempty"`

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

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

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

// RowData: Data about each cell in a row.
type RowData struct {
	// Values: The values in the row, one per column.
	Values []*CellData `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 *RowData) MarshalJSON() ([]byte, error) {
	type NoMethod RowData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ScorecardChartSpec: A scorecard chart. Scorecard charts are used to
// highlight key performance indicators, known as KPIs, on the
// spreadsheet. A scorecard chart can represent things like total sales,
// average cost, or a top selling item. You can specify a single data
// value, or aggregate over a range of data. Percentage or absolute
// difference from a baseline value can be highlighted, like changes
// over time.
type ScorecardChartSpec struct {
	// AggregateType: The aggregation type for key and baseline chart data
	// in scorecard chart. This field is optional.
	//
	// Possible values:
	//   "CHART_AGGREGATE_TYPE_UNSPECIFIED" - Default value, do not use.
	//   "AVERAGE" - Average aggregate function.
	//   "COUNT" - Count aggregate function.
	//   "MAX" - Maximum aggregate function.
	//   "MEDIAN" - Median aggregate function.
	//   "MIN" - Minimum aggregate function.
	//   "SUM" - Sum aggregate function.
	AggregateType string `json:"aggregateType,omitempty"`

	// BaselineValueData: The data for scorecard baseline value. This field
	// is optional.
	BaselineValueData *ChartData `json:"baselineValueData,omitempty"`

	// BaselineValueFormat: Formatting options for baseline value. This
	// field is needed only if baseline_value_data is specified.
	BaselineValueFormat *BaselineValueFormat `json:"baselineValueFormat,omitempty"`

	// CustomFormatOptions: Custom formatting options for numeric
	// key/baseline values in scorecard chart. This field is used only when
	// number_format_source is set to CUSTOM. This field is optional.
	CustomFormatOptions *ChartCustomNumberFormatOptions `json:"customFormatOptions,omitempty"`

	// KeyValueData: The data for scorecard key value.
	KeyValueData *ChartData `json:"keyValueData,omitempty"`

	// KeyValueFormat: Formatting options for key value.
	KeyValueFormat *KeyValueFormat `json:"keyValueFormat,omitempty"`

	// NumberFormatSource: The number format source used in the scorecard
	// chart. This field is optional.
	//
	// Possible values:
	//   "CHART_NUMBER_FORMAT_SOURCE_UNDEFINED" - Default value, do not use.
	//   "FROM_DATA" - Inherit number formatting from data.
	//   "CUSTOM" - Apply custom formatting as specified by
	// ChartCustomNumberFormatOptions.
	NumberFormatSource string `json:"numberFormatSource,omitempty"`

	// ScaleFactor: Value to scale scorecard key and baseline value. For
	// example, a factor of 10 can be used to divide all values in the chart
	// by 10. This field is optional.
	ScaleFactor float64 `json:"scaleFactor,omitempty"`

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

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

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

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

// SearchDeveloperMetadataRequest: A request to retrieve all developer
// metadata matching the set of specified criteria.
type SearchDeveloperMetadataRequest struct {
	// DataFilters: The data filters describing the criteria used to
	// determine which DeveloperMetadata entries to return.
	// DeveloperMetadata matching any of the specified filters are included
	// in the response.
	DataFilters []*DataFilter `json:"dataFilters,omitempty"`

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

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

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

// SearchDeveloperMetadataResponse: A reply to a developer metadata
// search request.
type SearchDeveloperMetadataResponse struct {
	// MatchedDeveloperMetadata: The metadata matching the criteria of the
	// search request.
	MatchedDeveloperMetadata []*MatchedDeveloperMetadata `json:"matchedDeveloperMetadata,omitempty"`

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

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

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

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

// SetBasicFilterRequest: Sets the basic filter associated with a sheet.
type SetBasicFilterRequest struct {
	// Filter: The filter to set.
	Filter *BasicFilter `json:"filter,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 *SetBasicFilterRequest) MarshalJSON() ([]byte, error) {
	type NoMethod SetBasicFilterRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SetDataValidationRequest: Sets a data validation rule to every cell
// in the range. To clear validation in a range, call this with no rule
// specified.
type SetDataValidationRequest struct {
	// Range: The range the data validation rule should apply to.
	Range *GridRange `json:"range,omitempty"`

	// Rule: The data validation rule to set on each cell in the range, or
	// empty to clear the data validation in the range.
	Rule *DataValidationRule `json:"rule,omitempty"`

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

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

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

// Sheet: A sheet in a spreadsheet.
type Sheet struct {
	// BandedRanges: The banded (alternating colors) ranges on this sheet.
	BandedRanges []*BandedRange `json:"bandedRanges,omitempty"`

	// BasicFilter: The filter on this sheet, if any.
	BasicFilter *BasicFilter `json:"basicFilter,omitempty"`

	// Charts: The specifications of every chart on this sheet.
	Charts []*EmbeddedChart `json:"charts,omitempty"`

	// ColumnGroups: All column groups on this sheet, ordered by increasing
	// range start index, then by group depth.
	ColumnGroups []*DimensionGroup `json:"columnGroups,omitempty"`

	// ConditionalFormats: The conditional format rules in this sheet.
	ConditionalFormats []*ConditionalFormatRule `json:"conditionalFormats,omitempty"`

	// Data: Data in the grid, if this is a grid sheet. The number of
	// GridData objects returned is dependent on the number of ranges
	// requested on this sheet. For example, if this is representing
	// `Sheet1`, and the spreadsheet was requested with ranges
	// `Sheet1!A1:C10` and `Sheet1!D15:E20`, then the first GridData will
	// have a startRow/startColumn of `0`, while the second one will have
	// `startRow 14` (zero-based row 15), and `startColumn 3` (zero-based
	// column D).
	Data []*GridData `json:"data,omitempty"`

	// DeveloperMetadata: The developer metadata associated with a sheet.
	DeveloperMetadata []*DeveloperMetadata `json:"developerMetadata,omitempty"`

	// FilterViews: The filter views in this sheet.
	FilterViews []*FilterView `json:"filterViews,omitempty"`

	// Merges: The ranges that are merged together.
	Merges []*GridRange `json:"merges,omitempty"`

	// Properties: The properties of the sheet.
	Properties *SheetProperties `json:"properties,omitempty"`

	// ProtectedRanges: The protected ranges in this sheet.
	ProtectedRanges []*ProtectedRange `json:"protectedRanges,omitempty"`

	// RowGroups: All row groups on this sheet, ordered by increasing range
	// start index, then by group depth.
	RowGroups []*DimensionGroup `json:"rowGroups,omitempty"`

	// Slicers: The slicers on this sheet.
	Slicers []*Slicer `json:"slicers,omitempty"`

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

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

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

// SheetProperties: Properties of a sheet.
type SheetProperties struct {
	// DataSourceSheetProperties: Output only. If present, the field
	// contains SheetType.DATA_SOURCE sheet specific properties.
	DataSourceSheetProperties *DataSourceSheetProperties `json:"dataSourceSheetProperties,omitempty"`

	// GridProperties: Additional properties of the sheet if this sheet is a
	// grid. (If the sheet is an object sheet, containing a chart or image,
	// then this field will be absent.) When writing it is an error to set
	// any grid properties on non-grid sheets.
	GridProperties *GridProperties `json:"gridProperties,omitempty"`

	// Hidden: True if the sheet is hidden in the UI, false if it's visible.
	Hidden bool `json:"hidden,omitempty"`

	// Index: The index of the sheet within the spreadsheet. When adding or
	// updating sheet properties, if this field is excluded then the sheet
	// is added or moved to the end of the sheet list. When updating sheet
	// indices or inserting sheets, movement is considered in "before the
	// move" indexes. For example, if there were 3 sheets (S1, S2, S3) in
	// order to move S1 ahead of S2 the index would have to be set to 2. A
	// sheet index update request is ignored if the requested index is
	// identical to the sheets current index or if the requested new index
	// is equal to the current sheet index + 1.
	Index int64 `json:"index,omitempty"`

	// RightToLeft: True if the sheet is an RTL sheet instead of an LTR
	// sheet.
	RightToLeft bool `json:"rightToLeft,omitempty"`

	// SheetId: The ID of the sheet. Must be non-negative. This field cannot
	// be changed once set.
	SheetId int64 `json:"sheetId,omitempty"`

	// SheetType: The type of sheet. Defaults to GRID. This field cannot be
	// changed once set.
	//
	// Possible values:
	//   "SHEET_TYPE_UNSPECIFIED" - Default value, do not use.
	//   "GRID" - The sheet is a grid.
	//   "OBJECT" - The sheet has no grid and instead has an object like a
	// chart or image.
	//   "DATA_SOURCE" - The sheet connects with an external DataSource and
	// shows the preview of data.
	SheetType string `json:"sheetType,omitempty"`

	// TabColor: The color of the tab in the UI.
	TabColor *Color `json:"tabColor,omitempty"`

	// TabColorStyle: The color of the tab in the UI. If tab_color is also
	// set, this field takes precedence.
	TabColorStyle *ColorStyle `json:"tabColorStyle,omitempty"`

	// Title: The name of the sheet.
	Title string `json:"title,omitempty"`

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

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

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

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

// Slicer: A slicer in a sheet.
type Slicer struct {
	// Position: The position of the slicer. Note that slicer can be
	// positioned only on existing sheet. Also, width and height of slicer
	// can be automatically adjusted to keep it within permitted limits.
	Position *EmbeddedObjectPosition `json:"position,omitempty"`

	// SlicerId: The ID of the slicer.
	SlicerId int64 `json:"slicerId,omitempty"`

	// Spec: The specification of the slicer.
	Spec *SlicerSpec `json:"spec,omitempty"`

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

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

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

// SlicerSpec: The specifications of a slicer.
type SlicerSpec struct {
	// ApplyToPivotTables: True if the filter should apply to pivot tables.
	// If not set, default to `True`.
	ApplyToPivotTables bool `json:"applyToPivotTables,omitempty"`

	// BackgroundColor: The background color of the slicer.
	BackgroundColor *Color `json:"backgroundColor,omitempty"`

	// BackgroundColorStyle: The background color of the slicer. If
	// background_color is also set, this field takes precedence.
	BackgroundColorStyle *ColorStyle `json:"backgroundColorStyle,omitempty"`

	// ColumnIndex: The column index in the data table on which the filter
	// is applied to.
	ColumnIndex int64 `json:"columnIndex,omitempty"`

	// DataRange: The data range of the slicer.
	DataRange *GridRange `json:"dataRange,omitempty"`

	// FilterCriteria: The filtering criteria of the slicer.
	FilterCriteria *FilterCriteria `json:"filterCriteria,omitempty"`

	// HorizontalAlignment: The horizontal alignment of title in the slicer.
	// If unspecified, defaults to `LEFT`
	//
	// Possible values:
	//   "HORIZONTAL_ALIGN_UNSPECIFIED" - The horizontal alignment is not
	// specified. Do not use this.
	//   "LEFT" - The text is explicitly aligned to the left of the cell.
	//   "CENTER" - The text is explicitly aligned to the center of the
	// cell.
	//   "RIGHT" - The text is explicitly aligned to the right of the cell.
	HorizontalAlignment string `json:"horizontalAlignment,omitempty"`

	// TextFormat: The text format of title in the slicer.
	TextFormat *TextFormat `json:"textFormat,omitempty"`

	// Title: The title of the slicer.
	Title string `json:"title,omitempty"`

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

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

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

// SortRangeRequest: Sorts data in rows based on a sort order per
// column.
type SortRangeRequest struct {
	// Range: The range to sort.
	Range *GridRange `json:"range,omitempty"`

	// SortSpecs: The sort order per column. Later specifications are used
	// when values are equal in the earlier specifications.
	SortSpecs []*SortSpec `json:"sortSpecs,omitempty"`

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

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

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

// SortSpec: A sort order associated with a specific column or row.
type SortSpec struct {
	// BackgroundColor: The background fill color to sort by; cells with
	// this fill color are sorted to the top. Mutually exclusive with
	// foreground_color.
	BackgroundColor *Color `json:"backgroundColor,omitempty"`

	// BackgroundColorStyle: The background fill color to sort by; cells
	// with this fill color are sorted to the top. Mutually exclusive with
	// foreground_color, and must be an RGB-type color. If background_color
	// is also set, this field takes precedence.
	BackgroundColorStyle *ColorStyle `json:"backgroundColorStyle,omitempty"`

	// DataSourceColumnReference: Reference to a data source column.
	DataSourceColumnReference *DataSourceColumnReference `json:"dataSourceColumnReference,omitempty"`

	// DimensionIndex: The dimension the sort should be applied to.
	DimensionIndex int64 `json:"dimensionIndex,omitempty"`

	// ForegroundColor: The foreground color to sort by; cells with this
	// foreground color are sorted to the top. Mutually exclusive with
	// background_color.
	ForegroundColor *Color `json:"foregroundColor,omitempty"`

	// ForegroundColorStyle: The foreground color to sort by; cells with
	// this foreground color are sorted to the top. Mutually exclusive with
	// background_color, and must be an RGB-type color. If foreground_color
	// is also set, this field takes precedence.
	ForegroundColorStyle *ColorStyle `json:"foregroundColorStyle,omitempty"`

	// SortOrder: The order data should be sorted.
	//
	// Possible values:
	//   "SORT_ORDER_UNSPECIFIED" - Default value, do not use this.
	//   "ASCENDING" - Sort ascending.
	//   "DESCENDING" - Sort descending.
	SortOrder string `json:"sortOrder,omitempty"`

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

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

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

// SourceAndDestination: A combination of a source range and how to
// extend that source.
type SourceAndDestination struct {
	// Dimension: The dimension that data should be filled into.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
	//   "ROWS" - Operates on the rows of a sheet.
	//   "COLUMNS" - Operates on the columns of a sheet.
	Dimension string `json:"dimension,omitempty"`

	// FillLength: The number of rows or columns that data should be filled
	// into. Positive numbers expand beyond the last row or last column of
	// the source. Negative numbers expand before the first row or first
	// column of the source.
	FillLength int64 `json:"fillLength,omitempty"`

	// Source: The location of the data to use as the source of the
	// autofill.
	Source *GridRange `json:"source,omitempty"`

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

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

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

// Spreadsheet: Resource that represents a spreadsheet.
type Spreadsheet struct {
	// DataSourceSchedules: Output only. A list of data source refresh
	// schedules.
	DataSourceSchedules []*DataSourceRefreshSchedule `json:"dataSourceSchedules,omitempty"`

	// DataSources: A list of external data sources connected with the
	// spreadsheet.
	DataSources []*DataSource `json:"dataSources,omitempty"`

	// DeveloperMetadata: The developer metadata associated with a
	// spreadsheet.
	DeveloperMetadata []*DeveloperMetadata `json:"developerMetadata,omitempty"`

	// NamedRanges: The named ranges defined in a spreadsheet.
	NamedRanges []*NamedRange `json:"namedRanges,omitempty"`

	// Properties: Overall properties of a spreadsheet.
	Properties *SpreadsheetProperties `json:"properties,omitempty"`

	// Sheets: The sheets that are part of a spreadsheet.
	Sheets []*Sheet `json:"sheets,omitempty"`

	// SpreadsheetId: The ID of the spreadsheet. This field is read-only.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// SpreadsheetUrl: The url of the spreadsheet. This field is read-only.
	SpreadsheetUrl string `json:"spreadsheetUrl,omitempty"`

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

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

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

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

// SpreadsheetProperties: Properties of a spreadsheet.
type SpreadsheetProperties struct {
	// AutoRecalc: The amount of time to wait before volatile functions are
	// recalculated.
	//
	// Possible values:
	//   "RECALCULATION_INTERVAL_UNSPECIFIED" - Default value. This value
	// must not be used.
	//   "ON_CHANGE" - Volatile functions are updated on every change.
	//   "MINUTE" - Volatile functions are updated on every change and every
	// minute.
	//   "HOUR" - Volatile functions are updated on every change and hourly.
	AutoRecalc string `json:"autoRecalc,omitempty"`

	// DefaultFormat: The default format of all cells in the spreadsheet.
	// CellData.effectiveFormat will not be set if the cell's format is
	// equal to this default format. This field is read-only.
	DefaultFormat *CellFormat `json:"defaultFormat,omitempty"`

	// IterativeCalculationSettings: Determines whether and how circular
	// references are resolved with iterative calculation. Absence of this
	// field means that circular references result in calculation errors.
	IterativeCalculationSettings *IterativeCalculationSettings `json:"iterativeCalculationSettings,omitempty"`

	// Locale: The locale of the spreadsheet in one of the following
	// formats: * an ISO 639-1 language code such as `en` * an ISO 639-2
	// language code such as `fil`, if no 639-1 code exists * a combination
	// of the ISO language code and country code, such as `en_US` Note: when
	// updating this field, not all locales/languages are supported.
	Locale string `json:"locale,omitempty"`

	// SpreadsheetTheme: Theme applied to the spreadsheet.
	SpreadsheetTheme *SpreadsheetTheme `json:"spreadsheetTheme,omitempty"`

	// TimeZone: The time zone of the spreadsheet, in CLDR format such as
	// `America/New_York`. If the time zone isn't recognized, this may be a
	// custom time zone such as `GMT-07:00`.
	TimeZone string `json:"timeZone,omitempty"`

	// Title: The title of the spreadsheet.
	Title string `json:"title,omitempty"`

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

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

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

// SpreadsheetTheme: Represents spreadsheet theme
type SpreadsheetTheme struct {
	// PrimaryFontFamily: Name of the primary font family.
	PrimaryFontFamily string `json:"primaryFontFamily,omitempty"`

	// ThemeColors: The spreadsheet theme color pairs. To update you must
	// provide all theme color pairs.
	ThemeColors []*ThemeColorPair `json:"themeColors,omitempty"`

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

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

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

// TextFormat: The format of a run of text in a cell. Absent values
// indicate that the field isn't specified.
type TextFormat struct {
	// Bold: True if the text is bold.
	Bold bool `json:"bold,omitempty"`

	// FontFamily: The font family.
	FontFamily string `json:"fontFamily,omitempty"`

	// FontSize: The size of the font.
	FontSize int64 `json:"fontSize,omitempty"`

	// ForegroundColor: The foreground color of the text.
	ForegroundColor *Color `json:"foregroundColor,omitempty"`

	// ForegroundColorStyle: The foreground color of the text. If
	// foreground_color is also set, this field takes precedence.
	ForegroundColorStyle *ColorStyle `json:"foregroundColorStyle,omitempty"`

	// Italic: True if the text is italicized.
	Italic bool `json:"italic,omitempty"`

	// Strikethrough: True if the text has a strikethrough.
	Strikethrough bool `json:"strikethrough,omitempty"`

	// Underline: True if the text is underlined.
	Underline bool `json:"underline,omitempty"`

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

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

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

// TextFormatRun: A run of a text format. The format of this run
// continues until the start index of the next run. When updating, all
// fields must be set.
type TextFormatRun struct {
	// Format: The format of this run. Absent values inherit the cell's
	// format.
	Format *TextFormat `json:"format,omitempty"`

	// StartIndex: The character index where this run starts.
	StartIndex int64 `json:"startIndex,omitempty"`

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

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

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

// TextPosition: Position settings for text.
type TextPosition struct {
	// HorizontalAlignment: Horizontal alignment setting for the piece of
	// text.
	//
	// Possible values:
	//   "HORIZONTAL_ALIGN_UNSPECIFIED" - The horizontal alignment is not
	// specified. Do not use this.
	//   "LEFT" - The text is explicitly aligned to the left of the cell.
	//   "CENTER" - The text is explicitly aligned to the center of the
	// cell.
	//   "RIGHT" - The text is explicitly aligned to the right of the cell.
	HorizontalAlignment string `json:"horizontalAlignment,omitempty"`

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

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

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

// TextRotation: The rotation applied to text in a cell.
type TextRotation struct {
	// Angle: The angle between the standard orientation and the desired
	// orientation. Measured in degrees. Valid values are between -90 and
	// 90. Positive angles are angled upwards, negative are angled
	// downwards. Note: For LTR text direction positive angles are in the
	// counterclockwise direction, whereas for RTL they are in the clockwise
	// direction
	Angle int64 `json:"angle,omitempty"`

	// Vertical: If true, text reads top to bottom, but the orientation of
	// individual characters is unchanged. For example: | V | | e | | r | |
	// t | | i | | c | | a | | l |
	Vertical bool `json:"vertical,omitempty"`

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

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

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

// TextToColumnsRequest: Splits a column of text into multiple columns,
// based on a delimiter in each cell.
type TextToColumnsRequest struct {
	// Delimiter: The delimiter to use. Used only if delimiterType is
	// CUSTOM.
	Delimiter string `json:"delimiter,omitempty"`

	// DelimiterType: The delimiter type to use.
	//
	// Possible values:
	//   "DELIMITER_TYPE_UNSPECIFIED" - Default value. This value must not
	// be used.
	//   "COMMA" - ","
	//   "SEMICOLON" - ";"
	//   "PERIOD" - "."
	//   "SPACE" - " "
	//   "CUSTOM" - A custom value as defined in delimiter.
	//   "AUTODETECT" - Automatically detect columns.
	DelimiterType string `json:"delimiterType,omitempty"`

	// Source: The source data range. This must span exactly one column.
	Source *GridRange `json:"source,omitempty"`

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

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

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

// ThemeColorPair: A pair mapping a spreadsheet theme color type to the
// concrete color it represents.
type ThemeColorPair struct {
	// Color: The concrete color corresponding to the theme color type.
	Color *ColorStyle `json:"color,omitempty"`

	// ColorType: The type of the spreadsheet theme color.
	//
	// Possible values:
	//   "THEME_COLOR_TYPE_UNSPECIFIED" - Unspecified theme color
	//   "TEXT" - Represents the primary text color
	//   "BACKGROUND" - Represents the primary background color
	//   "ACCENT1" - Represents the first accent color
	//   "ACCENT2" - Represents the second accent color
	//   "ACCENT3" - Represents the third accent color
	//   "ACCENT4" - Represents the fourth accent color
	//   "ACCENT5" - Represents the fifth accent color
	//   "ACCENT6" - Represents the sixth accent color
	//   "LINK" - Represents the color to use for hyperlinks
	ColorType string `json:"colorType,omitempty"`

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

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

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

// TimeOfDay: Represents a time of day. The date and time zone are
// either not significant or are specified elsewhere. An API may choose
// to allow leap seconds. Related types are google.type.Date and
// `google.protobuf.Timestamp`.
type TimeOfDay struct {
	// Hours: Hours of day in 24 hour format. Should be from 0 to 23. An API
	// may choose to allow the value "24:00:00" for scenarios like business
	// closing time.
	Hours int64 `json:"hours,omitempty"`

	// Minutes: Minutes of hour of day. Must be from 0 to 59.
	Minutes int64 `json:"minutes,omitempty"`

	// Nanos: Fractions of seconds in nanoseconds. Must be from 0 to
	// 999,999,999.
	Nanos int64 `json:"nanos,omitempty"`

	// Seconds: Seconds of minutes of the time. Must normally be from 0 to
	// 59. An API may allow the value 60 if it allows leap-seconds.
	Seconds int64 `json:"seconds,omitempty"`

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

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

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

// TreemapChartColorScale: A color scale for a treemap chart.
type TreemapChartColorScale struct {
	// MaxValueColor: The background color for cells with a color value
	// greater than or equal to maxValue. Defaults to #109618 if not
	// specified.
	MaxValueColor *Color `json:"maxValueColor,omitempty"`

	// MaxValueColorStyle: The background color for cells with a color value
	// greater than or equal to maxValue. Defaults to #109618 if not
	// specified. If max_value_color is also set, this field takes
	// precedence.
	MaxValueColorStyle *ColorStyle `json:"maxValueColorStyle,omitempty"`

	// MidValueColor: The background color for cells with a color value at
	// the midpoint between minValue and maxValue. Defaults to #efe6dc if
	// not specified.
	MidValueColor *Color `json:"midValueColor,omitempty"`

	// MidValueColorStyle: The background color for cells with a color value
	// at the midpoint between minValue and maxValue. Defaults to #efe6dc if
	// not specified. If mid_value_color is also set, this field takes
	// precedence.
	MidValueColorStyle *ColorStyle `json:"midValueColorStyle,omitempty"`

	// MinValueColor: The background color for cells with a color value less
	// than or equal to minValue. Defaults to #dc3912 if not specified.
	MinValueColor *Color `json:"minValueColor,omitempty"`

	// MinValueColorStyle: The background color for cells with a color value
	// less than or equal to minValue. Defaults to #dc3912 if not specified.
	// If min_value_color is also set, this field takes precedence.
	MinValueColorStyle *ColorStyle `json:"minValueColorStyle,omitempty"`

	// NoDataColor: The background color for cells that have no color data
	// associated with them. Defaults to #000000 if not specified.
	NoDataColor *Color `json:"noDataColor,omitempty"`

	// NoDataColorStyle: The background color for cells that have no color
	// data associated with them. Defaults to #000000 if not specified. If
	// no_data_color is also set, this field takes precedence.
	NoDataColorStyle *ColorStyle `json:"noDataColorStyle,omitempty"`

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

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

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

// TreemapChartSpec: A Treemap chart.
type TreemapChartSpec struct {
	// ColorData: The data that determines the background color of each
	// treemap data cell. This field is optional. If not specified,
	// size_data is used to determine background colors. If specified, the
	// data is expected to be numeric. color_scale will determine how the
	// values in this data map to data cell background colors.
	ColorData *ChartData `json:"colorData,omitempty"`

	// ColorScale: The color scale for data cells in the treemap chart. Data
	// cells are assigned colors based on their color values. These color
	// values come from color_data, or from size_data if color_data is not
	// specified. Cells with color values less than or equal to min_value
	// will have minValueColor as their background color. Cells with color
	// values greater than or equal to max_value will have maxValueColor as
	// their background color. Cells with color values between min_value and
	// max_value will have background colors on a gradient between
	// minValueColor and maxValueColor, the midpoint of the gradient being
	// midValueColor. Cells with missing or non-numeric color values will
	// have noDataColor as their background color.
	ColorScale *TreemapChartColorScale `json:"colorScale,omitempty"`

	// HeaderColor: The background color for header cells.
	HeaderColor *Color `json:"headerColor,omitempty"`

	// HeaderColorStyle: The background color for header cells. If
	// header_color is also set, this field takes precedence.
	HeaderColorStyle *ColorStyle `json:"headerColorStyle,omitempty"`

	// HideTooltips: True to hide tooltips.
	HideTooltips bool `json:"hideTooltips,omitempty"`

	// HintedLevels: The number of additional data levels beyond the labeled
	// levels to be shown on the treemap chart. These levels are not
	// interactive and are shown without their labels. Defaults to 0 if not
	// specified.
	HintedLevels int64 `json:"hintedLevels,omitempty"`

	// Labels: The data that contains the treemap cell labels.
	Labels *ChartData `json:"labels,omitempty"`

	// Levels: The number of data levels to show on the treemap chart. These
	// levels are interactive and are shown with their labels. Defaults to 2
	// if not specified.
	Levels int64 `json:"levels,omitempty"`

	// MaxValue: The maximum possible data value. Cells with values greater
	// than this will have the same color as cells with this value. If not
	// specified, defaults to the actual maximum value from color_data, or
	// the maximum value from size_data if color_data is not specified.
	MaxValue float64 `json:"maxValue,omitempty"`

	// MinValue: The minimum possible data value. Cells with values less
	// than this will have the same color as cells with this value. If not
	// specified, defaults to the actual minimum value from color_data, or
	// the minimum value from size_data if color_data is not specified.
	MinValue float64 `json:"minValue,omitempty"`

	// ParentLabels: The data the contains the treemap cells' parent labels.
	ParentLabels *ChartData `json:"parentLabels,omitempty"`

	// SizeData: The data that determines the size of each treemap data
	// cell. This data is expected to be numeric. The cells corresponding to
	// non-numeric or missing data will not be rendered. If color_data is
	// not specified, this data is used to determine data cell background
	// colors as well.
	SizeData *ChartData `json:"sizeData,omitempty"`

	// TextFormat: The text format for all labels on the chart.
	TextFormat *TextFormat `json:"textFormat,omitempty"`

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

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

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

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

// TrimWhitespaceRequest: Trims the whitespace (such as spaces, tabs, or
// new lines) in every cell in the specified range. This request removes
// all whitespace from the start and end of each cell's text, and
// reduces any subsequence of remaining whitespace characters to a
// single space. If the resulting trimmed text starts with a '+' or '='
// character, the text remains as a string value and isn't interpreted
// as a formula.
type TrimWhitespaceRequest struct {
	// Range: The range whose cells to trim.
	Range *GridRange `json:"range,omitempty"`

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

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

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

// TrimWhitespaceResponse: The result of trimming whitespace in cells.
type TrimWhitespaceResponse struct {
	// CellsChangedCount: The number of cells that were trimmed of
	// whitespace.
	CellsChangedCount int64 `json:"cellsChangedCount,omitempty"`

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

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

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

// UnmergeCellsRequest: Unmerges cells in the given range.
type UnmergeCellsRequest struct {
	// Range: The range within which all cells should be unmerged. If the
	// range spans multiple merges, all will be unmerged. The range must not
	// partially span any merge.
	Range *GridRange `json:"range,omitempty"`

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

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

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

// UpdateBandingRequest: Updates properties of the supplied banded
// range.
type UpdateBandingRequest struct {
	// BandedRange: The banded range to update with the new properties.
	BandedRange *BandedRange `json:"bandedRange,omitempty"`

	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `bandedRange` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

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

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

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

// UpdateBordersRequest: Updates the borders of a range. If a field is
// not set in the request, that means the border remains as-is. For
// example, with two subsequent UpdateBordersRequest: 1. range: A1:A5 `{
// top: RED, bottom: WHITE }` 2. range: A1:A5 `{ left: BLUE }` That
// would result in A1:A5 having a borders of `{ top: RED, bottom: WHITE,
// left: BLUE }`. If you want to clear a border, explicitly set the
// style to NONE.
type UpdateBordersRequest struct {
	// Bottom: The border to put at the bottom of the range.
	Bottom *Border `json:"bottom,omitempty"`

	// InnerHorizontal: The horizontal border to put within the range.
	InnerHorizontal *Border `json:"innerHorizontal,omitempty"`

	// InnerVertical: The vertical border to put within the range.
	InnerVertical *Border `json:"innerVertical,omitempty"`

	// Left: The border to put at the left of the range.
	Left *Border `json:"left,omitempty"`

	// Range: The range whose borders should be updated.
	Range *GridRange `json:"range,omitempty"`

	// Right: The border to put at the right of the range.
	Right *Border `json:"right,omitempty"`

	// Top: The border to put at the top of the range.
	Top *Border `json:"top,omitempty"`

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

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

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

// UpdateCellsRequest: Updates all cells in a range with new data.
type UpdateCellsRequest struct {
	// Fields: The fields of CellData that should be updated. At least one
	// field must be specified. The root is the CellData; 'row.values.'
	// should not be specified. A single "*" can be used as short-hand for
	// listing every field.
	Fields string `json:"fields,omitempty"`

	// Range: The range to write data to. If the data in rows does not cover
	// the entire requested range, the fields matching those set in fields
	// will be cleared.
	Range *GridRange `json:"range,omitempty"`

	// Rows: The data to write.
	Rows []*RowData `json:"rows,omitempty"`

	// Start: The coordinate to start writing data at. Any number of rows
	// and columns (including a different number of columns per row) may be
	// written.
	Start *GridCoordinate `json:"start,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 *UpdateCellsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateCellsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateChartSpecRequest: Updates a chart's specifications. (This does
// not move or resize a chart. To move or resize a chart, use
// UpdateEmbeddedObjectPositionRequest.)
type UpdateChartSpecRequest struct {
	// ChartId: The ID of the chart to update.
	ChartId int64 `json:"chartId,omitempty"`

	// Spec: The specification to apply to the chart.
	Spec *ChartSpec `json:"spec,omitempty"`

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

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

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

// UpdateConditionalFormatRuleRequest: Updates a conditional format rule
// at the given index, or moves a conditional format rule to another
// index.
type UpdateConditionalFormatRuleRequest struct {
	// Index: The zero-based index of the rule that should be replaced or
	// moved.
	Index int64 `json:"index,omitempty"`

	// NewIndex: The zero-based new index the rule should end up at.
	NewIndex int64 `json:"newIndex,omitempty"`

	// Rule: The rule that should replace the rule at the given index.
	Rule *ConditionalFormatRule `json:"rule,omitempty"`

	// SheetId: The sheet of the rule to move. Required if new_index is set,
	// unused otherwise.
	SheetId int64 `json:"sheetId,omitempty"`

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

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

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

// UpdateConditionalFormatRuleResponse: The result of updating a
// conditional format rule.
type UpdateConditionalFormatRuleResponse struct {
	// NewIndex: The index of the new rule.
	NewIndex int64 `json:"newIndex,omitempty"`

	// NewRule: The new rule that replaced the old rule (if replacing), or
	// the rule that was moved (if moved)
	NewRule *ConditionalFormatRule `json:"newRule,omitempty"`

	// OldIndex: The old index of the rule. Not set if a rule was replaced
	// (because it is the same as new_index).
	OldIndex int64 `json:"oldIndex,omitempty"`

	// OldRule: The old (deleted) rule. Not set if a rule was moved (because
	// it is the same as new_rule).
	OldRule *ConditionalFormatRule `json:"oldRule,omitempty"`

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

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

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

// UpdateDataSourceRequest: Updates a data source. After the data source
// is updated successfully, an execution is triggered to refresh the
// associated DataSource sheet to read data from the updated data
// source. The request requires an additional bigquery.readonly OAuth
// scope.
type UpdateDataSourceRequest struct {
	// DataSource: The data source to update.
	DataSource *DataSource `json:"dataSource,omitempty"`

	// Fields: The fields that should be updated. At least one field must be
	// specified. The root 'dataSource' is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

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

	// NullFields is a list of field names (e.g. "DataSource") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field 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)
}

// UpdateDataSourceResponse: The response from updating data source.
type UpdateDataSourceResponse struct {
	// DataExecutionStatus: The data execution status.
	DataExecutionStatus *DataExecutionStatus `json:"dataExecutionStatus,omitempty"`

	// DataSource: The updated data source.
	DataSource *DataSource `json:"dataSource,omitempty"`

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

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

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

// UpdateDeveloperMetadataRequest: A request to update properties of
// developer metadata. Updates the properties of the developer metadata
// selected by the filters to the values provided in the
// DeveloperMetadata resource. Callers must specify the properties they
// wish to update in the fields parameter, as well as specify at least
// one DataFilter matching the metadata they wish to update.
type UpdateDeveloperMetadataRequest struct {
	// DataFilters: The filters matching the developer metadata entries to
	// update.
	DataFilters []*DataFilter `json:"dataFilters,omitempty"`

	// DeveloperMetadata: The value that all metadata matched by the data
	// filters will be updated to.
	DeveloperMetadata *DeveloperMetadata `json:"developerMetadata,omitempty"`

	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `developerMetadata` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

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

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

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

// UpdateDeveloperMetadataResponse: The response from updating developer
// metadata.
type UpdateDeveloperMetadataResponse struct {
	// DeveloperMetadata: The updated developer metadata.
	DeveloperMetadata []*DeveloperMetadata `json:"developerMetadata,omitempty"`

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

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

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

// UpdateDimensionGroupRequest: Updates the state of the specified
// group.
type UpdateDimensionGroupRequest struct {
	// DimensionGroup: The group whose state should be updated. The range
	// and depth of the group should specify a valid group on the sheet, and
	// all other fields updated.
	DimensionGroup *DimensionGroup `json:"dimensionGroup,omitempty"`

	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `dimensionGroup` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

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

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

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

// UpdateDimensionPropertiesRequest: Updates properties of dimensions
// within the specified range.
type UpdateDimensionPropertiesRequest struct {
	// DataSourceSheetRange: The columns on a data source sheet to update.
	DataSourceSheetRange *DataSourceSheetDimensionRange `json:"dataSourceSheetRange,omitempty"`

	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `properties` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

	// Properties: Properties to update.
	Properties *DimensionProperties `json:"properties,omitempty"`

	// Range: The rows or columns to update.
	Range *DimensionRange `json:"range,omitempty"`

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

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

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

// UpdateEmbeddedObjectPositionRequest: Update an embedded object's
// position (such as a moving or resizing a chart or image).
type UpdateEmbeddedObjectPositionRequest struct {
	// Fields: The fields of OverlayPosition that should be updated when
	// setting a new position. Used only if newPosition.overlayPosition is
	// set, in which case at least one field must be specified. The root
	// `newPosition.overlayPosition` is implied and should not be specified.
	// A single "*" can be used as short-hand for listing every field.
	Fields string `json:"fields,omitempty"`

	// NewPosition: An explicit position to move the embedded object to. If
	// newPosition.sheetId is set, a new sheet with that ID will be created.
	// If newPosition.newSheet is set to true, a new sheet will be created
	// with an ID that will be chosen for you.
	NewPosition *EmbeddedObjectPosition `json:"newPosition,omitempty"`

	// ObjectId: The ID of the object to moved.
	ObjectId int64 `json:"objectId,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 *UpdateEmbeddedObjectPositionRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateEmbeddedObjectPositionRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateEmbeddedObjectPositionResponse: The result of updating an
// embedded object's position.
type UpdateEmbeddedObjectPositionResponse struct {
	// Position: The new position of the embedded object.
	Position *EmbeddedObjectPosition `json:"position,omitempty"`

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

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

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

// UpdateFilterViewRequest: Updates properties of the filter view.
type UpdateFilterViewRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `filter` is implied and should not be specified.
	// A single "*" can be used as short-hand for listing every field.
	Fields string `json:"fields,omitempty"`

	// Filter: The new properties of the filter view.
	Filter *FilterView `json:"filter,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 *UpdateFilterViewRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateFilterViewRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateNamedRangeRequest: Updates properties of the named range with
// the specified namedRangeId.
type UpdateNamedRangeRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `namedRange` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

	// NamedRange: The named range to update with the new properties.
	NamedRange *NamedRange `json:"namedRange,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 *UpdateNamedRangeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateNamedRangeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateProtectedRangeRequest: Updates an existing protected range with
// the specified protectedRangeId.
type UpdateProtectedRangeRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `protectedRange` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

	// ProtectedRange: The protected range to update with the new
	// properties.
	ProtectedRange *ProtectedRange `json:"protectedRange,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 *UpdateProtectedRangeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateProtectedRangeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateSheetPropertiesRequest: Updates properties of the sheet with
// the specified sheetId.
type UpdateSheetPropertiesRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `properties` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

	// Properties: The properties to update.
	Properties *SheetProperties `json:"properties,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 *UpdateSheetPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateSheetPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateSlicerSpecRequest: Updates a slicer's specifications. (This
// does not move or resize a slicer. To move or resize a slicer use
// UpdateEmbeddedObjectPositionRequest.
type UpdateSlicerSpecRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `SlicerSpec` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

	// SlicerId: The id of the slicer to update.
	SlicerId int64 `json:"slicerId,omitempty"`

	// Spec: The specification to apply to the slicer.
	Spec *SlicerSpec `json:"spec,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 *UpdateSlicerSpecRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateSlicerSpecRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateSpreadsheetPropertiesRequest: Updates properties of a
// spreadsheet.
type UpdateSpreadsheetPropertiesRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root 'properties' is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field.
	Fields string `json:"fields,omitempty"`

	// Properties: The properties to update.
	Properties *SpreadsheetProperties `json:"properties,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 *UpdateSpreadsheetPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateSpreadsheetPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateValuesByDataFilterResponse: The response when updating a range
// of values by a data filter in a spreadsheet.
type UpdateValuesByDataFilterResponse struct {
	// DataFilter: The data filter that selected the range that was updated.
	DataFilter *DataFilter `json:"dataFilter,omitempty"`

	// UpdatedCells: The number of cells updated.
	UpdatedCells int64 `json:"updatedCells,omitempty"`

	// UpdatedColumns: The number of columns where at least one cell in the
	// column was updated.
	UpdatedColumns int64 `json:"updatedColumns,omitempty"`

	// UpdatedData: The values of the cells in the range matched by the
	// dataFilter after all updates were applied. This is only included if
	// the request's `includeValuesInResponse` field was `true`.
	UpdatedData *ValueRange `json:"updatedData,omitempty"`

	// UpdatedRange: The range (in A1 notation) that updates were applied
	// to.
	UpdatedRange string `json:"updatedRange,omitempty"`

	// UpdatedRows: The number of rows where at least one cell in the row
	// was updated.
	UpdatedRows int64 `json:"updatedRows,omitempty"`

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

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

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

// UpdateValuesResponse: The response when updating a range of values in
// a spreadsheet.
type UpdateValuesResponse struct {
	// SpreadsheetId: The spreadsheet the updates were applied to.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// UpdatedCells: The number of cells updated.
	UpdatedCells int64 `json:"updatedCells,omitempty"`

	// UpdatedColumns: The number of columns where at least one cell in the
	// column was updated.
	UpdatedColumns int64 `json:"updatedColumns,omitempty"`

	// UpdatedData: The values of the cells after updates were applied. This
	// is only included if the request's `includeValuesInResponse` field was
	// `true`.
	UpdatedData *ValueRange `json:"updatedData,omitempty"`

	// UpdatedRange: The range (in A1 notation) that updates were applied
	// to.
	UpdatedRange string `json:"updatedRange,omitempty"`

	// UpdatedRows: The number of rows where at least one cell in the row
	// was updated.
	UpdatedRows int64 `json:"updatedRows,omitempty"`

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

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

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

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

// ValueRange: Data within a range of the spreadsheet.
type ValueRange struct {
	// MajorDimension: The major dimension of the values. For output, if the
	// spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, then requesting
	// `range=A1:B2,majorDimension=ROWS` will return `[[1,2],[3,4]]`,
	// whereas requesting `range=A1:B2,majorDimension=COLUMNS` will return
	// `[[1,3],[2,4]]`. For input, with `range=A1:B2,majorDimension=ROWS`
	// then `[[1,2],[3,4]]` will set `A1=1,B1=2,A2=3,B2=4`. With
	// `range=A1:B2,majorDimension=COLUMNS` then `[[1,2],[3,4]]` will set
	// `A1=1,B1=3,A2=2,B2=4`. When writing, if this field is not set, it
	// defaults to ROWS.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
	//   "ROWS" - Operates on the rows of a sheet.
	//   "COLUMNS" - Operates on the columns of a sheet.
	MajorDimension string `json:"majorDimension,omitempty"`

	// Range: The range the values cover, in A1 notation. For output, this
	// range indicates the entire requested range, even though the values
	// will exclude trailing rows and columns. When appending values, this
	// field represents the range to search for a table, after which values
	// will be appended.
	Range string `json:"range,omitempty"`

	// Values: The data that was read or to be written. This is an array of
	// arrays, the outer array representing all the data and each inner
	// array representing a major dimension. Each item in the inner array
	// corresponds with one cell. For output, empty trailing rows and
	// columns will not be included. For input, supported value types are:
	// bool, string, and double. Null values will be skipped. To set a cell
	// to an empty value, set the string value to an empty string.
	Values [][]interface{} `json:"values,omitempty"`

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

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

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

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

// WaterfallChartColumnStyle: Styles for a waterfall chart column.
type WaterfallChartColumnStyle struct {
	// Color: The color of the column.
	Color *Color `json:"color,omitempty"`

	// ColorStyle: The color of the column. If color is also set, this field
	// takes precedence.
	ColorStyle *ColorStyle `json:"colorStyle,omitempty"`

	// Label: The label of the column's legend.
	Label string `json:"label,omitempty"`

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

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

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

// WaterfallChartCustomSubtotal: A custom subtotal column for a
// waterfall chart series.
type WaterfallChartCustomSubtotal struct {
	// DataIsSubtotal: True if the data point at subtotal_index is the
	// subtotal. If false, the subtotal will be computed and appear after
	// the data point.
	DataIsSubtotal bool `json:"dataIsSubtotal,omitempty"`

	// Label: A label for the subtotal column.
	Label string `json:"label,omitempty"`

	// SubtotalIndex: The 0-based index of a data point within the series.
	// If data_is_subtotal is true, the data point at this index is the
	// subtotal. Otherwise, the subtotal appears after the data point with
	// this index. A series can have multiple subtotals at arbitrary
	// indices, but subtotals do not affect the indices of the data points.
	// For example, if a series has three data points, their indices will
	// always be 0, 1, and 2, regardless of how many subtotals exist on the
	// series or what data points they are associated with.
	SubtotalIndex int64 `json:"subtotalIndex,omitempty"`

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

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

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

// WaterfallChartDomain: The domain of a waterfall chart.
type WaterfallChartDomain struct {
	// Data: The data of the WaterfallChartDomain.
	Data *ChartData `json:"data,omitempty"`

	// Reversed: True to reverse the order of the domain values (horizontal
	// axis).
	Reversed bool `json:"reversed,omitempty"`

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

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

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

// WaterfallChartSeries: A single series of data for a waterfall chart.
type WaterfallChartSeries struct {
	// CustomSubtotals: Custom subtotal columns appearing in this series.
	// The order in which subtotals are defined is not significant. Only one
	// subtotal may be defined for each data point.
	CustomSubtotals []*WaterfallChartCustomSubtotal `json:"customSubtotals,omitempty"`

	// Data: The data being visualized in this series.
	Data *ChartData `json:"data,omitempty"`

	// HideTrailingSubtotal: True to hide the subtotal column from the end
	// of the series. By default, a subtotal column will appear at the end
	// of each series. Setting this field to true will hide that subtotal
	// column for this series.
	HideTrailingSubtotal bool `json:"hideTrailingSubtotal,omitempty"`

	// NegativeColumnsStyle: Styles for all columns in this series with
	// negative values.
	NegativeColumnsStyle *WaterfallChartColumnStyle `json:"negativeColumnsStyle,omitempty"`

	// PositiveColumnsStyle: Styles for all columns in this series with
	// positive values.
	PositiveColumnsStyle *WaterfallChartColumnStyle `json:"positiveColumnsStyle,omitempty"`

	// SubtotalColumnsStyle: Styles for all subtotal columns in this series.
	SubtotalColumnsStyle *WaterfallChartColumnStyle `json:"subtotalColumnsStyle,omitempty"`

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

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

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

// WaterfallChartSpec: A waterfall chart.
type WaterfallChartSpec struct {
	// ConnectorLineStyle: The line style for the connector lines.
	ConnectorLineStyle *LineStyle `json:"connectorLineStyle,omitempty"`

	// Domain: The domain data (horizontal axis) for the waterfall chart.
	Domain *WaterfallChartDomain `json:"domain,omitempty"`

	// FirstValueIsTotal: True to interpret the first value as a total.
	FirstValueIsTotal bool `json:"firstValueIsTotal,omitempty"`

	// HideConnectorLines: True to hide connector lines between columns.
	HideConnectorLines bool `json:"hideConnectorLines,omitempty"`

	// Series: The data this waterfall chart is visualizing.
	Series []*WaterfallChartSeries `json:"series,omitempty"`

	// StackedType: The stacked type.
	//
	// Possible values:
	//   "WATERFALL_STACKED_TYPE_UNSPECIFIED" - Default value, do not use.
	//   "STACKED" - Values corresponding to the same domain (horizontal
	// axis) value will be stacked vertically.
	//   "SEQUENTIAL" - Series will spread out along the horizontal axis.
	StackedType string `json:"stackedType,omitempty"`

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

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

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

// method id "sheets.spreadsheets.batchUpdate":

type SpreadsheetsBatchUpdateCall struct {
	s                             *Service
	spreadsheetId                 string
	batchupdatespreadsheetrequest *BatchUpdateSpreadsheetRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// BatchUpdate: Applies one or more updates to the spreadsheet. Each
// request is validated before being applied. If any request is not
// valid then the entire request will fail and nothing will be applied.
// Some requests have replies to give you some information about how
// they are applied. The replies will mirror the requests. For example,
// if you applied 4 updates and the 3rd one had a reply, then the
// response will have 2 empty replies, the actual reply, and another
// empty reply, in that order. Due to the collaborative nature of
// spreadsheets, it is not guaranteed that the spreadsheet will reflect
// exactly your changes after this completes, however it is guaranteed
// that the updates in the request will be applied together atomically.
// Your changes may be altered with respect to collaborator changes. If
// there are no collaborators, the spreadsheet should reflect your
// changes.
func (r *SpreadsheetsService) BatchUpdate(spreadsheetId string, batchupdatespreadsheetrequest *BatchUpdateSpreadsheetRequest) *SpreadsheetsBatchUpdateCall {
	c := &SpreadsheetsBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.batchupdatespreadsheetrequest = batchupdatespreadsheetrequest
	return c
}

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

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

func (c *SpreadsheetsBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.batchupdatespreadsheetrequest)
	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, "v4/spreadsheets/{spreadsheetId}:batchUpdate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.batchUpdate" call.
// Exactly one of *BatchUpdateSpreadsheetResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BatchUpdateSpreadsheetResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsBatchUpdateCall) Do(opts ...googleapi.CallOption) (*BatchUpdateSpreadsheetResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchUpdateSpreadsheetResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Applies one or more updates to the spreadsheet. Each request is validated before being applied. If any request is not valid then the entire request will fail and nothing will be applied. Some requests have replies to give you some information about how they are applied. The replies will mirror the requests. For example, if you applied 4 updates and the 3rd one had a reply, then the response will have 2 empty replies, the actual reply, and another empty reply, in that order. Due to the collaborative nature of spreadsheets, it is not guaranteed that the spreadsheet will reflect exactly your changes after this completes, however it is guaranteed that the updates in the request will be applied together atomically. Your changes may be altered with respect to collaborator changes. If there are no collaborators, the spreadsheet should reflect your changes.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.batchUpdate",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "spreadsheetId": {
	//       "description": "The spreadsheet to apply the updates to.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}:batchUpdate",
	//   "request": {
	//     "$ref": "BatchUpdateSpreadsheetRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchUpdateSpreadsheetResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.create":

type SpreadsheetsCreateCall struct {
	s           *Service
	spreadsheet *Spreadsheet
	urlParams_  gensupport.URLParams
	ctx_        context.Context
	header_     http.Header
}

// Create: Creates a spreadsheet, returning the newly created
// spreadsheet.
func (r *SpreadsheetsService) Create(spreadsheet *Spreadsheet) *SpreadsheetsCreateCall {
	c := &SpreadsheetsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheet = spreadsheet
	return c
}

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

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

func (c *SpreadsheetsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.spreadsheet)
	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, "v4/spreadsheets")
	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 "sheets.spreadsheets.create" call.
// Exactly one of *Spreadsheet or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Spreadsheet.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SpreadsheetsCreateCall) Do(opts ...googleapi.CallOption) (*Spreadsheet, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Spreadsheet{
		ServerResponse: googleapi.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 spreadsheet, returning the newly created spreadsheet.",
	//   "flatPath": "v4/spreadsheets",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v4/spreadsheets",
	//   "request": {
	//     "$ref": "Spreadsheet"
	//   },
	//   "response": {
	//     "$ref": "Spreadsheet"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.get":

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

// Get: Returns the spreadsheet at the given ID. The caller must specify
// the spreadsheet ID. By default, data within grids will not be
// returned. You can include grid data one of two ways: * Specify a
// field mask listing your desired fields using the `fields` URL
// parameter in HTTP * Set the includeGridData URL parameter to true. If
// a field mask is set, the `includeGridData` parameter is ignored For
// large spreadsheets, it is recommended to retrieve only the specific
// fields of the spreadsheet that you want. To retrieve only subsets of
// the spreadsheet, use the ranges URL parameter. Multiple ranges can be
// specified. Limiting the range will return only the portions of the
// spreadsheet that intersect the requested ranges. Ranges are specified
// using A1 notation.
func (r *SpreadsheetsService) Get(spreadsheetId string) *SpreadsheetsGetCall {
	c := &SpreadsheetsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	return c
}

// IncludeGridData sets the optional parameter "includeGridData": True
// if grid data should be returned. This parameter is ignored if a field
// mask was set in the request.
func (c *SpreadsheetsGetCall) IncludeGridData(includeGridData bool) *SpreadsheetsGetCall {
	c.urlParams_.Set("includeGridData", fmt.Sprint(includeGridData))
	return c
}

// Ranges sets the optional parameter "ranges": The ranges to retrieve
// from the spreadsheet.
func (c *SpreadsheetsGetCall) Ranges(ranges ...string) *SpreadsheetsGetCall {
	c.urlParams_.SetMulti("ranges", append([]string{}, ranges...))
	return c
}

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

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

func (c *SpreadsheetsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "v4/spreadsheets/{spreadsheetId}")
	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{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.get" call.
// Exactly one of *Spreadsheet or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Spreadsheet.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SpreadsheetsGetCall) Do(opts ...googleapi.CallOption) (*Spreadsheet, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Spreadsheet{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the spreadsheet at the given ID. The caller must specify the spreadsheet ID. By default, data within grids will not be returned. You can include grid data one of two ways: * Specify a field mask listing your desired fields using the `fields` URL parameter in HTTP * Set the includeGridData URL parameter to true. If a field mask is set, the `includeGridData` parameter is ignored For large spreadsheets, it is recommended to retrieve only the specific fields of the spreadsheet that you want. To retrieve only subsets of the spreadsheet, use the ranges URL parameter. Multiple ranges can be specified. Limiting the range will return only the portions of the spreadsheet that intersect the requested ranges. Ranges are specified using A1 notation.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}",
	//   "httpMethod": "GET",
	//   "id": "sheets.spreadsheets.get",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "includeGridData": {
	//       "description": "True if grid data should be returned. This parameter is ignored if a field mask was set in the request.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ranges": {
	//       "description": "The ranges to retrieve from the spreadsheet.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "spreadsheetId": {
	//       "description": "The spreadsheet to request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}",
	//   "response": {
	//     "$ref": "Spreadsheet"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/spreadsheets",
	//     "https://www.googleapis.com/auth/spreadsheets.readonly"
	//   ]
	// }

}

// method id "sheets.spreadsheets.getByDataFilter":

type SpreadsheetsGetByDataFilterCall struct {
	s                                 *Service
	spreadsheetId                     string
	getspreadsheetbydatafilterrequest *GetSpreadsheetByDataFilterRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// GetByDataFilter: Returns the spreadsheet at the given ID. The caller
// must specify the spreadsheet ID. This method differs from
// GetSpreadsheet in that it allows selecting which subsets of
// spreadsheet data to return by specifying a dataFilters parameter.
// Multiple DataFilters can be specified. Specifying one or more data
// filters will return the portions of the spreadsheet that intersect
// ranges matched by any of the filters. By default, data within grids
// will not be returned. You can include grid data one of two ways: *
// Specify a field mask listing your desired fields using the `fields`
// URL parameter in HTTP * Set the includeGridData parameter to true. If
// a field mask is set, the `includeGridData` parameter is ignored For
// large spreadsheets, it is recommended to retrieve only the specific
// fields of the spreadsheet that you want.
func (r *SpreadsheetsService) GetByDataFilter(spreadsheetId string, getspreadsheetbydatafilterrequest *GetSpreadsheetByDataFilterRequest) *SpreadsheetsGetByDataFilterCall {
	c := &SpreadsheetsGetByDataFilterCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.getspreadsheetbydatafilterrequest = getspreadsheetbydatafilterrequest
	return c
}

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

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

func (c *SpreadsheetsGetByDataFilterCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.getspreadsheetbydatafilterrequest)
	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, "v4/spreadsheets/{spreadsheetId}:getByDataFilter")
	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{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.getByDataFilter" call.
// Exactly one of *Spreadsheet or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Spreadsheet.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SpreadsheetsGetByDataFilterCall) Do(opts ...googleapi.CallOption) (*Spreadsheet, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Spreadsheet{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the spreadsheet at the given ID. The caller must specify the spreadsheet ID. This method differs from GetSpreadsheet in that it allows selecting which subsets of spreadsheet data to return by specifying a dataFilters parameter. Multiple DataFilters can be specified. Specifying one or more data filters will return the portions of the spreadsheet that intersect ranges matched by any of the filters. By default, data within grids will not be returned. You can include grid data one of two ways: * Specify a field mask listing your desired fields using the `fields` URL parameter in HTTP * Set the includeGridData parameter to true. If a field mask is set, the `includeGridData` parameter is ignored For large spreadsheets, it is recommended to retrieve only the specific fields of the spreadsheet that you want.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}:getByDataFilter",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.getByDataFilter",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "spreadsheetId": {
	//       "description": "The spreadsheet to request.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}:getByDataFilter",
	//   "request": {
	//     "$ref": "GetSpreadsheetByDataFilterRequest"
	//   },
	//   "response": {
	//     "$ref": "Spreadsheet"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.developerMetadata.get":

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

// Get: Returns the developer metadata with the specified ID. The caller
// must specify the spreadsheet ID and the developer metadata's unique
// metadataId.
func (r *SpreadsheetsDeveloperMetadataService) Get(spreadsheetId string, metadataId int64) *SpreadsheetsDeveloperMetadataGetCall {
	c := &SpreadsheetsDeveloperMetadataGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.metadataId = metadataId
	return c
}

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

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

func (c *SpreadsheetsDeveloperMetadataGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "v4/spreadsheets/{spreadsheetId}/developerMetadata/{metadataId}")
	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{
		"spreadsheetId": c.spreadsheetId,
		"metadataId":    strconv.FormatInt(c.metadataId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.developerMetadata.get" call.
// Exactly one of *DeveloperMetadata or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DeveloperMetadata.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsDeveloperMetadataGetCall) Do(opts ...googleapi.CallOption) (*DeveloperMetadata, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DeveloperMetadata{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the developer metadata with the specified ID. The caller must specify the spreadsheet ID and the developer metadata's unique metadataId.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/developerMetadata/{metadataId}",
	//   "httpMethod": "GET",
	//   "id": "sheets.spreadsheets.developerMetadata.get",
	//   "parameterOrder": [
	//     "spreadsheetId",
	//     "metadataId"
	//   ],
	//   "parameters": {
	//     "metadataId": {
	//       "description": "The ID of the developer metadata to retrieve.",
	//       "format": "int32",
	//       "location": "path",
	//       "required": true,
	//       "type": "integer"
	//     },
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to retrieve metadata from.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/developerMetadata/{metadataId}",
	//   "response": {
	//     "$ref": "DeveloperMetadata"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.developerMetadata.search":

type SpreadsheetsDeveloperMetadataSearchCall struct {
	s                              *Service
	spreadsheetId                  string
	searchdevelopermetadatarequest *SearchDeveloperMetadataRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Search: Returns all developer metadata matching the specified
// DataFilter. If the provided DataFilter represents a
// DeveloperMetadataLookup object, this will return all
// DeveloperMetadata entries selected by it. If the DataFilter
// represents a location in a spreadsheet, this will return all
// developer metadata associated with locations intersecting that
// region.
func (r *SpreadsheetsDeveloperMetadataService) Search(spreadsheetId string, searchdevelopermetadatarequest *SearchDeveloperMetadataRequest) *SpreadsheetsDeveloperMetadataSearchCall {
	c := &SpreadsheetsDeveloperMetadataSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.searchdevelopermetadatarequest = searchdevelopermetadatarequest
	return c
}

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

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

func (c *SpreadsheetsDeveloperMetadataSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.searchdevelopermetadatarequest)
	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, "v4/spreadsheets/{spreadsheetId}/developerMetadata:search")
	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{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.developerMetadata.search" call.
// Exactly one of *SearchDeveloperMetadataResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *SearchDeveloperMetadataResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsDeveloperMetadataSearchCall) Do(opts ...googleapi.CallOption) (*SearchDeveloperMetadataResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SearchDeveloperMetadataResponse{
		ServerResponse: googleapi.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 all developer metadata matching the specified DataFilter. If the provided DataFilter represents a DeveloperMetadataLookup object, this will return all DeveloperMetadata entries selected by it. If the DataFilter represents a location in a spreadsheet, this will return all developer metadata associated with locations intersecting that region.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/developerMetadata:search",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.developerMetadata.search",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to retrieve metadata from.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/developerMetadata:search",
	//   "request": {
	//     "$ref": "SearchDeveloperMetadataRequest"
	//   },
	//   "response": {
	//     "$ref": "SearchDeveloperMetadataResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.sheets.copyTo":

type SpreadsheetsSheetsCopyToCall struct {
	s                                    *Service
	spreadsheetId                        string
	sheetId                              int64
	copysheettoanotherspreadsheetrequest *CopySheetToAnotherSpreadsheetRequest
	urlParams_                           gensupport.URLParams
	ctx_                                 context.Context
	header_                              http.Header
}

// CopyTo: Copies a single sheet from a spreadsheet to another
// spreadsheet. Returns the properties of the newly created sheet.
func (r *SpreadsheetsSheetsService) CopyTo(spreadsheetId string, sheetId int64, copysheettoanotherspreadsheetrequest *CopySheetToAnotherSpreadsheetRequest) *SpreadsheetsSheetsCopyToCall {
	c := &SpreadsheetsSheetsCopyToCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.sheetId = sheetId
	c.copysheettoanotherspreadsheetrequest = copysheettoanotherspreadsheetrequest
	return c
}

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

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

func (c *SpreadsheetsSheetsCopyToCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.copysheettoanotherspreadsheetrequest)
	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, "v4/spreadsheets/{spreadsheetId}/sheets/{sheetId}:copyTo")
	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{
		"spreadsheetId": c.spreadsheetId,
		"sheetId":       strconv.FormatInt(c.sheetId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.sheets.copyTo" call.
// Exactly one of *SheetProperties or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *SheetProperties.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsSheetsCopyToCall) Do(opts ...googleapi.CallOption) (*SheetProperties, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SheetProperties{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Copies a single sheet from a spreadsheet to another spreadsheet. Returns the properties of the newly created sheet.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/sheets/{sheetId}:copyTo",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.sheets.copyTo",
	//   "parameterOrder": [
	//     "spreadsheetId",
	//     "sheetId"
	//   ],
	//   "parameters": {
	//     "sheetId": {
	//       "description": "The ID of the sheet to copy.",
	//       "format": "int32",
	//       "location": "path",
	//       "required": true,
	//       "type": "integer"
	//     },
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet containing the sheet to copy.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/sheets/{sheetId}:copyTo",
	//   "request": {
	//     "$ref": "CopySheetToAnotherSpreadsheetRequest"
	//   },
	//   "response": {
	//     "$ref": "SheetProperties"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.append":

type SpreadsheetsValuesAppendCall struct {
	s             *Service
	spreadsheetId string
	range_        string
	valuerange    *ValueRange
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Append: Appends values to a spreadsheet. The input range is used to
// search for existing data and find a "table" within that range. Values
// will be appended to the next row of the table, starting with the
// first column of the table. See the
// [guide](/sheets/api/guides/values#appending_values) and [sample
// code](/sheets/api/samples/writing#append_values) for specific details
// of how tables are detected and data is appended. The caller must
// specify the spreadsheet ID, range, and a valueInputOption. The
// `valueInputOption` only controls how the input data will be added to
// the sheet (column-wise or row-wise), it does not influence what cell
// the data starts being written to.
func (r *SpreadsheetsValuesService) Append(spreadsheetId string, range_ string, valuerange *ValueRange) *SpreadsheetsValuesAppendCall {
	c := &SpreadsheetsValuesAppendCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.range_ = range_
	c.valuerange = valuerange
	return c
}

// IncludeValuesInResponse sets the optional parameter
// "includeValuesInResponse": Determines if the update response should
// include the values of the cells that were appended. By default,
// responses do not include the updated values.
func (c *SpreadsheetsValuesAppendCall) IncludeValuesInResponse(includeValuesInResponse bool) *SpreadsheetsValuesAppendCall {
	c.urlParams_.Set("includeValuesInResponse", fmt.Sprint(includeValuesInResponse))
	return c
}

// InsertDataOption sets the optional parameter "insertDataOption": How
// the input data should be inserted.
//
// Possible values:
//   "OVERWRITE" - The new data overwrites existing data in the areas it
// is written. (Note: adding data to the end of the sheet will still
// insert new rows or columns so the data can be written.)
//   "INSERT_ROWS" - Rows are inserted for the new data.
func (c *SpreadsheetsValuesAppendCall) InsertDataOption(insertDataOption string) *SpreadsheetsValuesAppendCall {
	c.urlParams_.Set("insertDataOption", insertDataOption)
	return c
}

// ResponseDateTimeRenderOption sets the optional parameter
// "responseDateTimeRenderOption": Determines how dates, times, and
// durations in the response should be rendered. This is ignored if
// response_value_render_option is FORMATTED_VALUE. The default dateTime
// render option is [DateTimeRenderOption.SERIAL_NUMBER].
//
// Possible values:
//   "SERIAL_NUMBER" - Instructs date, time, datetime, and duration
// fields to be output as doubles in "serial number" format, as
// popularized by Lotus 1-2-3. The whole number portion of the value
// (left of the decimal) counts the days since December 30th 1899. The
// fractional portion (right of the decimal) counts the time as a
// fraction of the day. For example, January 1st 1900 at noon would be
// 2.5, 2 because it's 2 days after December 30st 1899, and .5 because
// noon is half a day. February 1st 1900 at 3pm would be 33.625. This
// correctly treats the year 1900 as not a leap year.
//   "FORMATTED_STRING" - Instructs date, time, datetime, and duration
// fields to be output as strings in their given number format (which is
// dependent on the spreadsheet locale).
func (c *SpreadsheetsValuesAppendCall) ResponseDateTimeRenderOption(responseDateTimeRenderOption string) *SpreadsheetsValuesAppendCall {
	c.urlParams_.Set("responseDateTimeRenderOption", responseDateTimeRenderOption)
	return c
}

// ResponseValueRenderOption sets the optional parameter
// "responseValueRenderOption": Determines how values in the response
// should be rendered. The default render option is
// ValueRenderOption.FORMATTED_VALUE.
//
// Possible values:
//   "FORMATTED_VALUE" - Values will be calculated & formatted in the
// reply according to the cell's formatting. Formatting is based on the
// spreadsheet's locale, not the requesting user's locale. For example,
// if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then
// `A2` would return "$1.23".
//   "UNFORMATTED_VALUE" - Values will be calculated, but not formatted
// in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and
// formatted as currency, then `A2` would return the number `1.23`.
//   "FORMULA" - Values will not be calculated. The reply will include
// the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and
// formatted as currency, then A2 would return "=A1".
func (c *SpreadsheetsValuesAppendCall) ResponseValueRenderOption(responseValueRenderOption string) *SpreadsheetsValuesAppendCall {
	c.urlParams_.Set("responseValueRenderOption", responseValueRenderOption)
	return c
}

// ValueInputOption sets the optional parameter "valueInputOption": How
// the input data should be interpreted.
//
// Possible values:
//   "INPUT_VALUE_OPTION_UNSPECIFIED" - Default input value. This value
// must not be used.
//   "RAW" - The values the user has entered will not be parsed and will
// be stored as-is.
//   "USER_ENTERED" - The values will be parsed as if the user typed
// them into the UI. Numbers will stay as numbers, but strings may be
// converted to numbers, dates, etc. following the same rules that are
// applied when entering text into a cell via the Google Sheets UI.
func (c *SpreadsheetsValuesAppendCall) ValueInputOption(valueInputOption string) *SpreadsheetsValuesAppendCall {
	c.urlParams_.Set("valueInputOption", valueInputOption)
	return c
}

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

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

func (c *SpreadsheetsValuesAppendCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.valuerange)
	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, "v4/spreadsheets/{spreadsheetId}/values/{range}:append")
	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{
		"spreadsheetId": c.spreadsheetId,
		"range":         c.range_,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.append" call.
// Exactly one of *AppendValuesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AppendValuesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsValuesAppendCall) Do(opts ...googleapi.CallOption) (*AppendValuesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AppendValuesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Appends values to a spreadsheet. The input range is used to search for existing data and find a \"table\" within that range. Values will be appended to the next row of the table, starting with the first column of the table. See the [guide](/sheets/api/guides/values#appending_values) and [sample code](/sheets/api/samples/writing#append_values) for specific details of how tables are detected and data is appended. The caller must specify the spreadsheet ID, range, and a valueInputOption. The `valueInputOption` only controls how the input data will be added to the sheet (column-wise or row-wise), it does not influence what cell the data starts being written to.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values/{range}:append",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.values.append",
	//   "parameterOrder": [
	//     "spreadsheetId",
	//     "range"
	//   ],
	//   "parameters": {
	//     "includeValuesInResponse": {
	//       "description": "Determines if the update response should include the values of the cells that were appended. By default, responses do not include the updated values.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "insertDataOption": {
	//       "description": "How the input data should be inserted.",
	//       "enum": [
	//         "OVERWRITE",
	//         "INSERT_ROWS"
	//       ],
	//       "enumDescriptions": [
	//         "The new data overwrites existing data in the areas it is written. (Note: adding data to the end of the sheet will still insert new rows or columns so the data can be written.)",
	//         "Rows are inserted for the new data."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "range": {
	//       "description": "The A1 notation of a range to search for a logical table of data. Values are appended after the last row of the table.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "responseDateTimeRenderOption": {
	//       "description": "Determines how dates, times, and durations in the response should be rendered. This is ignored if response_value_render_option is FORMATTED_VALUE. The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER].",
	//       "enum": [
	//         "SERIAL_NUMBER",
	//         "FORMATTED_STRING"
	//       ],
	//       "enumDescriptions": [
	//         "Instructs date, time, datetime, and duration fields to be output as doubles in \"serial number\" format, as popularized by Lotus 1-2-3. The whole number portion of the value (left of the decimal) counts the days since December 30th 1899. The fractional portion (right of the decimal) counts the time as a fraction of the day. For example, January 1st 1900 at noon would be 2.5, 2 because it's 2 days after December 30st 1899, and .5 because noon is half a day. February 1st 1900 at 3pm would be 33.625. This correctly treats the year 1900 as not a leap year.",
	//         "Instructs date, time, datetime, and duration fields to be output as strings in their given number format (which is dependent on the spreadsheet locale)."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "responseValueRenderOption": {
	//       "description": "Determines how values in the response should be rendered. The default render option is ValueRenderOption.FORMATTED_VALUE.",
	//       "enum": [
	//         "FORMATTED_VALUE",
	//         "UNFORMATTED_VALUE",
	//         "FORMULA"
	//       ],
	//       "enumDescriptions": [
	//         "Values will be calculated \u0026 formatted in the reply according to the cell's formatting. Formatting is based on the spreadsheet's locale, not the requesting user's locale. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then `A2` would return `\"$1.23\"`.",
	//         "Values will be calculated, but not formatted in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then `A2` would return the number `1.23`.",
	//         "Values will not be calculated. The reply will include the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then A2 would return `\"=A1\"`."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "valueInputOption": {
	//       "description": "How the input data should be interpreted.",
	//       "enum": [
	//         "INPUT_VALUE_OPTION_UNSPECIFIED",
	//         "RAW",
	//         "USER_ENTERED"
	//       ],
	//       "enumDescriptions": [
	//         "Default input value. This value must not be used.",
	//         "The values the user has entered will not be parsed and will be stored as-is.",
	//         "The values will be parsed as if the user typed them into the UI. Numbers will stay as numbers, but strings may be converted to numbers, dates, etc. following the same rules that are applied when entering text into a cell via the Google Sheets UI."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values/{range}:append",
	//   "request": {
	//     "$ref": "ValueRange"
	//   },
	//   "response": {
	//     "$ref": "AppendValuesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.batchClear":

type SpreadsheetsValuesBatchClearCall struct {
	s                       *Service
	spreadsheetId           string
	batchclearvaluesrequest *BatchClearValuesRequest
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// BatchClear: Clears one or more ranges of values from a spreadsheet.
// The caller must specify the spreadsheet ID and one or more ranges.
// Only values are cleared -- all other properties of the cell (such as
// formatting, data validation, etc..) are kept.
func (r *SpreadsheetsValuesService) BatchClear(spreadsheetId string, batchclearvaluesrequest *BatchClearValuesRequest) *SpreadsheetsValuesBatchClearCall {
	c := &SpreadsheetsValuesBatchClearCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.batchclearvaluesrequest = batchclearvaluesrequest
	return c
}

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

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

func (c *SpreadsheetsValuesBatchClearCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.batchclearvaluesrequest)
	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, "v4/spreadsheets/{spreadsheetId}/values:batchClear")
	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{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.batchClear" call.
// Exactly one of *BatchClearValuesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *BatchClearValuesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsValuesBatchClearCall) Do(opts ...googleapi.CallOption) (*BatchClearValuesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchClearValuesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Clears one or more ranges of values from a spreadsheet. The caller must specify the spreadsheet ID and one or more ranges. Only values are cleared -- all other properties of the cell (such as formatting, data validation, etc..) are kept.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values:batchClear",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.values.batchClear",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values:batchClear",
	//   "request": {
	//     "$ref": "BatchClearValuesRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchClearValuesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.batchClearByDataFilter":

type SpreadsheetsValuesBatchClearByDataFilterCall struct {
	s                                   *Service
	spreadsheetId                       string
	batchclearvaluesbydatafilterrequest *BatchClearValuesByDataFilterRequest
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// BatchClearByDataFilter: Clears one or more ranges of values from a
// spreadsheet. The caller must specify the spreadsheet ID and one or
// more DataFilters. Ranges matching any of the specified data filters
// will be cleared. Only values are cleared -- all other properties of
// the cell (such as formatting, data validation, etc..) are kept.
func (r *SpreadsheetsValuesService) BatchClearByDataFilter(spreadsheetId string, batchclearvaluesbydatafilterrequest *BatchClearValuesByDataFilterRequest) *SpreadsheetsValuesBatchClearByDataFilterCall {
	c := &SpreadsheetsValuesBatchClearByDataFilterCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.batchclearvaluesbydatafilterrequest = batchclearvaluesbydatafilterrequest
	return c
}

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

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

func (c *SpreadsheetsValuesBatchClearByDataFilterCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.batchclearvaluesbydatafilterrequest)
	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, "v4/spreadsheets/{spreadsheetId}/values:batchClearByDataFilter")
	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{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.batchClearByDataFilter" call.
// Exactly one of *BatchClearValuesByDataFilterResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BatchClearValuesByDataFilterResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SpreadsheetsValuesBatchClearByDataFilterCall) Do(opts ...googleapi.CallOption) (*BatchClearValuesByDataFilterResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchClearValuesByDataFilterResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Clears one or more ranges of values from a spreadsheet. The caller must specify the spreadsheet ID and one or more DataFilters. Ranges matching any of the specified data filters will be cleared. Only values are cleared -- all other properties of the cell (such as formatting, data validation, etc..) are kept.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values:batchClearByDataFilter",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.values.batchClearByDataFilter",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values:batchClearByDataFilter",
	//   "request": {
	//     "$ref": "BatchClearValuesByDataFilterRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchClearValuesByDataFilterResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.batchGet":

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

// BatchGet: Returns one or more ranges of values from a spreadsheet.
// The caller must specify the spreadsheet ID and one or more ranges.
func (r *SpreadsheetsValuesService) BatchGet(spreadsheetId string) *SpreadsheetsValuesBatchGetCall {
	c := &SpreadsheetsValuesBatchGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	return c
}

// DateTimeRenderOption sets the optional parameter
// "dateTimeRenderOption": How dates, times, and durations should be
// represented in the output. This is ignored if value_render_option is
// FORMATTED_VALUE. The default dateTime render option is
// [DateTimeRenderOption.SERIAL_NUMBER].
//
// Possible values:
//   "SERIAL_NUMBER" - Instructs date, time, datetime, and duration
// fields to be output as doubles in "serial number" format, as
// popularized by Lotus 1-2-3. The whole number portion of the value
// (left of the decimal) counts the days since December 30th 1899. The
// fractional portion (right of the decimal) counts the time as a
// fraction of the day. For example, January 1st 1900 at noon would be
// 2.5, 2 because it's 2 days after December 30st 1899, and .5 because
// noon is half a day. February 1st 1900 at 3pm would be 33.625. This
// correctly treats the year 1900 as not a leap year.
//   "FORMATTED_STRING" - Instructs date, time, datetime, and duration
// fields to be output as strings in their given number format (which is
// dependent on the spreadsheet locale).
func (c *SpreadsheetsValuesBatchGetCall) DateTimeRenderOption(dateTimeRenderOption string) *SpreadsheetsValuesBatchGetCall {
	c.urlParams_.Set("dateTimeRenderOption", dateTimeRenderOption)
	return c
}

// MajorDimension sets the optional parameter "majorDimension": The
// major dimension that results should use. For example, if the
// spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, then requesting
// `range=A1:B2,majorDimension=ROWS` returns `[[1,2],[3,4]]`, whereas
// requesting `range=A1:B2,majorDimension=COLUMNS` returns
// `[[1,3],[2,4]]`.
//
// Possible values:
//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
//   "ROWS" - Operates on the rows of a sheet.
//   "COLUMNS" - Operates on the columns of a sheet.
func (c *SpreadsheetsValuesBatchGetCall) MajorDimension(majorDimension string) *SpreadsheetsValuesBatchGetCall {
	c.urlParams_.Set("majorDimension", majorDimension)
	return c
}

// Ranges sets the optional parameter "ranges": The A1 notation of the
// values to retrieve.
func (c *SpreadsheetsValuesBatchGetCall) Ranges(ranges ...string) *SpreadsheetsValuesBatchGetCall {
	c.urlParams_.SetMulti("ranges", append([]string{}, ranges...))
	return c
}

// ValueRenderOption sets the optional parameter "valueRenderOption":
// How values should be represented in the output. The default render
// option is ValueRenderOption.FORMATTED_VALUE.
//
// Possible values:
//   "FORMATTED_VALUE" - Values will be calculated & formatted in the
// reply according to the cell's formatting. Formatting is based on the
// spreadsheet's locale, not the requesting user's locale. For example,
// if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then
// `A2` would return "$1.23".
//   "UNFORMATTED_VALUE" - Values will be calculated, but not formatted
// in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and
// formatted as currency, then `A2` would return the number `1.23`.
//   "FORMULA" - Values will not be calculated. The reply will include
// the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and
// formatted as currency, then A2 would return "=A1".
func (c *SpreadsheetsValuesBatchGetCall) ValueRenderOption(valueRenderOption string) *SpreadsheetsValuesBatchGetCall {
	c.urlParams_.Set("valueRenderOption", valueRenderOption)
	return c
}

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

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

func (c *SpreadsheetsValuesBatchGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "v4/spreadsheets/{spreadsheetId}/values:batchGet")
	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{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.batchGet" call.
// Exactly one of *BatchGetValuesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BatchGetValuesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsValuesBatchGetCall) Do(opts ...googleapi.CallOption) (*BatchGetValuesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchGetValuesResponse{
		ServerResponse: googleapi.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 one or more ranges of values from a spreadsheet. The caller must specify the spreadsheet ID and one or more ranges.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values:batchGet",
	//   "httpMethod": "GET",
	//   "id": "sheets.spreadsheets.values.batchGet",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "dateTimeRenderOption": {
	//       "description": "How dates, times, and durations should be represented in the output. This is ignored if value_render_option is FORMATTED_VALUE. The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER].",
	//       "enum": [
	//         "SERIAL_NUMBER",
	//         "FORMATTED_STRING"
	//       ],
	//       "enumDescriptions": [
	//         "Instructs date, time, datetime, and duration fields to be output as doubles in \"serial number\" format, as popularized by Lotus 1-2-3. The whole number portion of the value (left of the decimal) counts the days since December 30th 1899. The fractional portion (right of the decimal) counts the time as a fraction of the day. For example, January 1st 1900 at noon would be 2.5, 2 because it's 2 days after December 30st 1899, and .5 because noon is half a day. February 1st 1900 at 3pm would be 33.625. This correctly treats the year 1900 as not a leap year.",
	//         "Instructs date, time, datetime, and duration fields to be output as strings in their given number format (which is dependent on the spreadsheet locale)."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "majorDimension": {
	//       "description": "The major dimension that results should use. For example, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, then requesting `range=A1:B2,majorDimension=ROWS` returns `[[1,2],[3,4]]`, whereas requesting `range=A1:B2,majorDimension=COLUMNS` returns `[[1,3],[2,4]]`.",
	//       "enum": [
	//         "DIMENSION_UNSPECIFIED",
	//         "ROWS",
	//         "COLUMNS"
	//       ],
	//       "enumDescriptions": [
	//         "The default value, do not use.",
	//         "Operates on the rows of a sheet.",
	//         "Operates on the columns of a sheet."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ranges": {
	//       "description": "The A1 notation of the values to retrieve.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to retrieve data from.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "valueRenderOption": {
	//       "description": "How values should be represented in the output. The default render option is ValueRenderOption.FORMATTED_VALUE.",
	//       "enum": [
	//         "FORMATTED_VALUE",
	//         "UNFORMATTED_VALUE",
	//         "FORMULA"
	//       ],
	//       "enumDescriptions": [
	//         "Values will be calculated \u0026 formatted in the reply according to the cell's formatting. Formatting is based on the spreadsheet's locale, not the requesting user's locale. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then `A2` would return `\"$1.23\"`.",
	//         "Values will be calculated, but not formatted in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then `A2` would return the number `1.23`.",
	//         "Values will not be calculated. The reply will include the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then A2 would return `\"=A1\"`."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values:batchGet",
	//   "response": {
	//     "$ref": "BatchGetValuesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/spreadsheets",
	//     "https://www.googleapis.com/auth/spreadsheets.readonly"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.batchGetByDataFilter":

type SpreadsheetsValuesBatchGetByDataFilterCall struct {
	s                                 *Service
	spreadsheetId                     string
	batchgetvaluesbydatafilterrequest *BatchGetValuesByDataFilterRequest
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// BatchGetByDataFilter: Returns one or more ranges of values that match
// the specified data filters. The caller must specify the spreadsheet
// ID and one or more DataFilters. Ranges that match any of the data
// filters in the request will be returned.
func (r *SpreadsheetsValuesService) BatchGetByDataFilter(spreadsheetId string, batchgetvaluesbydatafilterrequest *BatchGetValuesByDataFilterRequest) *SpreadsheetsValuesBatchGetByDataFilterCall {
	c := &SpreadsheetsValuesBatchGetByDataFilterCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.batchgetvaluesbydatafilterrequest = batchgetvaluesbydatafilterrequest
	return c
}

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

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

func (c *SpreadsheetsValuesBatchGetByDataFilterCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.batchgetvaluesbydatafilterrequest)
	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, "v4/spreadsheets/{spreadsheetId}/values:batchGetByDataFilter")
	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{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.batchGetByDataFilter" call.
// Exactly one of *BatchGetValuesByDataFilterResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BatchGetValuesByDataFilterResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SpreadsheetsValuesBatchGetByDataFilterCall) Do(opts ...googleapi.CallOption) (*BatchGetValuesByDataFilterResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchGetValuesByDataFilterResponse{
		ServerResponse: googleapi.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 one or more ranges of values that match the specified data filters. The caller must specify the spreadsheet ID and one or more DataFilters. Ranges that match any of the data filters in the request will be returned.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values:batchGetByDataFilter",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.values.batchGetByDataFilter",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to retrieve data from.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values:batchGetByDataFilter",
	//   "request": {
	//     "$ref": "BatchGetValuesByDataFilterRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchGetValuesByDataFilterResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.batchUpdate":

type SpreadsheetsValuesBatchUpdateCall struct {
	s                        *Service
	spreadsheetId            string
	batchupdatevaluesrequest *BatchUpdateValuesRequest
	urlParams_               gensupport.URLParams
	ctx_                     context.Context
	header_                  http.Header
}

// BatchUpdate: Sets values in one or more ranges of a spreadsheet. The
// caller must specify the spreadsheet ID, a valueInputOption, and one
// or more ValueRanges.
func (r *SpreadsheetsValuesService) BatchUpdate(spreadsheetId string, batchupdatevaluesrequest *BatchUpdateValuesRequest) *SpreadsheetsValuesBatchUpdateCall {
	c := &SpreadsheetsValuesBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.batchupdatevaluesrequest = batchupdatevaluesrequest
	return c
}

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

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

func (c *SpreadsheetsValuesBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.batchupdatevaluesrequest)
	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, "v4/spreadsheets/{spreadsheetId}/values:batchUpdate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.batchUpdate" call.
// Exactly one of *BatchUpdateValuesResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *BatchUpdateValuesResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsValuesBatchUpdateCall) Do(opts ...googleapi.CallOption) (*BatchUpdateValuesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchUpdateValuesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets values in one or more ranges of a spreadsheet. The caller must specify the spreadsheet ID, a valueInputOption, and one or more ValueRanges.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.values.batchUpdate",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values:batchUpdate",
	//   "request": {
	//     "$ref": "BatchUpdateValuesRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchUpdateValuesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.batchUpdateByDataFilter":

type SpreadsheetsValuesBatchUpdateByDataFilterCall struct {
	s                                    *Service
	spreadsheetId                        string
	batchupdatevaluesbydatafilterrequest *BatchUpdateValuesByDataFilterRequest
	urlParams_                           gensupport.URLParams
	ctx_                                 context.Context
	header_                              http.Header
}

// BatchUpdateByDataFilter: Sets values in one or more ranges of a
// spreadsheet. The caller must specify the spreadsheet ID, a
// valueInputOption, and one or more DataFilterValueRanges.
func (r *SpreadsheetsValuesService) BatchUpdateByDataFilter(spreadsheetId string, batchupdatevaluesbydatafilterrequest *BatchUpdateValuesByDataFilterRequest) *SpreadsheetsValuesBatchUpdateByDataFilterCall {
	c := &SpreadsheetsValuesBatchUpdateByDataFilterCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.batchupdatevaluesbydatafilterrequest = batchupdatevaluesbydatafilterrequest
	return c
}

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

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

func (c *SpreadsheetsValuesBatchUpdateByDataFilterCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.batchupdatevaluesbydatafilterrequest)
	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, "v4/spreadsheets/{spreadsheetId}/values:batchUpdateByDataFilter")
	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{
		"spreadsheetId": c.spreadsheetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.batchUpdateByDataFilter" call.
// Exactly one of *BatchUpdateValuesByDataFilterResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *BatchUpdateValuesByDataFilterResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsValuesBatchUpdateByDataFilterCall) Do(opts ...googleapi.CallOption) (*BatchUpdateValuesByDataFilterResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchUpdateValuesByDataFilterResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets values in one or more ranges of a spreadsheet. The caller must specify the spreadsheet ID, a valueInputOption, and one or more DataFilterValueRanges.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values:batchUpdateByDataFilter",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.values.batchUpdateByDataFilter",
	//   "parameterOrder": [
	//     "spreadsheetId"
	//   ],
	//   "parameters": {
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values:batchUpdateByDataFilter",
	//   "request": {
	//     "$ref": "BatchUpdateValuesByDataFilterRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchUpdateValuesByDataFilterResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.clear":

type SpreadsheetsValuesClearCall struct {
	s                  *Service
	spreadsheetId      string
	range_             string
	clearvaluesrequest *ClearValuesRequest
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Clear: Clears values from a spreadsheet. The caller must specify the
// spreadsheet ID and range. Only values are cleared -- all other
// properties of the cell (such as formatting, data validation, etc..)
// are kept.
func (r *SpreadsheetsValuesService) Clear(spreadsheetId string, range_ string, clearvaluesrequest *ClearValuesRequest) *SpreadsheetsValuesClearCall {
	c := &SpreadsheetsValuesClearCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.range_ = range_
	c.clearvaluesrequest = clearvaluesrequest
	return c
}

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

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

func (c *SpreadsheetsValuesClearCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.clearvaluesrequest)
	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, "v4/spreadsheets/{spreadsheetId}/values/{range}:clear")
	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{
		"spreadsheetId": c.spreadsheetId,
		"range":         c.range_,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.clear" call.
// Exactly one of *ClearValuesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ClearValuesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsValuesClearCall) Do(opts ...googleapi.CallOption) (*ClearValuesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ClearValuesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Clears values from a spreadsheet. The caller must specify the spreadsheet ID and range. Only values are cleared -- all other properties of the cell (such as formatting, data validation, etc..) are kept.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values/{range}:clear",
	//   "httpMethod": "POST",
	//   "id": "sheets.spreadsheets.values.clear",
	//   "parameterOrder": [
	//     "spreadsheetId",
	//     "range"
	//   ],
	//   "parameters": {
	//     "range": {
	//       "description": "The A1 notation of the values to clear.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values/{range}:clear",
	//   "request": {
	//     "$ref": "ClearValuesRequest"
	//   },
	//   "response": {
	//     "$ref": "ClearValuesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.get":

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

// Get: Returns a range of values from a spreadsheet. The caller must
// specify the spreadsheet ID and a range.
func (r *SpreadsheetsValuesService) Get(spreadsheetId string, range_ string) *SpreadsheetsValuesGetCall {
	c := &SpreadsheetsValuesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.range_ = range_
	return c
}

// DateTimeRenderOption sets the optional parameter
// "dateTimeRenderOption": How dates, times, and durations should be
// represented in the output. This is ignored if value_render_option is
// FORMATTED_VALUE. The default dateTime render option is
// [DateTimeRenderOption.SERIAL_NUMBER].
//
// Possible values:
//   "SERIAL_NUMBER" - Instructs date, time, datetime, and duration
// fields to be output as doubles in "serial number" format, as
// popularized by Lotus 1-2-3. The whole number portion of the value
// (left of the decimal) counts the days since December 30th 1899. The
// fractional portion (right of the decimal) counts the time as a
// fraction of the day. For example, January 1st 1900 at noon would be
// 2.5, 2 because it's 2 days after December 30st 1899, and .5 because
// noon is half a day. February 1st 1900 at 3pm would be 33.625. This
// correctly treats the year 1900 as not a leap year.
//   "FORMATTED_STRING" - Instructs date, time, datetime, and duration
// fields to be output as strings in their given number format (which is
// dependent on the spreadsheet locale).
func (c *SpreadsheetsValuesGetCall) DateTimeRenderOption(dateTimeRenderOption string) *SpreadsheetsValuesGetCall {
	c.urlParams_.Set("dateTimeRenderOption", dateTimeRenderOption)
	return c
}

// MajorDimension sets the optional parameter "majorDimension": The
// major dimension that results should use. For example, if the
// spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, then requesting
// `range=A1:B2,majorDimension=ROWS` returns `[[1,2],[3,4]]`, whereas
// requesting `range=A1:B2,majorDimension=COLUMNS` returns
// `[[1,3],[2,4]]`.
//
// Possible values:
//   "DIMENSION_UNSPECIFIED" - The default value, do not use.
//   "ROWS" - Operates on the rows of a sheet.
//   "COLUMNS" - Operates on the columns of a sheet.
func (c *SpreadsheetsValuesGetCall) MajorDimension(majorDimension string) *SpreadsheetsValuesGetCall {
	c.urlParams_.Set("majorDimension", majorDimension)
	return c
}

// ValueRenderOption sets the optional parameter "valueRenderOption":
// How values should be represented in the output. The default render
// option is ValueRenderOption.FORMATTED_VALUE.
//
// Possible values:
//   "FORMATTED_VALUE" - Values will be calculated & formatted in the
// reply according to the cell's formatting. Formatting is based on the
// spreadsheet's locale, not the requesting user's locale. For example,
// if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then
// `A2` would return "$1.23".
//   "UNFORMATTED_VALUE" - Values will be calculated, but not formatted
// in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and
// formatted as currency, then `A2` would return the number `1.23`.
//   "FORMULA" - Values will not be calculated. The reply will include
// the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and
// formatted as currency, then A2 would return "=A1".
func (c *SpreadsheetsValuesGetCall) ValueRenderOption(valueRenderOption string) *SpreadsheetsValuesGetCall {
	c.urlParams_.Set("valueRenderOption", valueRenderOption)
	return c
}

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

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

func (c *SpreadsheetsValuesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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, "v4/spreadsheets/{spreadsheetId}/values/{range}")
	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{
		"spreadsheetId": c.spreadsheetId,
		"range":         c.range_,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.get" call.
// Exactly one of *ValueRange or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ValueRange.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SpreadsheetsValuesGetCall) Do(opts ...googleapi.CallOption) (*ValueRange, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ValueRange{
		ServerResponse: googleapi.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 a range of values from a spreadsheet. The caller must specify the spreadsheet ID and a range.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values/{range}",
	//   "httpMethod": "GET",
	//   "id": "sheets.spreadsheets.values.get",
	//   "parameterOrder": [
	//     "spreadsheetId",
	//     "range"
	//   ],
	//   "parameters": {
	//     "dateTimeRenderOption": {
	//       "description": "How dates, times, and durations should be represented in the output. This is ignored if value_render_option is FORMATTED_VALUE. The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER].",
	//       "enum": [
	//         "SERIAL_NUMBER",
	//         "FORMATTED_STRING"
	//       ],
	//       "enumDescriptions": [
	//         "Instructs date, time, datetime, and duration fields to be output as doubles in \"serial number\" format, as popularized by Lotus 1-2-3. The whole number portion of the value (left of the decimal) counts the days since December 30th 1899. The fractional portion (right of the decimal) counts the time as a fraction of the day. For example, January 1st 1900 at noon would be 2.5, 2 because it's 2 days after December 30st 1899, and .5 because noon is half a day. February 1st 1900 at 3pm would be 33.625. This correctly treats the year 1900 as not a leap year.",
	//         "Instructs date, time, datetime, and duration fields to be output as strings in their given number format (which is dependent on the spreadsheet locale)."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "majorDimension": {
	//       "description": "The major dimension that results should use. For example, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, then requesting `range=A1:B2,majorDimension=ROWS` returns `[[1,2],[3,4]]`, whereas requesting `range=A1:B2,majorDimension=COLUMNS` returns `[[1,3],[2,4]]`.",
	//       "enum": [
	//         "DIMENSION_UNSPECIFIED",
	//         "ROWS",
	//         "COLUMNS"
	//       ],
	//       "enumDescriptions": [
	//         "The default value, do not use.",
	//         "Operates on the rows of a sheet.",
	//         "Operates on the columns of a sheet."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "range": {
	//       "description": "The A1 notation of the values to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to retrieve data from.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "valueRenderOption": {
	//       "description": "How values should be represented in the output. The default render option is ValueRenderOption.FORMATTED_VALUE.",
	//       "enum": [
	//         "FORMATTED_VALUE",
	//         "UNFORMATTED_VALUE",
	//         "FORMULA"
	//       ],
	//       "enumDescriptions": [
	//         "Values will be calculated \u0026 formatted in the reply according to the cell's formatting. Formatting is based on the spreadsheet's locale, not the requesting user's locale. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then `A2` would return `\"$1.23\"`.",
	//         "Values will be calculated, but not formatted in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then `A2` would return the number `1.23`.",
	//         "Values will not be calculated. The reply will include the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then A2 would return `\"=A1\"`."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values/{range}",
	//   "response": {
	//     "$ref": "ValueRange"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/spreadsheets",
	//     "https://www.googleapis.com/auth/spreadsheets.readonly"
	//   ]
	// }

}

// method id "sheets.spreadsheets.values.update":

type SpreadsheetsValuesUpdateCall struct {
	s             *Service
	spreadsheetId string
	range_        string
	valuerange    *ValueRange
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Update: Sets values in a range of a spreadsheet. The caller must
// specify the spreadsheet ID, range, and a valueInputOption.
func (r *SpreadsheetsValuesService) Update(spreadsheetId string, range_ string, valuerange *ValueRange) *SpreadsheetsValuesUpdateCall {
	c := &SpreadsheetsValuesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.spreadsheetId = spreadsheetId
	c.range_ = range_
	c.valuerange = valuerange
	return c
}

// IncludeValuesInResponse sets the optional parameter
// "includeValuesInResponse": Determines if the update response should
// include the values of the cells that were updated. By default,
// responses do not include the updated values. If the range to write
// was larger than the range actually written, the response includes all
// values in the requested range (excluding trailing empty rows and
// columns).
func (c *SpreadsheetsValuesUpdateCall) IncludeValuesInResponse(includeValuesInResponse bool) *SpreadsheetsValuesUpdateCall {
	c.urlParams_.Set("includeValuesInResponse", fmt.Sprint(includeValuesInResponse))
	return c
}

// ResponseDateTimeRenderOption sets the optional parameter
// "responseDateTimeRenderOption": Determines how dates, times, and
// durations in the response should be rendered. This is ignored if
// response_value_render_option is FORMATTED_VALUE. The default dateTime
// render option is DateTimeRenderOption.SERIAL_NUMBER.
//
// Possible values:
//   "SERIAL_NUMBER" - Instructs date, time, datetime, and duration
// fields to be output as doubles in "serial number" format, as
// popularized by Lotus 1-2-3. The whole number portion of the value
// (left of the decimal) counts the days since December 30th 1899. The
// fractional portion (right of the decimal) counts the time as a
// fraction of the day. For example, January 1st 1900 at noon would be
// 2.5, 2 because it's 2 days after December 30st 1899, and .5 because
// noon is half a day. February 1st 1900 at 3pm would be 33.625. This
// correctly treats the year 1900 as not a leap year.
//   "FORMATTED_STRING" - Instructs date, time, datetime, and duration
// fields to be output as strings in their given number format (which is
// dependent on the spreadsheet locale).
func (c *SpreadsheetsValuesUpdateCall) ResponseDateTimeRenderOption(responseDateTimeRenderOption string) *SpreadsheetsValuesUpdateCall {
	c.urlParams_.Set("responseDateTimeRenderOption", responseDateTimeRenderOption)
	return c
}

// ResponseValueRenderOption sets the optional parameter
// "responseValueRenderOption": Determines how values in the response
// should be rendered. The default render option is
// ValueRenderOption.FORMATTED_VALUE.
//
// Possible values:
//   "FORMATTED_VALUE" - Values will be calculated & formatted in the
// reply according to the cell's formatting. Formatting is based on the
// spreadsheet's locale, not the requesting user's locale. For example,
// if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then
// `A2` would return "$1.23".
//   "UNFORMATTED_VALUE" - Values will be calculated, but not formatted
// in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and
// formatted as currency, then `A2` would return the number `1.23`.
//   "FORMULA" - Values will not be calculated. The reply will include
// the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and
// formatted as currency, then A2 would return "=A1".
func (c *SpreadsheetsValuesUpdateCall) ResponseValueRenderOption(responseValueRenderOption string) *SpreadsheetsValuesUpdateCall {
	c.urlParams_.Set("responseValueRenderOption", responseValueRenderOption)
	return c
}

// ValueInputOption sets the optional parameter "valueInputOption": How
// the input data should be interpreted.
//
// Possible values:
//   "INPUT_VALUE_OPTION_UNSPECIFIED" - Default input value. This value
// must not be used.
//   "RAW" - The values the user has entered will not be parsed and will
// be stored as-is.
//   "USER_ENTERED" - The values will be parsed as if the user typed
// them into the UI. Numbers will stay as numbers, but strings may be
// converted to numbers, dates, etc. following the same rules that are
// applied when entering text into a cell via the Google Sheets UI.
func (c *SpreadsheetsValuesUpdateCall) ValueInputOption(valueInputOption string) *SpreadsheetsValuesUpdateCall {
	c.urlParams_.Set("valueInputOption", valueInputOption)
	return c
}

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

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

func (c *SpreadsheetsValuesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200912")
	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.valuerange)
	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, "v4/spreadsheets/{spreadsheetId}/values/{range}")
	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{
		"spreadsheetId": c.spreadsheetId,
		"range":         c.range_,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "sheets.spreadsheets.values.update" call.
// Exactly one of *UpdateValuesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UpdateValuesResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SpreadsheetsValuesUpdateCall) Do(opts ...googleapi.CallOption) (*UpdateValuesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UpdateValuesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Sets values in a range of a spreadsheet. The caller must specify the spreadsheet ID, range, and a valueInputOption.",
	//   "flatPath": "v4/spreadsheets/{spreadsheetId}/values/{range}",
	//   "httpMethod": "PUT",
	//   "id": "sheets.spreadsheets.values.update",
	//   "parameterOrder": [
	//     "spreadsheetId",
	//     "range"
	//   ],
	//   "parameters": {
	//     "includeValuesInResponse": {
	//       "description": "Determines if the update response should include the values of the cells that were updated. By default, responses do not include the updated values. If the range to write was larger than the range actually written, the response includes all values in the requested range (excluding trailing empty rows and columns).",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "range": {
	//       "description": "The A1 notation of the values to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "responseDateTimeRenderOption": {
	//       "description": "Determines how dates, times, and durations in the response should be rendered. This is ignored if response_value_render_option is FORMATTED_VALUE. The default dateTime render option is DateTimeRenderOption.SERIAL_NUMBER.",
	//       "enum": [
	//         "SERIAL_NUMBER",
	//         "FORMATTED_STRING"
	//       ],
	//       "enumDescriptions": [
	//         "Instructs date, time, datetime, and duration fields to be output as doubles in \"serial number\" format, as popularized by Lotus 1-2-3. The whole number portion of the value (left of the decimal) counts the days since December 30th 1899. The fractional portion (right of the decimal) counts the time as a fraction of the day. For example, January 1st 1900 at noon would be 2.5, 2 because it's 2 days after December 30st 1899, and .5 because noon is half a day. February 1st 1900 at 3pm would be 33.625. This correctly treats the year 1900 as not a leap year.",
	//         "Instructs date, time, datetime, and duration fields to be output as strings in their given number format (which is dependent on the spreadsheet locale)."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "responseValueRenderOption": {
	//       "description": "Determines how values in the response should be rendered. The default render option is ValueRenderOption.FORMATTED_VALUE.",
	//       "enum": [
	//         "FORMATTED_VALUE",
	//         "UNFORMATTED_VALUE",
	//         "FORMULA"
	//       ],
	//       "enumDescriptions": [
	//         "Values will be calculated \u0026 formatted in the reply according to the cell's formatting. Formatting is based on the spreadsheet's locale, not the requesting user's locale. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then `A2` would return `\"$1.23\"`.",
	//         "Values will be calculated, but not formatted in the reply. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then `A2` would return the number `1.23`.",
	//         "Values will not be calculated. The reply will include the formulas. For example, if `A1` is `1.23` and `A2` is `=A1` and formatted as currency, then A2 would return `\"=A1\"`."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "spreadsheetId": {
	//       "description": "The ID of the spreadsheet to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "valueInputOption": {
	//       "description": "How the input data should be interpreted.",
	//       "enum": [
	//         "INPUT_VALUE_OPTION_UNSPECIFIED",
	//         "RAW",
	//         "USER_ENTERED"
	//       ],
	//       "enumDescriptions": [
	//         "Default input value. This value must not be used.",
	//         "The values the user has entered will not be parsed and will be stored as-is.",
	//         "The values will be parsed as if the user typed them into the UI. Numbers will stay as numbers, but strings may be converted to numbers, dates, etc. following the same rules that are applied when entering text into a cell via the Google Sheets UI."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v4/spreadsheets/{spreadsheetId}/values/{range}",
	//   "request": {
	//     "$ref": "ValueRange"
	//   },
	//   "response": {
	//     "$ref": "UpdateValuesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/spreadsheets"
	//   ]
	// }

}
