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

// 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))
	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)
}

// 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 {
	// Dimensions: The dimensions to automatically resize.
	Dimensions *DimensionRange `json:"dimensions,omitempty"`

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

	// NullFields is a list of field names (e.g. "Dimensions") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field 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 will be 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 will be 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 will be filled with this color and the colors
	// will
	// alternate between first_band_color and second_band_color
	// starting
	// from the second row or column. Otherwise, the first row or column
	// will be
	// filled with first_band_color and the colors will 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 will be filled with this color and the colors
	// will
	// alternate between first_band_color and second_band_color
	// starting
	// from the second row or column. Otherwise, the first row or column
	// will be
	// filled with first_band_color and the colors will 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 <a href="/chart/interactive/docs/gallery/barchart">bar
	// chart</a>.
	//   "LINE" - A <a href="/chart/interactive/docs/gallery/linechart">line
	// chart</a>.
	//   "AREA" - An <a
	// href="/chart/interactive/docs/gallery/areachart">area chart</a>.
	//   "COLUMN" - A <a
	// href="/chart/interactive/docs/gallery/columnchart">column chart</a>.
	//   "SCATTER" - A <a
	// href="/chart/interactive/docs/gallery/scatterchart">scatter
	// chart</a>.
	//   "COMBO" - A <a
	// href="/chart/interactive/docs/gallery/combochart">combo chart</a>.
	//   "STEPPED_AREA" - A <a
	// href="/chart/interactive/docs/gallery/steppedareachart">stepped
	// area
	// chart</a>.
	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 <a href="/chart/interactive/docs/gallery/barchart">bar
	// chart</a>.
	//   "LINE" - A <a href="/chart/interactive/docs/gallery/linechart">line
	// chart</a>.
	//   "AREA" - An <a
	// href="/chart/interactive/docs/gallery/areachart">area chart</a>.
	//   "COLUMN" - A <a
	// href="/chart/interactive/docs/gallery/columnchart">column chart</a>.
	//   "SCATTER" - A <a
	// href="/chart/interactive/docs/gallery/scatterchart">scatter
	// chart</a>.
	//   "COMBO" - A <a
	// href="/chart/interactive/docs/gallery/combochart">combo chart</a>.
	//   "STEPPED_AREA" - A <a
	// href="/chart/interactive/docs/gallery/steppedareachart">stepped
	// area
	// chart</a>.
	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"`

	// 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
	// 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_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)
}

// 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".
	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 <a
// href="/chart/interactive/docs/gallery/bubblechart">bubble chart</a>.
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 <a
// href="/chart/interactive/docs/gallery/candlestickchart">candlestick
// ch
// art</a>.
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 {
	// 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. "DataValidation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DataValidation") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field 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 {
	// SourceRange: The source ranges of the data.
	SourceRange *ChartSourceRange `json:"sourceRange,omitempty"`

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

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

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

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

	// 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.
//
// 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)
}

// 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)
}

// 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)
}

// 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 {
	// 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. "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 *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
	}
	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 all other filter criteria. Requests to
	// set
	// this field will fail with a 400 error if any other filter criteria
	// field is
	// set.
	VisibleBackgroundColor *Color `json:"visibleBackgroundColor,omitempty"`

	// VisibleBackgroundColorStyle: The background fill color to filter by;
	// only cells with this fill color are
	// shown. Mutually exclusive with all other filter criteria. Requests to
	// set
	// this field will fail with a 400 error if any other filter criteria
	// field is
	// set.
	// If visible_background_color is also set, this field takes precedence.
	VisibleBackgroundColorStyle *ColorStyle `json:"visibleBackgroundColorStyle,omitempty"`

	// VisibleForegroundColor: The text color to filter by; only cells with
	// this text color are shown.
	// Mutually exclusive with all other filter criteria. Requests to set
	// this
	// field will fail with a 400 error if any other filter criteria field
	// is set.
	VisibleForegroundColor *Color `json:"visibleForegroundColor,omitempty"`

	// VisibleForegroundColorStyle: The text color to filter by; only cells
	// with this text color are shown.
	// Mutually exclusive with all other filter criteria. Requests to set
	// this
	// field will fail with a 400 error if any other filter criteria field
	// is set.
	// 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)
}

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

	// 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, e.g 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 <a
// href="/chart/interactive/docs/gallery/histogram">histogram
// chart</a>.
// 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)
}

// 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 <a
// href="/chart/interactive/docs/gallery/orgchart">org chart</a>.
// 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 <a
// href="/chart/interactive/docs/gallery/piechart">pie chart</a>.
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)
}

// PivotGroup: A single grouping (either row or column) in a pivot
// table.
type PivotGroup struct {
	// 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. "GroupRule") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

	// 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 UI, 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"`

	// 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)
}

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

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

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

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

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

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

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

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

	// NullFields is a list of field names (e.g. "GridProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field 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. Mutually
	// exclusive with sorting by
	// text color. Requests to set this field will fail with a 400 error
	// if
	// foreground color is also set.
	BackgroundColor *Color `json:"backgroundColor,omitempty"`

	// BackgroundColorStyle: The background fill color to sort by. Mutually
	// exclusive with sorting by
	// text color. Requests to set this field will fail with a 400 error
	// if
	// foreground color is also set.
	// If background_color is also set, this field takes precedence.
	BackgroundColorStyle *ColorStyle `json:"backgroundColorStyle,omitempty"`

	// DimensionIndex: The dimension the sort should be applied to.
	DimensionIndex int64 `json:"dimensionIndex,omitempty"`

	// ForegroundColor: The text color to sort by. Mutually exclusive with
	// sorting by background
	// fill color. Requests to set this field will fail with a 400 error
	// if
	// background color is also set.
	ForegroundColor *Color `json:"foregroundColor,omitempty"`

	// ForegroundColorStyle: The text color to sort by. Mutually exclusive
	// with sorting by background
	// fill color. Requests to set this field will fail with a 400 error
	// if
	// background color is also set.
	// 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 {
	// 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. "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 *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)
}

// 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 <a
// href="/chart/interactive/docs/gallery/treemap">Treemap chart</a>.
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)
}

// 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 {
	// 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. "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 *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/1.11.0 gdcl/20200214")
	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.\n\nEach request is validated before\nbeing applied. If any request is not valid then the entire request will\nfail and nothing will be applied.\n\nSome requests have replies to\ngive you some information about how\nthey are applied. The replies will mirror the requests.  For example,\nif you applied 4 updates and the 3rd one had a reply, then the\nresponse will have 2 empty replies, the actual reply, and another empty\nreply, in that order.\n\nDue to the collaborative nature of spreadsheets, it is not guaranteed that\nthe spreadsheet will reflect exactly your changes after this completes,\nhowever it is guaranteed that the updates in the request will be\napplied together atomically. Your changes may be altered with respect to\ncollaborator changes. If there are no collaborators, the spreadsheet\nshould 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/1.11.0 gdcl/20200214")
	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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID.\n\nBy default, data within grids will not be returned.\nYou can include grid data one of two ways:\n\n* Specify a field mask listing your desired fields using the `fields` URL\nparameter in HTTP\n\n* Set the includeGridData\nURL parameter to true.  If a field mask is set, the `includeGridData`\nparameter is ignored\n\nFor large spreadsheets, it is recommended to retrieve only the specific\nfields of the spreadsheet that you want.\n\nTo retrieve only subsets of the spreadsheet, use the\nranges URL parameter.\nMultiple ranges can be specified.  Limiting the range will\nreturn only the portions of the spreadsheet that intersect the requested\nranges. 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.\nThis 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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID.\n\nThis method differs from GetSpreadsheet in that it allows selecting\nwhich subsets of spreadsheet data to return by specifying a\ndataFilters parameter.\nMultiple DataFilters can be specified.  Specifying one or\nmore data filters will return the portions of the spreadsheet that\nintersect ranges matched by any of the filters.\n\nBy default, data within grids will not be returned.\nYou can include grid data one of two ways:\n\n* Specify a field mask listing your desired fields using the `fields` URL\nparameter in HTTP\n\n* Set the includeGridData\nparameter to true.  If a field mask is set, the `includeGridData`\nparameter is ignored\n\nFor large spreadsheets, it is recommended to retrieve only the specific\nfields 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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID and the developer metadata's\nunique 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/1.11.0 gdcl/20200214")
	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.\nIf the provided DataFilter represents a DeveloperMetadataLookup object,\nthis will return all DeveloperMetadata entries selected by it. If the\nDataFilter represents a location in a spreadsheet, this will return all\ndeveloper 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/1.11.0 gdcl/20200214")
	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.\nReturns 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"
//   "INSERT_ROWS"
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"
//   "FORMATTED_STRING"
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"
//   "UNFORMATTED_VALUE"
//   "FORMULA"
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"
//   "RAW"
//   "USER_ENTERED"
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/1.11.0 gdcl/20200214")
	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\nexisting data and find a \"table\" within that range. Values will be\nappended to the next row of the table, starting with the first column of\nthe table. See the\n[guide](/sheets/api/guides/values#appending_values)\nand\n[sample code](/sheets/api/samples/writing#append_values)\nfor specific details of how tables are detected and data is appended.\n\nThe caller must specify the spreadsheet ID, range, and\na valueInputOption.  The `valueInputOption` only\ncontrols how the input data will be added to the sheet (column-wise or\nrow-wise), it does not influence what cell the data starts being written\nto.",
	//   "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\nof the cells that were appended. By default, responses\ndo not include the updated values.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "insertDataOption": {
	//       "description": "How the input data should be inserted.",
	//       "enum": [
	//         "OVERWRITE",
	//         "INSERT_ROWS"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "range": {
	//       "description": "The A1 notation of a range to search for a logical table of data.\nValues 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\nrendered. This is ignored if response_value_render_option is\nFORMATTED_VALUE.\nThe default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER].",
	//       "enum": [
	//         "SERIAL_NUMBER",
	//         "FORMATTED_STRING"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "responseValueRenderOption": {
	//       "description": "Determines how values in the response should be rendered.\nThe default render option is ValueRenderOption.FORMATTED_VALUE.",
	//       "enum": [
	//         "FORMATTED_VALUE",
	//         "UNFORMATTED_VALUE",
	//         "FORMULA"
	//       ],
	//       "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"
	//       ],
	//       "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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID and one or more ranges.\nOnly values are cleared -- all other properties of the cell (such as\nformatting, 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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID and one or more\nDataFilters. Ranges matching any of the specified data\nfilters will be cleared.  Only values are cleared -- all other properties\nof 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"
//   "FORMATTED_STRING"
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"
//   "ROWS"
//   "COLUMNS"
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"
//   "UNFORMATTED_VALUE"
//   "FORMULA"
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/1.11.0 gdcl/20200214")
	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.\nThe 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.\nThis is ignored if value_render_option is\nFORMATTED_VALUE.\nThe default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER].",
	//       "enum": [
	//         "SERIAL_NUMBER",
	//         "FORMATTED_STRING"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "majorDimension": {
	//       "description": "The major dimension that results should use.\n\nFor example, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`,\nthen requesting `range=A1:B2,majorDimension=ROWS` returns `[[1,2],[3,4]]`,\nwhereas requesting `range=A1:B2,majorDimension=COLUMNS` returns\n`[[1,3],[2,4]]`.",
	//       "enum": [
	//         "DIMENSION_UNSPECIFIED",
	//         "ROWS",
	//         "COLUMNS"
	//       ],
	//       "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.\nThe default render option is ValueRenderOption.FORMATTED_VALUE.",
	//       "enum": [
	//         "FORMATTED_VALUE",
	//         "UNFORMATTED_VALUE",
	//         "FORMULA"
	//       ],
	//       "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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID and one or more\nDataFilters.  Ranges that match any of the data filters in\nthe 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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID,\na valueInputOption, and one or more\nValueRanges.",
	//   "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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID,\na valueInputOption, and one or more\nDataFilterValueRanges.",
	//   "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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID and range.\nOnly values are cleared -- all other properties of the cell (such as\nformatting, 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"
//   "FORMATTED_STRING"
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"
//   "ROWS"
//   "COLUMNS"
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"
//   "UNFORMATTED_VALUE"
//   "FORMULA"
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/1.11.0 gdcl/20200214")
	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.\nThe 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.\nThis is ignored if value_render_option is\nFORMATTED_VALUE.\nThe default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER].",
	//       "enum": [
	//         "SERIAL_NUMBER",
	//         "FORMATTED_STRING"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "majorDimension": {
	//       "description": "The major dimension that results should use.\n\nFor example, if the spreadsheet data is: `A1=1,B1=2,A2=3,B2=4`, then\nrequesting `range=A1:B2,majorDimension=ROWS` returns `[[1,2],[3,4]]`,\nwhereas requesting `range=A1:B2,majorDimension=COLUMNS` returns\n`[[1,3],[2,4]]`.",
	//       "enum": [
	//         "DIMENSION_UNSPECIFIED",
	//         "ROWS",
	//         "COLUMNS"
	//       ],
	//       "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.\nThe default render option is ValueRenderOption.FORMATTED_VALUE.",
	//       "enum": [
	//         "FORMATTED_VALUE",
	//         "UNFORMATTED_VALUE",
	//         "FORMULA"
	//       ],
	//       "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"
//   "FORMATTED_STRING"
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"
//   "UNFORMATTED_VALUE"
//   "FORMULA"
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"
//   "RAW"
//   "USER_ENTERED"
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/1.11.0 gdcl/20200214")
	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.\nThe caller must specify the spreadsheet ID, range, and\na 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\nof the cells that were updated. By default, responses\ndo not include the updated values.\nIf the range to write was larger than the range actually written, the\nresponse includes all values in the requested range (excluding trailing\nempty 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\nrendered. This is ignored if response_value_render_option is\nFORMATTED_VALUE.\nThe default dateTime render option is\nDateTimeRenderOption.SERIAL_NUMBER.",
	//       "enum": [
	//         "SERIAL_NUMBER",
	//         "FORMATTED_STRING"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "responseValueRenderOption": {
	//       "description": "Determines how values in the response should be rendered.\nThe default render option is ValueRenderOption.FORMATTED_VALUE.",
	//       "enum": [
	//         "FORMATTED_VALUE",
	//         "UNFORMATTED_VALUE",
	//         "FORMULA"
	//       ],
	//       "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"
	//       ],
	//       "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"
	//   ]
	// }

}
