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

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

	googleapi "google.golang.org/api/googleapi"
	internal "google.golang.org/api/internal"
	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 = "docs:v1"
const apiName = "docs"
const apiVersion = "v1"
const basePath = "https://docs.googleapis.com/"
const mtlsBasePath = "https://docs.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See, edit, create, and delete all your Google Docs documents
	DocumentsScope = "https://www.googleapis.com/auth/documents"

	// See all your Google Docs documents
	DocumentsReadonlyScope = "https://www.googleapis.com/auth/documents.readonly"

	// See, edit, create, and delete all of your Google Drive files
	DriveScope = "https://www.googleapis.com/auth/drive"

	// See, edit, create, and delete only the specific Google Drive files
	// you use 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"
)

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

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Documents = NewDocumentsService(s)
	return s, nil
}

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

	Documents *DocumentsService
}

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

func NewDocumentsService(s *Service) *DocumentsService {
	rs := &DocumentsService{s: s}
	return rs
}

type DocumentsService struct {
	s *Service
}

// AutoText: A ParagraphElement representing a spot in the text that is
// dynamically replaced with content that can change over time, like a
// page number.
type AutoText struct {
	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. An AutoText may
	// have multiple insertion IDs if it is a nested suggested change. If
	// empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// AutoText, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this AutoText.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

	// Type: The type of this auto text.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - An unspecified auto text type.
	//   "PAGE_NUMBER" - Type for auto text that represents the current page
	// number.
	//   "PAGE_COUNT" - Type for auto text that represents the total number
	// of pages in the document.
	Type string `json:"type,omitempty"`

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

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

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

// Background: Represents the background of a document.
type Background struct {
	// Color: The background color.
	Color *OptionalColor `json:"color,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Color") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *Background) MarshalJSON() ([]byte, error) {
	type NoMethod Background
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BackgroundSuggestionState: A mask that indicates which of the fields
// on the base Background have been changed in this suggestion. For any
// field set to true, the Backgound has a new suggested value.
type BackgroundSuggestionState struct {
	// BackgroundColorSuggested: Indicates whether the current background
	// color has been modified in this suggestion.
	BackgroundColorSuggested bool `json:"backgroundColorSuggested,omitempty"`

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

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

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

// BatchUpdateDocumentRequest: Request message for BatchUpdateDocument.
type BatchUpdateDocumentRequest struct {
	// Requests: A list of updates to apply to the document.
	Requests []*Request `json:"requests,omitempty"`

	// WriteControl: Provides control over how write requests are executed.
	WriteControl *WriteControl `json:"writeControl,omitempty"`

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

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

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

// BatchUpdateDocumentResponse: Response message from a
// BatchUpdateDocument request.
type BatchUpdateDocumentResponse struct {
	// DocumentId: The ID of the document to which the updates were applied
	// to.
	DocumentId string `json:"documentId,omitempty"`

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

	// WriteControl: The updated write control after applying the request.
	WriteControl *WriteControl `json:"writeControl,omitempty"`

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

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

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

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

// Body: The document body. The body typically contains the full
// document contents except for headers, footers and footnotes.
type Body struct {
	// Content: The contents of the body. The indexes for the body's content
	// begin at zero.
	Content []*StructuralElement `json:"content,omitempty"`

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

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

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

// Bullet: Describes the bullet of a paragraph.
type Bullet struct {
	// ListId: The ID of the list this paragraph belongs to.
	ListId string `json:"listId,omitempty"`

	// NestingLevel: The nesting level of this paragraph in the list.
	NestingLevel int64 `json:"nestingLevel,omitempty"`

	// TextStyle: The paragraph specific text style applied to this bullet.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// BulletSuggestionState: A mask that indicates which of the fields on
// the base Bullet have been changed in this suggestion. For any field
// set to true, there is a new suggested value.
type BulletSuggestionState struct {
	// ListIdSuggested: Indicates if there was a suggested change to the
	// list_id.
	ListIdSuggested bool `json:"listIdSuggested,omitempty"`

	// NestingLevelSuggested: Indicates if there was a suggested change to
	// the nesting_level.
	NestingLevelSuggested bool `json:"nestingLevelSuggested,omitempty"`

	// TextStyleSuggestionState: A mask that indicates which of the fields
	// in text style have been changed in this suggestion.
	TextStyleSuggestionState *TextStyleSuggestionState `json:"textStyleSuggestionState,omitempty"`

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

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

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

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

	// ForceSendFields is a list of field names (e.g. "RgbColor") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *Color) MarshalJSON() ([]byte, error) {
	type NoMethod Color
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ColumnBreak: A ParagraphElement representing a column break. A column
// break makes the subsequent text start at the top of the next column.
type ColumnBreak struct {
	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A ColumnBreak may
	// have multiple insertion IDs if it is a nested suggested change. If
	// empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// ColumnBreak, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this ColumnBreak. Similar to text
	// content, like text runs and footnote references, the text style of a
	// column break can affect content layout as well as the styling of text
	// inserted adjacent to it.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// CreateFooterRequest: Creates a Footer. The new footer is applied to
// the SectionStyle at the location of the SectionBreak if specified,
// otherwise it is applied to the DocumentStyle. If a footer of the
// specified type already exists, a 400 bad request error is returned.
type CreateFooterRequest struct {
	// SectionBreakLocation: The location of the SectionBreak immediately
	// preceding the section whose SectionStyle this footer should belong
	// to. If this is unset or refers to the first section break in the
	// document, the footer applies to the document style.
	SectionBreakLocation *Location `json:"sectionBreakLocation,omitempty"`

	// Type: The type of footer to create.
	//
	// Possible values:
	//   "HEADER_FOOTER_TYPE_UNSPECIFIED" - The header/footer type is
	// unspecified.
	//   "DEFAULT" - A default header/footer.
	Type string `json:"type,omitempty"`

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

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

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

// CreateFooterResponse: The result of creating a footer.
type CreateFooterResponse struct {
	// FooterId: The ID of the created footer.
	FooterId string `json:"footerId,omitempty"`

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

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

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

// CreateFootnoteRequest: Creates a Footnote segment and inserts a new
// FootnoteReference to it at the given location. The new Footnote
// segment will contain a space followed by a newline character.
type CreateFootnoteRequest struct {
	// EndOfSegmentLocation: Inserts the footnote reference at the end of
	// the document body. Footnote references cannot be inserted inside a
	// header, footer or footnote. Since footnote references can only be
	// inserted in the body, the segment ID field must be empty.
	EndOfSegmentLocation *EndOfSegmentLocation `json:"endOfSegmentLocation,omitempty"`

	// Location: Inserts the footnote reference at a specific index in the
	// document. The footnote reference must be inserted inside the bounds
	// of an existing Paragraph. For instance, it cannot be inserted at a
	// table's start index (i.e. between the table and its preceding
	// paragraph). Footnote references cannot be inserted inside an
	// equation, header, footer or footnote. Since footnote references can
	// only be inserted in the body, the segment ID field must be empty.
	Location *Location `json:"location,omitempty"`

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

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

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

// CreateFootnoteResponse: The result of creating a footnote.
type CreateFootnoteResponse struct {
	// FootnoteId: The ID of the created footnote.
	FootnoteId string `json:"footnoteId,omitempty"`

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

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

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

// CreateHeaderRequest: Creates a Header. The new header is applied to
// the SectionStyle at the location of the SectionBreak if specified,
// otherwise it is applied to the DocumentStyle. If a header of the
// specified type already exists, a 400 bad request error is returned.
type CreateHeaderRequest struct {
	// SectionBreakLocation: The location of the SectionBreak which begins
	// the section this header should belong to. If `section_break_location'
	// is unset or if it refers to the first section break in the document
	// body, the header applies to the DocumentStyle
	SectionBreakLocation *Location `json:"sectionBreakLocation,omitempty"`

	// Type: The type of header to create.
	//
	// Possible values:
	//   "HEADER_FOOTER_TYPE_UNSPECIFIED" - The header/footer type is
	// unspecified.
	//   "DEFAULT" - A default header/footer.
	Type string `json:"type,omitempty"`

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

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

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

// CreateHeaderResponse: The result of creating a header.
type CreateHeaderResponse struct {
	// HeaderId: The ID of the created header.
	HeaderId string `json:"headerId,omitempty"`

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

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

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

// CreateNamedRangeRequest: Creates a NamedRange referencing the given
// range.
type CreateNamedRangeRequest struct {
	// Name: The name of the NamedRange. Names do not need to be unique.
	// Names must be at least 1 character and no more than 256 characters,
	// measured in UTF-16 code units.
	Name string `json:"name,omitempty"`

	// Range: The range to apply the name to.
	Range *Range `json:"range,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *CreateNamedRangeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateNamedRangeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateNamedRangeResponse: The result of creating a named range.
type CreateNamedRangeResponse struct {
	// NamedRangeId: The ID of the created named range.
	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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *CreateNamedRangeResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateNamedRangeResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateParagraphBulletsRequest: Creates bullets for all of the
// paragraphs that overlap with the given range. The nesting level of
// each paragraph will be determined by counting leading tabs in front
// of each paragraph. To avoid excess space between the bullet and the
// corresponding paragraph, these leading tabs are removed by this
// request. This may change the indices of parts of the text. If the
// paragraph immediately before paragraphs being updated is in a list
// with a matching preset, the paragraphs being updated are added to
// that preceding list.
type CreateParagraphBulletsRequest struct {
	// BulletPreset: The kinds of bullet glyphs to be used.
	//
	// Possible values:
	//   "BULLET_GLYPH_PRESET_UNSPECIFIED" - The bullet glyph preset is
	// unspecified.
	//   "BULLET_DISC_CIRCLE_SQUARE" - A bulleted list with a `DISC`,
	// `CIRCLE` and `SQUARE` bullet glyph for the first 3 list nesting
	// levels.
	//   "BULLET_DIAMONDX_ARROW3D_SQUARE" - A bulleted list with a
	// `DIAMONDX`, `ARROW3D` and `SQUARE` bullet glyph for the first 3 list
	// nesting levels.
	//   "BULLET_CHECKBOX" - A bulleted list with `CHECKBOX` bullet glyphs
	// for all list nesting levels.
	//   "BULLET_ARROW_DIAMOND_DISC" - A bulleted list with a `ARROW`,
	// `DIAMOND` and `DISC` bullet glyph for the first 3 list nesting
	// levels.
	//   "BULLET_STAR_CIRCLE_SQUARE" - A bulleted list with a `STAR`,
	// `CIRCLE` and `SQUARE` bullet glyph for the first 3 list nesting
	// levels.
	//   "BULLET_ARROW3D_CIRCLE_SQUARE" - A bulleted list with a `ARROW3D`,
	// `CIRCLE` and `SQUARE` bullet glyph for the first 3 list nesting
	// levels.
	//   "BULLET_LEFTTRIANGLE_DIAMOND_DISC" - A bulleted list with a
	// `LEFTTRIANGLE`, `DIAMOND` and `DISC` bullet glyph for the first 3
	// list nesting levels.
	//   "BULLET_DIAMONDX_HOLLOWDIAMOND_SQUARE" - A bulleted list with a
	// `DIAMONDX`, `HOLLOWDIAMOND` and `SQUARE` bullet glyph for the first 3
	// list nesting levels.
	//   "BULLET_DIAMOND_CIRCLE_SQUARE" - A bulleted list with a `DIAMOND`,
	// `CIRCLE` and `SQUARE` bullet glyph for the first 3 list nesting
	// levels.
	//   "NUMBERED_DECIMAL_ALPHA_ROMAN" - A numbered list with `DECIMAL`,
	// `ALPHA` and `ROMAN` numeric glyphs for the first 3 list nesting
	// levels, followed by periods.
	//   "NUMBERED_DECIMAL_ALPHA_ROMAN_PARENS" - A numbered list with
	// `DECIMAL`, `ALPHA` and `ROMAN` numeric glyphs for the first 3 list
	// nesting levels, followed by parenthesis.
	//   "NUMBERED_DECIMAL_NESTED" - A numbered list with `DECIMAL` numeric
	// glyphs separated by periods, where each nesting level uses the
	// previous nesting level's glyph as a prefix. For example: '1.',
	// '1.1.', '2.', '2.2.'.
	//   "NUMBERED_UPPERALPHA_ALPHA_ROMAN" - A numbered list with
	// `UPPERALPHA`, `ALPHA` and `ROMAN` numeric glyphs for the first 3 list
	// nesting levels, followed by periods.
	//   "NUMBERED_UPPERROMAN_UPPERALPHA_DECIMAL" - A numbered list with
	// `UPPERROMAN`, `UPPERALPHA` and `DECIMAL` numeric glyphs for the first
	// 3 list nesting levels, followed by periods.
	//   "NUMBERED_ZERODECIMAL_ALPHA_ROMAN" - A numbered list with
	// `ZERODECIMAL`, `ALPHA` and `ROMAN` numeric glyphs for the first 3
	// list nesting levels, followed by periods.
	BulletPreset string `json:"bulletPreset,omitempty"`

	// Range: The range to apply the bullet preset to.
	Range *Range `json:"range,omitempty"`

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

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

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

// CropProperties: The crop properties of an image. The crop rectangle
// is represented using fractional offsets from the original content's
// four edges. - If the offset is in the interval (0, 1), the
// corresponding edge of crop rectangle is positioned inside of the
// image's original bounding rectangle. - If the offset is negative or
// greater than 1, the corresponding edge of crop rectangle is
// positioned outside of the image's original bounding rectangle. - If
// all offsets and rotation angle are 0, the image is not cropped.
type CropProperties struct {
	// Angle: The clockwise rotation angle of the crop rectangle around its
	// center, in radians. Rotation is applied after the offsets.
	Angle float64 `json:"angle,omitempty"`

	// OffsetBottom: The offset specifies how far inwards the bottom edge of
	// the crop rectangle is from the bottom edge of the original content as
	// a fraction of the original content's height.
	OffsetBottom float64 `json:"offsetBottom,omitempty"`

	// OffsetLeft: The offset specifies how far inwards the left edge of the
	// crop rectangle is from the left edge of the original content as a
	// fraction of the original content's width.
	OffsetLeft float64 `json:"offsetLeft,omitempty"`

	// OffsetRight: The offset specifies how far inwards the right edge of
	// the crop rectangle is from the right edge of the original content as
	// a fraction of the original content's width.
	OffsetRight float64 `json:"offsetRight,omitempty"`

	// OffsetTop: The offset specifies how far inwards the top edge of the
	// crop rectangle is from the top edge of the original content as a
	// fraction of the original content's height.
	OffsetTop float64 `json:"offsetTop,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Angle") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *CropProperties) MarshalJSON() ([]byte, error) {
	type NoMethod CropProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *CropProperties) UnmarshalJSON(data []byte) error {
	type NoMethod CropProperties
	var s1 struct {
		Angle        gensupport.JSONFloat64 `json:"angle"`
		OffsetBottom gensupport.JSONFloat64 `json:"offsetBottom"`
		OffsetLeft   gensupport.JSONFloat64 `json:"offsetLeft"`
		OffsetRight  gensupport.JSONFloat64 `json:"offsetRight"`
		OffsetTop    gensupport.JSONFloat64 `json:"offsetTop"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Angle = float64(s1.Angle)
	s.OffsetBottom = float64(s1.OffsetBottom)
	s.OffsetLeft = float64(s1.OffsetLeft)
	s.OffsetRight = float64(s1.OffsetRight)
	s.OffsetTop = float64(s1.OffsetTop)
	return nil
}

// CropPropertiesSuggestionState: A mask that indicates which of the
// fields on the base CropProperties have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type CropPropertiesSuggestionState struct {
	// AngleSuggested: Indicates if there was a suggested change to angle.
	AngleSuggested bool `json:"angleSuggested,omitempty"`

	// OffsetBottomSuggested: Indicates if there was a suggested change to
	// offset_bottom.
	OffsetBottomSuggested bool `json:"offsetBottomSuggested,omitempty"`

	// OffsetLeftSuggested: Indicates if there was a suggested change to
	// offset_left.
	OffsetLeftSuggested bool `json:"offsetLeftSuggested,omitempty"`

	// OffsetRightSuggested: Indicates if there was a suggested change to
	// offset_right.
	OffsetRightSuggested bool `json:"offsetRightSuggested,omitempty"`

	// OffsetTopSuggested: Indicates if there was a suggested change to
	// offset_top.
	OffsetTopSuggested bool `json:"offsetTopSuggested,omitempty"`

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

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

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

// DeleteContentRangeRequest: Deletes content from the document.
type DeleteContentRangeRequest struct {
	// Range: The range of content to delete. Deleting text that crosses a
	// paragraph boundary may result in changes to paragraph styles, lists,
	// positioned objects and bookmarks as the two paragraphs are merged.
	// Attempting to delete certain ranges can result in an invalid document
	// structure in which case a 400 bad request error is returned. Some
	// examples of invalid delete requests include: * Deleting one code unit
	// of a surrogate pair. * Deleting the last newline character of a Body,
	// Header, Footer, Footnote, TableCell or TableOfContents. * Deleting
	// the start or end of a Table, TableOfContents or Equation without
	// deleting the entire element. * Deleting the newline character before
	// a Table, TableOfContents or SectionBreak without deleting the
	// element. * Deleting individual rows or cells of a table. Deleting the
	// content within a table cell is allowed.
	Range *Range `json:"range,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Range") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *DeleteContentRangeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteContentRangeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteFooterRequest: Deletes a Footer from the document.
type DeleteFooterRequest struct {
	// FooterId: The id of the footer to delete. If this footer is defined
	// on DocumentStyle, the reference to this footer is removed, resulting
	// in no footer of that type for the first section of the document. If
	// this footer is defined on a SectionStyle, the reference to this
	// footer is removed and the footer of that type is now continued from
	// the previous section.
	FooterId string `json:"footerId,omitempty"`

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

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

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

// DeleteHeaderRequest: Deletes a Header from the document.
type DeleteHeaderRequest struct {
	// HeaderId: The id of the header to delete. If this header is defined
	// on DocumentStyle, the reference to this header is removed, resulting
	// in no header of that type for the first section of the document. If
	// this header is defined on a SectionStyle, the reference to this
	// header is removed and the header of that type is now continued from
	// the previous section.
	HeaderId string `json:"headerId,omitempty"`

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

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

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

// DeleteNamedRangeRequest: Deletes a NamedRange.
type DeleteNamedRangeRequest struct {
	// Name: The name of the range(s) to delete. All named ranges with the
	// given name will be deleted.
	Name string `json:"name,omitempty"`

	// NamedRangeId: The ID of the named range to delete.
	NamedRangeId string `json:"namedRangeId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *DeleteNamedRangeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteNamedRangeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteParagraphBulletsRequest: Deletes bullets from all of the
// paragraphs that overlap with the given range. The nesting level of
// each paragraph will be visually preserved by adding indent to the
// start of the corresponding paragraph.
type DeleteParagraphBulletsRequest struct {
	// Range: The range to delete bullets from.
	Range *Range `json:"range,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Range") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *DeleteParagraphBulletsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteParagraphBulletsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeletePositionedObjectRequest: Deletes a PositionedObject from the
// document.
type DeletePositionedObjectRequest struct {
	// ObjectId: The ID of the positioned object to delete.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *DeletePositionedObjectRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeletePositionedObjectRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteTableColumnRequest: Deletes a column from a table.
type DeleteTableColumnRequest struct {
	// TableCellLocation: The reference table cell location from which the
	// column will be deleted. The column this cell spans will be deleted.
	// If this is a merged cell that spans multiple columns, all columns
	// that the cell spans will be deleted. If no columns remain in the
	// table after this deletion, the whole table is deleted.
	TableCellLocation *TableCellLocation `json:"tableCellLocation,omitempty"`

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

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

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

// DeleteTableRowRequest: Deletes a row from a table.
type DeleteTableRowRequest struct {
	// TableCellLocation: The reference table cell location from which the
	// row will be deleted. The row this cell spans will be deleted. If this
	// is a merged cell that spans multiple rows, all rows that the cell
	// spans will be deleted. If no rows remain in the table after this
	// deletion, the whole table is deleted.
	TableCellLocation *TableCellLocation `json:"tableCellLocation,omitempty"`

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

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

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

// Dimension: A magnitude in a single direction in the specified units.
type Dimension struct {
	// Magnitude: The magnitude.
	Magnitude float64 `json:"magnitude,omitempty"`

	// Unit: The units for magnitude.
	//
	// Possible values:
	//   "UNIT_UNSPECIFIED" - The units are unknown.
	//   "PT" - A point, 1/72 of an inch.
	Unit string `json:"unit,omitempty"`

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

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

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

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

// Document: A Google Docs document.
type Document struct {
	// Body: Output only. The main body of the document.
	Body *Body `json:"body,omitempty"`

	// DocumentId: Output only. The ID of the document.
	DocumentId string `json:"documentId,omitempty"`

	// DocumentStyle: Output only. The style of the document.
	DocumentStyle *DocumentStyle `json:"documentStyle,omitempty"`

	// Footers: Output only. The footers in the document, keyed by footer
	// ID.
	Footers map[string]Footer `json:"footers,omitempty"`

	// Footnotes: Output only. The footnotes in the document, keyed by
	// footnote ID.
	Footnotes map[string]Footnote `json:"footnotes,omitempty"`

	// Headers: Output only. The headers in the document, keyed by header
	// ID.
	Headers map[string]Header `json:"headers,omitempty"`

	// InlineObjects: Output only. The inline objects in the document, keyed
	// by object ID.
	InlineObjects map[string]InlineObject `json:"inlineObjects,omitempty"`

	// Lists: Output only. The lists in the document, keyed by list ID.
	Lists map[string]List `json:"lists,omitempty"`

	// NamedRanges: Output only. The named ranges in the document, keyed by
	// name.
	NamedRanges map[string]NamedRanges `json:"namedRanges,omitempty"`

	// NamedStyles: Output only. The named styles of the document.
	NamedStyles *NamedStyles `json:"namedStyles,omitempty"`

	// PositionedObjects: Output only. The positioned objects in the
	// document, keyed by object ID.
	PositionedObjects map[string]PositionedObject `json:"positionedObjects,omitempty"`

	// RevisionId: Output only. The revision ID of the document. Can be used
	// in update requests to specify which revision of a document to apply
	// updates to and how the request should behave if the document has been
	// edited since that revision. Only populated if the user has edit
	// access to the document. The revision ID is not a sequential number
	// but an opaque string. The format of the revision ID might change over
	// time. A returned revision ID is only guaranteed to be valid for 24
	// hours after it has been returned and cannot be shared across users.
	// If the revision ID is unchanged between calls, then the document has
	// not changed. Conversely, a changed ID (for the same document and
	// user) usually means the document has been updated. However, a changed
	// ID can also be due to internal factors such as ID format changes.
	RevisionId string `json:"revisionId,omitempty"`

	// SuggestedDocumentStyleChanges: Output only. The suggested changes to
	// the style of the document, keyed by suggestion ID.
	SuggestedDocumentStyleChanges map[string]SuggestedDocumentStyle `json:"suggestedDocumentStyleChanges,omitempty"`

	// SuggestedNamedStylesChanges: Output only. The suggested changes to
	// the named styles of the document, keyed by suggestion ID.
	SuggestedNamedStylesChanges map[string]SuggestedNamedStyles `json:"suggestedNamedStylesChanges,omitempty"`

	// SuggestionsViewMode: Output only. The suggestions view mode applied
	// to the document. Note: When editing a document, changes must be based
	// on a document with SUGGESTIONS_INLINE.
	//
	// Possible values:
	//   "DEFAULT_FOR_CURRENT_ACCESS" - The SuggestionsViewMode applied to
	// the returned document depends on the user's current access level. If
	// the user only has view access, PREVIEW_WITHOUT_SUGGESTIONS is
	// applied. Otherwise, SUGGESTIONS_INLINE is applied. This is the
	// default suggestions view mode.
	//   "SUGGESTIONS_INLINE" - The returned document has suggestions
	// inline. Suggested changes will be differentiated from base content
	// within the document. Requests to retrieve a document using this mode
	// will return a 403 error if the user does not have permission to view
	// suggested changes.
	//   "PREVIEW_SUGGESTIONS_ACCEPTED" - The returned document is a preview
	// with all suggested changes accepted. Requests to retrieve a document
	// using this mode will return a 403 error if the user does not have
	// permission to view suggested changes.
	//   "PREVIEW_WITHOUT_SUGGESTIONS" - The returned document is a preview
	// with all suggested changes rejected if there are any suggestions in
	// the document.
	SuggestionsViewMode string `json:"suggestionsViewMode,omitempty"`

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

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

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

// DocumentStyle: The style of the document.
type DocumentStyle struct {
	// Background: The background of the document. Documents cannot have a
	// transparent background color.
	Background *Background `json:"background,omitempty"`

	// DefaultFooterId: The ID of the default footer. If not set, there is
	// no default footer. This property is read-only.
	DefaultFooterId string `json:"defaultFooterId,omitempty"`

	// DefaultHeaderId: The ID of the default header. If not set, there is
	// no default header. This property is read-only.
	DefaultHeaderId string `json:"defaultHeaderId,omitempty"`

	// EvenPageFooterId: The ID of the footer used only for even pages. The
	// value of use_even_page_header_footer determines whether to use the
	// default_footer_id or this value for the footer on even pages. If not
	// set, there is no even page footer. This property is read-only.
	EvenPageFooterId string `json:"evenPageFooterId,omitempty"`

	// EvenPageHeaderId: The ID of the header used only for even pages. The
	// value of use_even_page_header_footer determines whether to use the
	// default_header_id or this value for the header on even pages. If not
	// set, there is no even page header. This property is read-only.
	EvenPageHeaderId string `json:"evenPageHeaderId,omitempty"`

	// FirstPageFooterId: The ID of the footer used only for the first page.
	// If not set then a unique footer for the first page does not exist.
	// The value of use_first_page_header_footer determines whether to use
	// the default_footer_id or this value for the footer on the first page.
	// If not set, there is no first page footer. This property is
	// read-only.
	FirstPageFooterId string `json:"firstPageFooterId,omitempty"`

	// FirstPageHeaderId: The ID of the header used only for the first page.
	// If not set then a unique header for the first page does not exist.
	// The value of use_first_page_header_footer determines whether to use
	// the default_header_id or this value for the header on the first page.
	// If not set, there is no first page header. This property is
	// read-only.
	FirstPageHeaderId string `json:"firstPageHeaderId,omitempty"`

	// MarginBottom: The bottom page margin. Updating the bottom page margin
	// on the document style clears the bottom page margin on all section
	// styles.
	MarginBottom *Dimension `json:"marginBottom,omitempty"`

	// MarginFooter: The amount of space between the bottom of the page and
	// the contents of the footer.
	MarginFooter *Dimension `json:"marginFooter,omitempty"`

	// MarginHeader: The amount of space between the top of the page and the
	// contents of the header.
	MarginHeader *Dimension `json:"marginHeader,omitempty"`

	// MarginLeft: The left page margin. Updating the left page margin on
	// the document style clears the left page margin on all section styles.
	// It may also cause columns to resize in all sections.
	MarginLeft *Dimension `json:"marginLeft,omitempty"`

	// MarginRight: The right page margin. Updating the right page margin on
	// the document style clears the right page margin on all section
	// styles. It may also cause columns to resize in all sections.
	MarginRight *Dimension `json:"marginRight,omitempty"`

	// MarginTop: The top page margin. Updating the top page margin on the
	// document style clears the top page margin on all section styles.
	MarginTop *Dimension `json:"marginTop,omitempty"`

	// PageNumberStart: The page number from which to start counting the
	// number of pages.
	PageNumberStart int64 `json:"pageNumberStart,omitempty"`

	// PageSize: The size of a page in the document.
	PageSize *Size `json:"pageSize,omitempty"`

	// UseCustomHeaderFooterMargins: Indicates whether DocumentStyle
	// margin_header, SectionStyle margin_header and DocumentStyle
	// margin_footer, SectionStyle margin_footer are respected. When false,
	// the default values in the Docs editor for header and footer margin
	// are used. This property is read-only.
	UseCustomHeaderFooterMargins bool `json:"useCustomHeaderFooterMargins,omitempty"`

	// UseEvenPageHeaderFooter: Indicates whether to use the even page
	// header / footer IDs for the even pages.
	UseEvenPageHeaderFooter bool `json:"useEvenPageHeaderFooter,omitempty"`

	// UseFirstPageHeaderFooter: Indicates whether to use the first page
	// header / footer IDs for the first page.
	UseFirstPageHeaderFooter bool `json:"useFirstPageHeaderFooter,omitempty"`

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

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

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

// DocumentStyleSuggestionState: A mask that indicates which of the
// fields on the base DocumentStyle have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type DocumentStyleSuggestionState struct {
	// BackgroundSuggestionState: A mask that indicates which of the fields
	// in background have been changed in this suggestion.
	BackgroundSuggestionState *BackgroundSuggestionState `json:"backgroundSuggestionState,omitempty"`

	// DefaultFooterIdSuggested: Indicates if there was a suggested change
	// to default_footer_id.
	DefaultFooterIdSuggested bool `json:"defaultFooterIdSuggested,omitempty"`

	// DefaultHeaderIdSuggested: Indicates if there was a suggested change
	// to default_header_id.
	DefaultHeaderIdSuggested bool `json:"defaultHeaderIdSuggested,omitempty"`

	// EvenPageFooterIdSuggested: Indicates if there was a suggested change
	// to even_page_footer_id.
	EvenPageFooterIdSuggested bool `json:"evenPageFooterIdSuggested,omitempty"`

	// EvenPageHeaderIdSuggested: Indicates if there was a suggested change
	// to even_page_header_id.
	EvenPageHeaderIdSuggested bool `json:"evenPageHeaderIdSuggested,omitempty"`

	// FirstPageFooterIdSuggested: Indicates if there was a suggested change
	// to first_page_footer_id.
	FirstPageFooterIdSuggested bool `json:"firstPageFooterIdSuggested,omitempty"`

	// FirstPageHeaderIdSuggested: Indicates if there was a suggested change
	// to first_page_header_id.
	FirstPageHeaderIdSuggested bool `json:"firstPageHeaderIdSuggested,omitempty"`

	// MarginBottomSuggested: Indicates if there was a suggested change to
	// margin_bottom.
	MarginBottomSuggested bool `json:"marginBottomSuggested,omitempty"`

	// MarginFooterSuggested: Indicates if there was a suggested change to
	// margin_footer.
	MarginFooterSuggested bool `json:"marginFooterSuggested,omitempty"`

	// MarginHeaderSuggested: Indicates if there was a suggested change to
	// margin_header.
	MarginHeaderSuggested bool `json:"marginHeaderSuggested,omitempty"`

	// MarginLeftSuggested: Indicates if there was a suggested change to
	// margin_left.
	MarginLeftSuggested bool `json:"marginLeftSuggested,omitempty"`

	// MarginRightSuggested: Indicates if there was a suggested change to
	// margin_right.
	MarginRightSuggested bool `json:"marginRightSuggested,omitempty"`

	// MarginTopSuggested: Indicates if there was a suggested change to
	// margin_top.
	MarginTopSuggested bool `json:"marginTopSuggested,omitempty"`

	// PageNumberStartSuggested: Indicates if there was a suggested change
	// to page_number_start.
	PageNumberStartSuggested bool `json:"pageNumberStartSuggested,omitempty"`

	// PageSizeSuggestionState: A mask that indicates which of the fields in
	// size have been changed in this suggestion.
	PageSizeSuggestionState *SizeSuggestionState `json:"pageSizeSuggestionState,omitempty"`

	// UseCustomHeaderFooterMarginsSuggested: Indicates if there was a
	// suggested change to use_custom_header_footer_margins.
	UseCustomHeaderFooterMarginsSuggested bool `json:"useCustomHeaderFooterMarginsSuggested,omitempty"`

	// UseEvenPageHeaderFooterSuggested: Indicates if there was a suggested
	// change to use_even_page_header_footer.
	UseEvenPageHeaderFooterSuggested bool `json:"useEvenPageHeaderFooterSuggested,omitempty"`

	// UseFirstPageHeaderFooterSuggested: Indicates if there was a suggested
	// change to use_first_page_header_footer.
	UseFirstPageHeaderFooterSuggested bool `json:"useFirstPageHeaderFooterSuggested,omitempty"`

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

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

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

// EmbeddedDrawingProperties: The properties of an embedded drawing.
type EmbeddedDrawingProperties struct {
}

// EmbeddedDrawingPropertiesSuggestionState: A mask that indicates which
// of the fields on the base EmbeddedDrawingProperties have been changed
// in this suggestion. For any field set to true, there is a new
// suggested value.
type EmbeddedDrawingPropertiesSuggestionState struct {
}

// EmbeddedObject: An embedded object in the document.
type EmbeddedObject struct {
	// Description: The description of the embedded object. The `title` and
	// `description` are both combined to display alt text.
	Description string `json:"description,omitempty"`

	// EmbeddedDrawingProperties: The properties of an embedded drawing.
	EmbeddedDrawingProperties *EmbeddedDrawingProperties `json:"embeddedDrawingProperties,omitempty"`

	// EmbeddedObjectBorder: The border of the embedded object.
	EmbeddedObjectBorder *EmbeddedObjectBorder `json:"embeddedObjectBorder,omitempty"`

	// ImageProperties: The properties of an image.
	ImageProperties *ImageProperties `json:"imageProperties,omitempty"`

	// LinkedContentReference: A reference to the external linked source
	// content. For example, it contains a reference to the source Sheets
	// chart when the embedded object is a linked chart. If unset, then the
	// embedded object is not linked.
	LinkedContentReference *LinkedContentReference `json:"linkedContentReference,omitempty"`

	// MarginBottom: The bottom margin of the embedded object.
	MarginBottom *Dimension `json:"marginBottom,omitempty"`

	// MarginLeft: The left margin of the embedded object.
	MarginLeft *Dimension `json:"marginLeft,omitempty"`

	// MarginRight: The right margin of the embedded object.
	MarginRight *Dimension `json:"marginRight,omitempty"`

	// MarginTop: The top margin of the embedded object.
	MarginTop *Dimension `json:"marginTop,omitempty"`

	// Size: The visible size of the image after cropping.
	Size *Size `json:"size,omitempty"`

	// Title: The title of the embedded object. The `title` and
	// `description` are both combined to display alt text.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EmbeddedObject) MarshalJSON() ([]byte, error) {
	type NoMethod EmbeddedObject
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EmbeddedObjectBorder: A border around an EmbeddedObject.
type EmbeddedObjectBorder struct {
	// Color: The color of the border.
	Color *OptionalColor `json:"color,omitempty"`

	// DashStyle: The dash style of the border.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'. This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	DashStyle string `json:"dashStyle,omitempty"`

	// PropertyState: The property state of the border property.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding property when rendered in the document. This is
	// the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the corresponding property when rendered in the
	// document.
	PropertyState string `json:"propertyState,omitempty"`

	// Width: The width of the border.
	Width *Dimension `json:"width,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Color") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *EmbeddedObjectBorder) MarshalJSON() ([]byte, error) {
	type NoMethod EmbeddedObjectBorder
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EmbeddedObjectBorderSuggestionState: A mask that indicates which of
// the fields on the base EmbeddedObjectBorder have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type EmbeddedObjectBorderSuggestionState struct {
	// ColorSuggested: Indicates if there was a suggested change to color.
	ColorSuggested bool `json:"colorSuggested,omitempty"`

	// DashStyleSuggested: Indicates if there was a suggested change to
	// dash_style.
	DashStyleSuggested bool `json:"dashStyleSuggested,omitempty"`

	// PropertyStateSuggested: Indicates if there was a suggested change to
	// property_state.
	PropertyStateSuggested bool `json:"propertyStateSuggested,omitempty"`

	// WidthSuggested: Indicates if there was a suggested change to width.
	WidthSuggested bool `json:"widthSuggested,omitempty"`

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

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

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

// EmbeddedObjectSuggestionState: A mask that indicates which of the
// fields on the base EmbeddedObject have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type EmbeddedObjectSuggestionState struct {
	// DescriptionSuggested: Indicates if there was a suggested change to
	// description.
	DescriptionSuggested bool `json:"descriptionSuggested,omitempty"`

	// EmbeddedDrawingPropertiesSuggestionState: A mask that indicates which
	// of the fields in embedded_drawing_properties have been changed in
	// this suggestion.
	EmbeddedDrawingPropertiesSuggestionState *EmbeddedDrawingPropertiesSuggestionState `json:"embeddedDrawingPropertiesSuggestionState,omitempty"`

	// EmbeddedObjectBorderSuggestionState: A mask that indicates which of
	// the fields in embedded_object_border have been changed in this
	// suggestion.
	EmbeddedObjectBorderSuggestionState *EmbeddedObjectBorderSuggestionState `json:"embeddedObjectBorderSuggestionState,omitempty"`

	// ImagePropertiesSuggestionState: A mask that indicates which of the
	// fields in image_properties have been changed in this suggestion.
	ImagePropertiesSuggestionState *ImagePropertiesSuggestionState `json:"imagePropertiesSuggestionState,omitempty"`

	// LinkedContentReferenceSuggestionState: A mask that indicates which of
	// the fields in linked_content_reference have been changed in this
	// suggestion.
	LinkedContentReferenceSuggestionState *LinkedContentReferenceSuggestionState `json:"linkedContentReferenceSuggestionState,omitempty"`

	// MarginBottomSuggested: Indicates if there was a suggested change to
	// margin_bottom.
	MarginBottomSuggested bool `json:"marginBottomSuggested,omitempty"`

	// MarginLeftSuggested: Indicates if there was a suggested change to
	// margin_left.
	MarginLeftSuggested bool `json:"marginLeftSuggested,omitempty"`

	// MarginRightSuggested: Indicates if there was a suggested change to
	// margin_right.
	MarginRightSuggested bool `json:"marginRightSuggested,omitempty"`

	// MarginTopSuggested: Indicates if there was a suggested change to
	// margin_top.
	MarginTopSuggested bool `json:"marginTopSuggested,omitempty"`

	// SizeSuggestionState: A mask that indicates which of the fields in
	// size have been changed in this suggestion.
	SizeSuggestionState *SizeSuggestionState `json:"sizeSuggestionState,omitempty"`

	// TitleSuggested: Indicates if there was a suggested change to title.
	TitleSuggested bool `json:"titleSuggested,omitempty"`

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

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

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

// EndOfSegmentLocation: Location at the end of a body, header, footer
// or footnote. The location is immediately before the last newline in
// the document segment.
type EndOfSegmentLocation struct {
	// SegmentId: The ID of the header, footer or footnote the location is
	// in. An empty segment ID signifies the document's body.
	SegmentId string `json:"segmentId,omitempty"`

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

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

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

// Equation: A ParagraphElement representing an equation.
type Equation struct {
	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A Equation may
	// have multiple insertion IDs if it is a nested suggested change. If
	// empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

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

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

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

// Footer: A document footer.
type Footer struct {
	// Content: The contents of the footer. The indexes for a footer's
	// content begin at zero.
	Content []*StructuralElement `json:"content,omitempty"`

	// FooterId: The ID of the footer.
	FooterId string `json:"footerId,omitempty"`

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

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

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

// Footnote: A document footnote.
type Footnote struct {
	// Content: The contents of the footnote. The indexes for a footnote's
	// content begin at zero.
	Content []*StructuralElement `json:"content,omitempty"`

	// FootnoteId: The ID of the footnote.
	FootnoteId string `json:"footnoteId,omitempty"`

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

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

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

// FootnoteReference: A ParagraphElement representing a footnote
// reference. A footnote reference is the inline content rendered with a
// number and is used to identify the footnote.
type FootnoteReference struct {
	// FootnoteId: The ID of the footnote that contains the content of this
	// footnote reference.
	FootnoteId string `json:"footnoteId,omitempty"`

	// FootnoteNumber: The rendered number of this footnote.
	FootnoteNumber string `json:"footnoteNumber,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A
	// FootnoteReference may have multiple insertion IDs if it is a nested
	// suggested change. If empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// FootnoteReference, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this FootnoteReference.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// Header: A document header.
type Header struct {
	// Content: The contents of the header. The indexes for a header's
	// content begin at zero.
	Content []*StructuralElement `json:"content,omitempty"`

	// HeaderId: The ID of the header.
	HeaderId string `json:"headerId,omitempty"`

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

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

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

// HorizontalRule: A ParagraphElement representing a horizontal line.
type HorizontalRule struct {
	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A HorizontalRule
	// may have multiple insertion IDs if it is a nested suggested change.
	// If empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// HorizontalRule, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this HorizontalRule. Similar to text
	// content, like text runs and footnote references, the text style of a
	// horizontal rule can affect content layout as well as the styling of
	// text inserted adjacent to it.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// ImageProperties: The properties of an image.
type ImageProperties struct {
	// Angle: The clockwise rotation angle of the image, in radians.
	Angle float64 `json:"angle,omitempty"`

	// Brightness: The brightness effect of the image. The value should be
	// in the interval [-1.0, 1.0], where 0 means no effect.
	Brightness float64 `json:"brightness,omitempty"`

	// ContentUri: A URI to the image with a default lifetime of 30 minutes.
	// This URI is tagged with the account of the requester. Anyone with the
	// URI effectively accesses the image as the original requester. Access
	// to the image may be lost if the document's sharing settings change.
	ContentUri string `json:"contentUri,omitempty"`

	// Contrast: The contrast effect of the image. The value should be in
	// the interval [-1.0, 1.0], where 0 means no effect.
	Contrast float64 `json:"contrast,omitempty"`

	// CropProperties: The crop properties of the image.
	CropProperties *CropProperties `json:"cropProperties,omitempty"`

	// SourceUri: The source URI is the URI used to insert the image. The
	// source URI can be empty.
	SourceUri string `json:"sourceUri,omitempty"`

	// Transparency: The transparency effect of the image. The value should
	// be in the interval [0.0, 1.0], where 0 means no effect and 1 means
	// completely transparent.
	Transparency float64 `json:"transparency,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Angle") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *ImageProperties) MarshalJSON() ([]byte, error) {
	type NoMethod ImageProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ImageProperties) UnmarshalJSON(data []byte) error {
	type NoMethod ImageProperties
	var s1 struct {
		Angle        gensupport.JSONFloat64 `json:"angle"`
		Brightness   gensupport.JSONFloat64 `json:"brightness"`
		Contrast     gensupport.JSONFloat64 `json:"contrast"`
		Transparency gensupport.JSONFloat64 `json:"transparency"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Angle = float64(s1.Angle)
	s.Brightness = float64(s1.Brightness)
	s.Contrast = float64(s1.Contrast)
	s.Transparency = float64(s1.Transparency)
	return nil
}

// ImagePropertiesSuggestionState: A mask that indicates which of the
// fields on the base ImageProperties have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type ImagePropertiesSuggestionState struct {
	// AngleSuggested: Indicates if there was a suggested change to angle.
	AngleSuggested bool `json:"angleSuggested,omitempty"`

	// BrightnessSuggested: Indicates if there was a suggested change to
	// brightness.
	BrightnessSuggested bool `json:"brightnessSuggested,omitempty"`

	// ContentUriSuggested: Indicates if there was a suggested change to
	// content_uri.
	ContentUriSuggested bool `json:"contentUriSuggested,omitempty"`

	// ContrastSuggested: Indicates if there was a suggested change to
	// contrast.
	ContrastSuggested bool `json:"contrastSuggested,omitempty"`

	// CropPropertiesSuggestionState: A mask that indicates which of the
	// fields in crop_properties have been changed in this suggestion.
	CropPropertiesSuggestionState *CropPropertiesSuggestionState `json:"cropPropertiesSuggestionState,omitempty"`

	// SourceUriSuggested: Indicates if there was a suggested change to
	// source_uri.
	SourceUriSuggested bool `json:"sourceUriSuggested,omitempty"`

	// TransparencySuggested: Indicates if there was a suggested change to
	// transparency.
	TransparencySuggested bool `json:"transparencySuggested,omitempty"`

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

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

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

// InlineObject: An object that appears inline with text. An
// InlineObject contains an EmbeddedObject such as an image.
type InlineObject struct {
	// InlineObjectProperties: The properties of this inline object.
	InlineObjectProperties *InlineObjectProperties `json:"inlineObjectProperties,omitempty"`

	// ObjectId: The ID of this inline object. Can be used to update an
	// object’s properties.
	ObjectId string `json:"objectId,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInlineObjectPropertiesChanges: The suggested changes to the
	// inline object properties, keyed by suggestion ID.
	SuggestedInlineObjectPropertiesChanges map[string]SuggestedInlineObjectProperties `json:"suggestedInlineObjectPropertiesChanges,omitempty"`

	// SuggestedInsertionId: The suggested insertion ID. If empty, then this
	// is not a suggested insertion.
	SuggestedInsertionId string `json:"suggestedInsertionId,omitempty"`

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

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

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

// InlineObjectElement: A ParagraphElement that contains an
// InlineObject.
type InlineObjectElement struct {
	// InlineObjectId: The ID of the InlineObject this element contains.
	InlineObjectId string `json:"inlineObjectId,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. An
	// InlineObjectElement may have multiple insertion IDs if it is a nested
	// suggested change. If empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// InlineObject, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this InlineObjectElement. Similar to
	// text content, like text runs and footnote references, the text style
	// of an inline object element can affect content layout as well as the
	// styling of text inserted adjacent to it.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// InlineObjectProperties: Properties of an InlineObject.
type InlineObjectProperties struct {
	// EmbeddedObject: The embedded object of this inline object.
	EmbeddedObject *EmbeddedObject `json:"embeddedObject,omitempty"`

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

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

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

// InlineObjectPropertiesSuggestionState: A mask that indicates which of
// the fields on the base InlineObjectProperties have been changed in
// this suggestion. For any field set to true, there is a new suggested
// value.
type InlineObjectPropertiesSuggestionState struct {
	// EmbeddedObjectSuggestionState: A mask that indicates which of the
	// fields in embedded_object have been changed in this suggestion.
	EmbeddedObjectSuggestionState *EmbeddedObjectSuggestionState `json:"embeddedObjectSuggestionState,omitempty"`

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

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

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

// InsertInlineImageRequest: Inserts an InlineObject containing an image
// at the given location.
type InsertInlineImageRequest struct {
	// EndOfSegmentLocation: Inserts the text at the end of a header, footer
	// or the document body. Inline images cannot be inserted inside a
	// footnote.
	EndOfSegmentLocation *EndOfSegmentLocation `json:"endOfSegmentLocation,omitempty"`

	// Location: Inserts the image at a specific index in the document. The
	// image must be inserted inside the bounds of an existing Paragraph.
	// For instance, it cannot be inserted at a table's start index (i.e.
	// between the table and its preceding paragraph). Inline images cannot
	// be inserted inside a footnote or equation.
	Location *Location `json:"location,omitempty"`

	// ObjectSize: The size that the image should appear as in the document.
	// This property is optional and the final size of the image in the
	// document is determined by the following rules: * If neither width nor
	// height is specified, then a default size of the image is calculated
	// based on its resolution. * If one dimension is specified then the
	// other dimension is calculated to preserve the aspect ratio of the
	// image. * If both width and height are specified, the image is scaled
	// to fit within the provided dimensions while maintaining its aspect
	// ratio.
	ObjectSize *Size `json:"objectSize,omitempty"`

	// Uri: The image URI. The image is fetched once at insertion time and a
	// copy is stored for display inside the document. Images must be less
	// than 50MB in size, cannot exceed 25 megapixels, and must be in one of
	// PNG, JPEG, or GIF format. The provided URI can be at most 2 kB in
	// length. The URI itself is saved with the image, and exposed via the
	// ImageProperties.content_uri field.
	Uri string `json:"uri,omitempty"`

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

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

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

// InsertInlineImageResponse: The result of inserting an inline image.
type InsertInlineImageResponse struct {
	// ObjectId: The ID of the created InlineObject.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *InsertInlineImageResponse) MarshalJSON() ([]byte, error) {
	type NoMethod InsertInlineImageResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertInlineSheetsChartResponse: The result of inserting an embedded
// Google Sheets chart.
type InsertInlineSheetsChartResponse struct {
	// ObjectId: The object ID of the inserted chart.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *InsertInlineSheetsChartResponse) MarshalJSON() ([]byte, error) {
	type NoMethod InsertInlineSheetsChartResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertPageBreakRequest: Inserts a page break followed by a newline at
// the specified location.
type InsertPageBreakRequest struct {
	// EndOfSegmentLocation: Inserts the page break at the end of the
	// document body. Page breaks cannot be inserted inside a footnote,
	// header or footer. Since page breaks can only be inserted inside the
	// body, the segment ID field must be empty.
	EndOfSegmentLocation *EndOfSegmentLocation `json:"endOfSegmentLocation,omitempty"`

	// Location: Inserts the page break at a specific index in the document.
	// The page break must be inserted inside the bounds of an existing
	// Paragraph. For instance, it cannot be inserted at a table's start
	// index (i.e. between the table and its preceding paragraph). Page
	// breaks cannot be inserted inside a table, equation, footnote, header
	// or footer. Since page breaks can only be inserted inside the body,
	// the segment ID field must be empty.
	Location *Location `json:"location,omitempty"`

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

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

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

// InsertSectionBreakRequest: Inserts a section break at the given
// location. A newline character will be inserted before the section
// break.
type InsertSectionBreakRequest struct {
	// EndOfSegmentLocation: Inserts a newline and a section break at the
	// end of the document body. Section breaks cannot be inserted inside a
	// footnote, header or footer. Because section breaks can only be
	// inserted inside the body, the segment ID field must be empty.
	EndOfSegmentLocation *EndOfSegmentLocation `json:"endOfSegmentLocation,omitempty"`

	// Location: Inserts a newline and a section break at a specific index
	// in the document. The section break must be inserted inside the bounds
	// of an existing Paragraph. For instance, it cannot be inserted at a
	// table's start index (i.e. between the table and its preceding
	// paragraph). Section breaks cannot be inserted inside a table,
	// equation, footnote, header, or footer. Since section breaks can only
	// be inserted inside the body, the segment ID field must be empty.
	Location *Location `json:"location,omitempty"`

	// SectionType: The type of section to insert.
	//
	// Possible values:
	//   "SECTION_TYPE_UNSPECIFIED" - The section type is unspecified.
	//   "CONTINUOUS" - The section starts immediately after the last
	// paragraph of the previous section.
	//   "NEXT_PAGE" - The section starts on the next page.
	SectionType string `json:"sectionType,omitempty"`

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

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

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

// InsertTableColumnRequest: Inserts an empty column into a table.
type InsertTableColumnRequest struct {
	// InsertRight: Whether to insert new column to the right of the
	// reference cell location. - `True`: insert to the right. - `False`:
	// insert to the left.
	InsertRight bool `json:"insertRight,omitempty"`

	// TableCellLocation: The reference table cell location from which
	// columns will be inserted. A new column will be inserted to the left
	// (or right) of the column where the reference cell is. If the
	// reference cell is a merged cell, a new column will be inserted to the
	// left (or right) of the merged cell.
	TableCellLocation *TableCellLocation `json:"tableCellLocation,omitempty"`

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

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

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

// InsertTableRequest: Inserts a table at the specified location. A
// newline character will be inserted before the inserted table.
type InsertTableRequest struct {
	// Columns: The number of columns in the table.
	Columns int64 `json:"columns,omitempty"`

	// EndOfSegmentLocation: Inserts the table at the end of the given
	// header, footer or document body. A newline character will be inserted
	// before the inserted table. Tables cannot be inserted inside a
	// footnote.
	EndOfSegmentLocation *EndOfSegmentLocation `json:"endOfSegmentLocation,omitempty"`

	// Location: Inserts the table at a specific model index. A newline
	// character will be inserted before the inserted table, therefore the
	// table start index will be at the specified location index + 1. The
	// table must be inserted inside the bounds of an existing Paragraph.
	// For instance, it cannot be inserted at a table's start index (i.e.
	// between an existing table and its preceding paragraph). Tables cannot
	// be inserted inside a footnote or equation.
	Location *Location `json:"location,omitempty"`

	// Rows: The number of rows in the table.
	Rows int64 `json:"rows,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Columns") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *InsertTableRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InsertTableRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertTableRowRequest: Inserts an empty row into a table.
type InsertTableRowRequest struct {
	// InsertBelow: Whether to insert new row below the reference cell
	// location. - `True`: insert below the cell. - `False`: insert above
	// the cell.
	InsertBelow bool `json:"insertBelow,omitempty"`

	// TableCellLocation: The reference table cell location from which rows
	// will be inserted. A new row will be inserted above (or below) the row
	// where the reference cell is. If the reference cell is a merged cell,
	// a new row will be inserted above (or below) the merged cell.
	TableCellLocation *TableCellLocation `json:"tableCellLocation,omitempty"`

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

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

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

// InsertTextRequest: Inserts text at the specified location.
type InsertTextRequest struct {
	// EndOfSegmentLocation: Inserts the text at the end of a header,
	// footer, footnote or the document body.
	EndOfSegmentLocation *EndOfSegmentLocation `json:"endOfSegmentLocation,omitempty"`

	// Location: Inserts the text at a specific index in the document. Text
	// must be inserted inside the bounds of an existing Paragraph. For
	// instance, text cannot be inserted at a table's start index (i.e.
	// between the table and its preceding paragraph). The text must be
	// inserted in the preceding paragraph.
	Location *Location `json:"location,omitempty"`

	// Text: The text to be inserted. Inserting a newline character will
	// implicitly create a new Paragraph at that index. The paragraph style
	// of the new paragraph will be copied from the paragraph at the current
	// insertion index, including lists and bullets. Text styles for
	// inserted text will be determined automatically, generally preserving
	// the styling of neighboring text. In most cases, the text style for
	// the inserted text will match the text immediately before the
	// insertion index. Some control characters (U+0000-U+0008,
	// U+000C-U+001F) and characters from the Unicode Basic Multilingual
	// Plane Private Use Area (U+E000-U+F8FF) will be stripped out of the
	// inserted text.
	Text string `json:"text,omitempty"`

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

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

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

// Link: A reference to another portion of a document or an external URL
// resource.
type Link struct {
	// BookmarkId: The ID of a bookmark in this document.
	BookmarkId string `json:"bookmarkId,omitempty"`

	// HeadingId: The ID of a heading in this document.
	HeadingId string `json:"headingId,omitempty"`

	// Url: An external URL.
	Url string `json:"url,omitempty"`

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

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

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

// LinkedContentReference: A reference to the external linked source
// content.
type LinkedContentReference struct {
	// SheetsChartReference: A reference to the linked chart.
	SheetsChartReference *SheetsChartReference `json:"sheetsChartReference,omitempty"`

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

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

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

// LinkedContentReferenceSuggestionState: A mask that indicates which of
// the fields on the base LinkedContentReference have been changed in
// this suggestion. For any field set to true, there is a new suggested
// value.
type LinkedContentReferenceSuggestionState struct {
	// SheetsChartReferenceSuggestionState: A mask that indicates which of
	// the fields in sheets_chart_reference have been changed in this
	// suggestion.
	SheetsChartReferenceSuggestionState *SheetsChartReferenceSuggestionState `json:"sheetsChartReferenceSuggestionState,omitempty"`

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

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

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

// List: A List represents the list attributes for a group of paragraphs
// that all belong to the same list. A paragraph that is part of a list
// has a reference to the list's ID in its bullet.
type List struct {
	// ListProperties: The properties of the list.
	ListProperties *ListProperties `json:"listProperties,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this list.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionId: The suggested insertion ID. If empty, then this
	// is not a suggested insertion.
	SuggestedInsertionId string `json:"suggestedInsertionId,omitempty"`

	// SuggestedListPropertiesChanges: The suggested changes to the list
	// properties, keyed by suggestion ID.
	SuggestedListPropertiesChanges map[string]SuggestedListProperties `json:"suggestedListPropertiesChanges,omitempty"`

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

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

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

// ListProperties: The properties of a list which describe the look and
// feel of bullets belonging to paragraphs associated with a list.
type ListProperties struct {
	// NestingLevels: Describes the properties of the bullets at the
	// associated level. A list has at most nine levels of nesting with
	// nesting level 0 corresponding to the top-most level and nesting level
	// 8 corresponding to the most nested level. The nesting levels are
	// returned in ascending order with the least nested returned first.
	NestingLevels []*NestingLevel `json:"nestingLevels,omitempty"`

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

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

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

// ListPropertiesSuggestionState: A mask that indicates which of the
// fields on the base ListProperties have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type ListPropertiesSuggestionState struct {
	// NestingLevelsSuggestionStates: A mask that indicates which of the
	// fields on the corresponding NestingLevel in nesting_levels have been
	// changed in this suggestion. The nesting level suggestion states are
	// returned in ascending order of the nesting level with the least
	// nested returned first.
	NestingLevelsSuggestionStates []*NestingLevelSuggestionState `json:"nestingLevelsSuggestionStates,omitempty"`

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

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

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

// Location: A particular location in the document.
type Location struct {
	// Index: The zero-based index, in UTF-16 code units. The index is
	// relative to the beginning of the segment specified by segment_id.
	Index int64 `json:"index,omitempty"`

	// SegmentId: The ID of the header, footer or footnote the location is
	// in. An empty segment ID signifies the document's body.
	SegmentId string `json:"segmentId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Index") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *Location) MarshalJSON() ([]byte, error) {
	type NoMethod Location
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MergeTableCellsRequest: Merges cells in a Table.
type MergeTableCellsRequest struct {
	// TableRange: The table range specifying which cells of the table to
	// merge. Any text in the cells being merged will be concatenated and
	// stored in the "head" cell of the range. This is the upper-left cell
	// of the range when the content direction is left to right, and the
	// upper-right cell of the range otherwise. If the range is
	// non-rectangular (which can occur in some cases where the range covers
	// cells that are already merged or where the table is non-rectangular),
	// a 400 bad request error is returned.
	TableRange *TableRange `json:"tableRange,omitempty"`

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

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

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

// NamedRange: A collection of Ranges with the same named range ID.
// Named ranges allow developers to associate parts of a document with
// an arbitrary user-defined label so their contents can be
// programmatically read or edited at a later time. A document can
// contain multiple named ranges with the same name, but every named
// range has a unique ID. A named range is created with a single Range,
// and content inserted inside a named range generally expands that
// range. However, certain document changes can cause the range to be
// split into multiple ranges. Named ranges are not private. All
// applications and collaborators that have access to the document can
// see its named ranges.
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"`

	// Ranges: The ranges that belong to this named range.
	Ranges []*Range `json:"ranges,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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)
}

// NamedRanges: A collection of all the NamedRanges in the document that
// share a given name.
type NamedRanges struct {
	// Name: The name that all the named ranges share.
	Name string `json:"name,omitempty"`

	// NamedRanges: The NamedRanges that share the same name.
	NamedRanges []*NamedRange `json:"namedRanges,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *NamedRanges) MarshalJSON() ([]byte, error) {
	type NoMethod NamedRanges
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NamedStyle: A named style. Paragraphs in the document can inherit
// their TextStyle and ParagraphStyle from this named style when they
// have the same named style type.
type NamedStyle struct {
	// NamedStyleType: The type of this named style.
	//
	// Possible values:
	//   "NAMED_STYLE_TYPE_UNSPECIFIED" - The type of named style is
	// unspecified.
	//   "NORMAL_TEXT" - Normal text.
	//   "TITLE" - Title.
	//   "SUBTITLE" - Subtitle.
	//   "HEADING_1" - Heading 1.
	//   "HEADING_2" - Heading 2.
	//   "HEADING_3" - Heading 3.
	//   "HEADING_4" - Heading 4.
	//   "HEADING_5" - Heading 5.
	//   "HEADING_6" - Heading 6.
	NamedStyleType string `json:"namedStyleType,omitempty"`

	// ParagraphStyle: The paragraph style of this named style.
	ParagraphStyle *ParagraphStyle `json:"paragraphStyle,omitempty"`

	// TextStyle: The text style of this named style.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// NamedStyleSuggestionState: A suggestion state of a NamedStyle
// message.
type NamedStyleSuggestionState struct {
	// NamedStyleType: The named style type that this suggestion state
	// corresponds to. This field is provided as a convenience for matching
	// the NamedStyleSuggestionState with its corresponding NamedStyle.
	//
	// Possible values:
	//   "NAMED_STYLE_TYPE_UNSPECIFIED" - The type of named style is
	// unspecified.
	//   "NORMAL_TEXT" - Normal text.
	//   "TITLE" - Title.
	//   "SUBTITLE" - Subtitle.
	//   "HEADING_1" - Heading 1.
	//   "HEADING_2" - Heading 2.
	//   "HEADING_3" - Heading 3.
	//   "HEADING_4" - Heading 4.
	//   "HEADING_5" - Heading 5.
	//   "HEADING_6" - Heading 6.
	NamedStyleType string `json:"namedStyleType,omitempty"`

	// ParagraphStyleSuggestionState: A mask that indicates which of the
	// fields in paragraph style have been changed in this suggestion.
	ParagraphStyleSuggestionState *ParagraphStyleSuggestionState `json:"paragraphStyleSuggestionState,omitempty"`

	// TextStyleSuggestionState: A mask that indicates which of the fields
	// in text style have been changed in this suggestion.
	TextStyleSuggestionState *TextStyleSuggestionState `json:"textStyleSuggestionState,omitempty"`

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

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

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

// NamedStyles: The named styles. Paragraphs in the document can inherit
// their TextStyle and ParagraphStyle from these named styles.
type NamedStyles struct {
	// Styles: The named styles. There is an entry for each of the possible
	// named style types.
	Styles []*NamedStyle `json:"styles,omitempty"`

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

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

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

// NamedStylesSuggestionState: The suggestion state of a NamedStyles
// message.
type NamedStylesSuggestionState struct {
	// StylesSuggestionStates: A mask that indicates which of the fields on
	// the corresponding NamedStyle in styles have been changed in this
	// suggestion. The order of these named style suggestion states match
	// the order of the corresponding named style within the named styles
	// suggestion.
	StylesSuggestionStates []*NamedStyleSuggestionState `json:"stylesSuggestionStates,omitempty"`

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

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

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

// NestingLevel: Contains properties describing the look and feel of a
// list bullet at a given level of nesting.
type NestingLevel struct {
	// BulletAlignment: The alignment of the bullet within the space
	// allotted for rendering the bullet.
	//
	// Possible values:
	//   "BULLET_ALIGNMENT_UNSPECIFIED" - The bullet alignment is
	// unspecified.
	//   "START" - The bullet is aligned to the start of the space allotted
	// for rendering the bullet. Left-aligned for LTR text, right-aligned
	// otherwise.
	//   "CENTER" - The bullet is aligned to the center of the space
	// allotted for rendering the bullet.
	//   "END" - The bullet is aligned to the end of the space allotted for
	// rendering the bullet. Right-aligned for LTR text, left-aligned
	// otherwise.
	BulletAlignment string `json:"bulletAlignment,omitempty"`

	// GlyphFormat: The format string used by bullets at this level of
	// nesting. The glyph format contains one or more placeholders, and
	// these placeholder are replaced with the appropriate values depending
	// on the glyph_type or glyph_symbol. The placeholders follow the
	// pattern `%[nesting_level]`. Furthermore, placeholders can have
	// prefixes and suffixes. Thus, the glyph format follows the pattern
	// `%[nesting_level]`. Note that the prefix and suffix are optional and
	// can be arbitrary strings. For example, the glyph format `%0.`
	// indicates that the rendered glyph will replace the placeholder with
	// the corresponding glyph for nesting level 0 followed by a period as
	// the suffix. So a list with a glyph type of UPPER_ALPHA and glyph
	// format `%0.` at nesting level 0 will result in a list with rendered
	// glyphs `A.` `B.` `C.` The glyph format can contain placeholders for
	// the current nesting level as well as placeholders for parent nesting
	// levels. For example, a list can have a glyph format of `%0.` at
	// nesting level 0 and a glyph format of `%0.%1.` at nesting level 1.
	// Assuming both nesting levels have DECIMAL glyph types, this would
	// result in a list with rendered glyphs `1.` `2.` ` 2.1.` ` 2.2.` `3.`
	// For nesting levels that are ordered, the string that replaces a
	// placeholder in the glyph format for a particular paragraph depends on
	// the paragraph's order within the list.
	GlyphFormat string `json:"glyphFormat,omitempty"`

	// GlyphSymbol: A custom glyph symbol used by bullets when paragraphs at
	// this level of nesting are unordered. The glyph symbol replaces
	// placeholders within the glyph_format. For example, if the
	// glyph_symbol is the solid circle corresponding to Unicode U+25cf code
	// point and the glyph_format is `%0`, the rendered glyph would be the
	// solid circle.
	GlyphSymbol string `json:"glyphSymbol,omitempty"`

	// GlyphType: The type of glyph used by bullets when paragraphs at this
	// level of nesting are ordered. The glyph type determines the type of
	// glyph used to replace placeholders within the glyph_format when
	// paragraphs at this level of nesting are ordered. For example, if the
	// nesting level is 0, the glyph_format is `%0.` and the glyph type is
	// DECIMAL, then the rendered glyph would replace the placeholder `%0`
	// in the glyph format with a number corresponding to list item's order
	// within the list.
	//
	// Possible values:
	//   "GLYPH_TYPE_UNSPECIFIED" - The glyph type is unspecified or
	// unsupported.
	//   "NONE" - An empty string.
	//   "DECIMAL" - A number, like `1`, `2`, or `3`.
	//   "ZERO_DECIMAL" - A number where single digit numbers are prefixed
	// with a zero, like `01`, `02`, or `03`. Numbers with more than one
	// digit are not prefixed with a zero.
	//   "UPPER_ALPHA" - An uppercase letter, like `A`, `B`, or `C`.
	//   "ALPHA" - A lowercase letter, like `a`, `b`, or `c`.
	//   "UPPER_ROMAN" - An uppercase Roman numeral, like `I`, `II`, or
	// `III`.
	//   "ROMAN" - A lowercase Roman numeral, like `i`, `ii`, or `iii`.
	GlyphType string `json:"glyphType,omitempty"`

	// IndentFirstLine: The amount of indentation for the first line of
	// paragraphs at this level of nesting.
	IndentFirstLine *Dimension `json:"indentFirstLine,omitempty"`

	// IndentStart: The amount of indentation for paragraphs at this level
	// of nesting. Applied to the side that corresponds to the start of the
	// text, based on the paragraph's content direction.
	IndentStart *Dimension `json:"indentStart,omitempty"`

	// StartNumber: The number of the first list item at this nesting level.
	// A value of 0 is treated as a value of 1 for lettered lists and roman
	// numeraled lists, i.e. for values of both 0 and 1, lettered and roman
	// numeraled lists will begin at `a` and `i` respectively. This value is
	// ignored for nesting levels with unordered glyphs.
	StartNumber int64 `json:"startNumber,omitempty"`

	// TextStyle: The text style of bullets at this level of nesting.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// NestingLevelSuggestionState: A mask that indicates which of the
// fields on the base NestingLevel have been changed in this suggestion.
// For any field set to true, there is a new suggested value.
type NestingLevelSuggestionState struct {
	// BulletAlignmentSuggested: Indicates if there was a suggested change
	// to bullet_alignment.
	BulletAlignmentSuggested bool `json:"bulletAlignmentSuggested,omitempty"`

	// GlyphFormatSuggested: Indicates if there was a suggested change to
	// glyph_format.
	GlyphFormatSuggested bool `json:"glyphFormatSuggested,omitempty"`

	// GlyphSymbolSuggested: Indicates if there was a suggested change to
	// glyph_symbol.
	GlyphSymbolSuggested bool `json:"glyphSymbolSuggested,omitempty"`

	// GlyphTypeSuggested: Indicates if there was a suggested change to
	// glyph_type.
	GlyphTypeSuggested bool `json:"glyphTypeSuggested,omitempty"`

	// IndentFirstLineSuggested: Indicates if there was a suggested change
	// to indent_first_line.
	IndentFirstLineSuggested bool `json:"indentFirstLineSuggested,omitempty"`

	// IndentStartSuggested: Indicates if there was a suggested change to
	// indent_start.
	IndentStartSuggested bool `json:"indentStartSuggested,omitempty"`

	// StartNumberSuggested: Indicates if there was a suggested change to
	// start_number.
	StartNumberSuggested bool `json:"startNumberSuggested,omitempty"`

	// TextStyleSuggestionState: A mask that indicates which of the fields
	// in text style have been changed in this suggestion.
	TextStyleSuggestionState *TextStyleSuggestionState `json:"textStyleSuggestionState,omitempty"`

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

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

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

// ObjectReferences: A collection of object IDs.
type ObjectReferences struct {
	// ObjectIds: The object IDs.
	ObjectIds []string `json:"objectIds,omitempty"`

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

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

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

// OptionalColor: A color that can either be fully opaque or fully
// transparent.
type OptionalColor struct {
	// Color: If set, this will be used as an opaque color. If unset, this
	// represents a transparent color.
	Color *Color `json:"color,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Color") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *OptionalColor) MarshalJSON() ([]byte, error) {
	type NoMethod OptionalColor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageBreak: A ParagraphElement representing a page break. A page break
// makes the subsequent text start at the top of the next page.
type PageBreak struct {
	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A PageBreak may
	// have multiple insertion IDs if it is a nested suggested change. If
	// empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// PageBreak, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this PageBreak. Similar to text content,
	// like text runs and footnote references, the text style of a page
	// break can affect content layout as well as the styling of text
	// inserted adjacent to it.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// Paragraph: A StructuralElement representing a paragraph. A paragraph
// is a range of content that is terminated with a newline character.
type Paragraph struct {
	// Bullet: The bullet for this paragraph. If not present, the paragraph
	// does not belong to a list.
	Bullet *Bullet `json:"bullet,omitempty"`

	// Elements: The content of the paragraph broken down into its component
	// parts.
	Elements []*ParagraphElement `json:"elements,omitempty"`

	// ParagraphStyle: The style of this paragraph.
	ParagraphStyle *ParagraphStyle `json:"paragraphStyle,omitempty"`

	// PositionedObjectIds: The IDs of the positioned objects tethered to
	// this paragraph.
	PositionedObjectIds []string `json:"positionedObjectIds,omitempty"`

	// SuggestedBulletChanges: The suggested changes to this paragraph's
	// bullet.
	SuggestedBulletChanges map[string]SuggestedBullet `json:"suggestedBulletChanges,omitempty"`

	// SuggestedParagraphStyleChanges: The suggested paragraph style changes
	// to this paragraph, keyed by suggestion ID.
	SuggestedParagraphStyleChanges map[string]SuggestedParagraphStyle `json:"suggestedParagraphStyleChanges,omitempty"`

	// SuggestedPositionedObjectIds: The IDs of the positioned objects that
	// are suggested to be attached to this paragraph, keyed by suggestion
	// ID.
	SuggestedPositionedObjectIds map[string]ObjectReferences `json:"suggestedPositionedObjectIds,omitempty"`

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

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

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

// ParagraphBorder: A border around a paragraph.
type ParagraphBorder struct {
	// Color: The color of the border.
	Color *OptionalColor `json:"color,omitempty"`

	// DashStyle: The dash style of the border.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'. This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	DashStyle string `json:"dashStyle,omitempty"`

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

	// Width: The width of the border.
	Width *Dimension `json:"width,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Color") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *ParagraphBorder) MarshalJSON() ([]byte, error) {
	type NoMethod ParagraphBorder
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ParagraphElement: A ParagraphElement describes content within a
// Paragraph.
type ParagraphElement struct {
	// AutoText: An auto text paragraph element.
	AutoText *AutoText `json:"autoText,omitempty"`

	// ColumnBreak: A column break paragraph element.
	ColumnBreak *ColumnBreak `json:"columnBreak,omitempty"`

	// EndIndex: The zero-base end index of this paragraph element,
	// exclusive, in UTF-16 code units.
	EndIndex int64 `json:"endIndex,omitempty"`

	// Equation: An equation paragraph element.
	Equation *Equation `json:"equation,omitempty"`

	// FootnoteReference: A footnote reference paragraph element.
	FootnoteReference *FootnoteReference `json:"footnoteReference,omitempty"`

	// HorizontalRule: A horizontal rule paragraph element.
	HorizontalRule *HorizontalRule `json:"horizontalRule,omitempty"`

	// InlineObjectElement: An inline object paragraph element.
	InlineObjectElement *InlineObjectElement `json:"inlineObjectElement,omitempty"`

	// PageBreak: A page break paragraph element.
	PageBreak *PageBreak `json:"pageBreak,omitempty"`

	// Person: A paragraph element that links to a person or email address.
	Person *Person `json:"person,omitempty"`

	// RichLink: A paragraph element that links to a Google resource (such
	// as a file in Drive, a Youtube video, a Calendar event, etc.)
	RichLink *RichLink `json:"richLink,omitempty"`

	// StartIndex: The zero-based start index of this paragraph element, in
	// UTF-16 code units.
	StartIndex int64 `json:"startIndex,omitempty"`

	// TextRun: A text run paragraph element.
	TextRun *TextRun `json:"textRun,omitempty"`

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

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

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

// ParagraphStyle: Styles that apply to a whole paragraph. Inherited
// paragraph styles are represented as unset fields in this message. A
// paragraph style's parent depends on where the paragraph style is
// defined: * The ParagraphStyle on a Paragraph inherits from the
// paragraph's corresponding named style type. * The ParagraphStyle on a
// named style inherits from the normal text named style. * The
// ParagraphStyle of the normal text named style inherits from the
// default paragraph style in the Docs editor. * The ParagraphStyle on a
// Paragraph element that is contained in a table may inherit its
// paragraph style from the table style. If the paragraph style does not
// inherit from a parent, unsetting fields will revert the style to a
// value matching the defaults in the Docs editor.
type ParagraphStyle struct {
	// Alignment: The text alignment for this paragraph.
	//
	// Possible values:
	//   "ALIGNMENT_UNSPECIFIED" - The paragraph alignment is inherited from
	// the parent.
	//   "START" - The paragraph is aligned to the start of the line.
	// Left-aligned for LTR text, right-aligned otherwise.
	//   "CENTER" - The paragraph is centered.
	//   "END" - The paragraph is aligned to the end of the line.
	// Right-aligned for LTR text, left-aligned otherwise.
	//   "JUSTIFIED" - The paragraph is justified.
	Alignment string `json:"alignment,omitempty"`

	// AvoidWidowAndOrphan: Whether to avoid widows and orphans for the
	// paragraph. If unset, the value is inherited from the parent.
	AvoidWidowAndOrphan bool `json:"avoidWidowAndOrphan,omitempty"`

	// BorderBetween: The border between this paragraph and the next and
	// previous paragraphs. If unset, the value is inherited from the
	// parent. The between border is rendered when the adjacent paragraph
	// has the same border and indent properties. Paragraph borders cannot
	// be partially updated. When making changes to a paragraph border the
	// new border must be specified in its entirety.
	BorderBetween *ParagraphBorder `json:"borderBetween,omitempty"`

	// BorderBottom: The border at the bottom of this paragraph. If unset,
	// the value is inherited from the parent. The bottom border is rendered
	// when the paragraph below has different border and indent properties.
	// Paragraph borders cannot be partially updated. When making changes to
	// a paragraph border the new border must be specified in its entirety.
	BorderBottom *ParagraphBorder `json:"borderBottom,omitempty"`

	// BorderLeft: The border to the left of this paragraph. If unset, the
	// value is inherited from the parent. Paragraph borders cannot be
	// partially updated. When making changes to a paragraph border the new
	// border must be specified in its entirety.
	BorderLeft *ParagraphBorder `json:"borderLeft,omitempty"`

	// BorderRight: The border to the right of this paragraph. If unset, the
	// value is inherited from the parent. Paragraph borders cannot be
	// partially updated. When making changes to a paragraph border the new
	// border must be specified in its entirety.
	BorderRight *ParagraphBorder `json:"borderRight,omitempty"`

	// BorderTop: The border at the top of this paragraph. If unset, the
	// value is inherited from the parent. The top border is rendered when
	// the paragraph above has different border and indent properties.
	// Paragraph borders cannot be partially updated. When making changes to
	// a paragraph border the new border must be specified in its entirety.
	BorderTop *ParagraphBorder `json:"borderTop,omitempty"`

	// Direction: The text direction of this paragraph. If unset, the value
	// defaults to LEFT_TO_RIGHT since paragraph direction is not inherited.
	//
	// Possible values:
	//   "CONTENT_DIRECTION_UNSPECIFIED" - The content direction is
	// unspecified.
	//   "LEFT_TO_RIGHT" - The content goes from left to right.
	//   "RIGHT_TO_LEFT" - The content goes from right to left.
	Direction string `json:"direction,omitempty"`

	// HeadingId: The heading ID of the paragraph. If empty, then this
	// paragraph is not a heading. This property is read-only.
	HeadingId string `json:"headingId,omitempty"`

	// IndentEnd: The amount of indentation for the paragraph on the side
	// that corresponds to the end of the text, based on the current
	// paragraph direction. If unset, the value is inherited from the
	// parent.
	IndentEnd *Dimension `json:"indentEnd,omitempty"`

	// IndentFirstLine: The amount of indentation for the first line of the
	// paragraph. If unset, the value is inherited from the parent.
	IndentFirstLine *Dimension `json:"indentFirstLine,omitempty"`

	// IndentStart: The amount of indentation for the paragraph on the side
	// that corresponds to the start of the text, based on the current
	// paragraph direction. If unset, the value is inherited from the
	// parent.
	IndentStart *Dimension `json:"indentStart,omitempty"`

	// KeepLinesTogether: Whether all lines of the paragraph should be laid
	// out on the same page or column if possible. If unset, the value is
	// inherited from the parent.
	KeepLinesTogether bool `json:"keepLinesTogether,omitempty"`

	// KeepWithNext: Whether at least a part of this paragraph should be
	// laid out on the same page or column as the next paragraph if
	// possible. If unset, the value is inherited from the parent.
	KeepWithNext bool `json:"keepWithNext,omitempty"`

	// LineSpacing: The amount of space between lines, as a percentage of
	// normal, where normal is represented as 100.0. If unset, the value is
	// inherited from the parent.
	LineSpacing float64 `json:"lineSpacing,omitempty"`

	// NamedStyleType: The named style type of the paragraph. Since updating
	// the named style type affects other properties within ParagraphStyle,
	// the named style type is applied before the other properties are
	// updated.
	//
	// Possible values:
	//   "NAMED_STYLE_TYPE_UNSPECIFIED" - The type of named style is
	// unspecified.
	//   "NORMAL_TEXT" - Normal text.
	//   "TITLE" - Title.
	//   "SUBTITLE" - Subtitle.
	//   "HEADING_1" - Heading 1.
	//   "HEADING_2" - Heading 2.
	//   "HEADING_3" - Heading 3.
	//   "HEADING_4" - Heading 4.
	//   "HEADING_5" - Heading 5.
	//   "HEADING_6" - Heading 6.
	NamedStyleType string `json:"namedStyleType,omitempty"`

	// Shading: The shading of the paragraph. If unset, the value is
	// inherited from the parent.
	Shading *Shading `json:"shading,omitempty"`

	// SpaceAbove: The amount of extra space above the paragraph. If unset,
	// the value is inherited from the parent.
	SpaceAbove *Dimension `json:"spaceAbove,omitempty"`

	// SpaceBelow: The amount of extra space below the paragraph. If unset,
	// the value is inherited from the parent.
	SpaceBelow *Dimension `json:"spaceBelow,omitempty"`

	// SpacingMode: The spacing mode for the paragraph.
	//
	// Possible values:
	//   "SPACING_MODE_UNSPECIFIED" - The spacing mode is inherited from the
	// parent.
	//   "NEVER_COLLAPSE" - Paragraph spacing is always rendered.
	//   "COLLAPSE_LISTS" - Paragraph spacing is skipped between list
	// elements.
	SpacingMode string `json:"spacingMode,omitempty"`

	// TabStops: A list of the tab stops for this paragraph. The list of tab
	// stops is not inherited. This property is read-only.
	TabStops []*TabStop `json:"tabStops,omitempty"`

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

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

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

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

// ParagraphStyleSuggestionState: A mask that indicates which of the
// fields on the base ParagraphStyle have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type ParagraphStyleSuggestionState struct {
	// AlignmentSuggested: Indicates if there was a suggested change to
	// alignment.
	AlignmentSuggested bool `json:"alignmentSuggested,omitempty"`

	// AvoidWidowAndOrphanSuggested: Indicates if there was a suggested
	// change to avoid_widow_and_orphan.
	AvoidWidowAndOrphanSuggested bool `json:"avoidWidowAndOrphanSuggested,omitempty"`

	// BorderBetweenSuggested: Indicates if there was a suggested change to
	// border_between.
	BorderBetweenSuggested bool `json:"borderBetweenSuggested,omitempty"`

	// BorderBottomSuggested: Indicates if there was a suggested change to
	// border_bottom.
	BorderBottomSuggested bool `json:"borderBottomSuggested,omitempty"`

	// BorderLeftSuggested: Indicates if there was a suggested change to
	// border_left.
	BorderLeftSuggested bool `json:"borderLeftSuggested,omitempty"`

	// BorderRightSuggested: Indicates if there was a suggested change to
	// border_right.
	BorderRightSuggested bool `json:"borderRightSuggested,omitempty"`

	// BorderTopSuggested: Indicates if there was a suggested change to
	// border_top.
	BorderTopSuggested bool `json:"borderTopSuggested,omitempty"`

	// DirectionSuggested: Indicates if there was a suggested change to
	// direction.
	DirectionSuggested bool `json:"directionSuggested,omitempty"`

	// HeadingIdSuggested: Indicates if there was a suggested change to
	// heading_id.
	HeadingIdSuggested bool `json:"headingIdSuggested,omitempty"`

	// IndentEndSuggested: Indicates if there was a suggested change to
	// indent_end.
	IndentEndSuggested bool `json:"indentEndSuggested,omitempty"`

	// IndentFirstLineSuggested: Indicates if there was a suggested change
	// to indent_first_line.
	IndentFirstLineSuggested bool `json:"indentFirstLineSuggested,omitempty"`

	// IndentStartSuggested: Indicates if there was a suggested change to
	// indent_start.
	IndentStartSuggested bool `json:"indentStartSuggested,omitempty"`

	// KeepLinesTogetherSuggested: Indicates if there was a suggested change
	// to keep_lines_together.
	KeepLinesTogetherSuggested bool `json:"keepLinesTogetherSuggested,omitempty"`

	// KeepWithNextSuggested: Indicates if there was a suggested change to
	// keep_with_next.
	KeepWithNextSuggested bool `json:"keepWithNextSuggested,omitempty"`

	// LineSpacingSuggested: Indicates if there was a suggested change to
	// line_spacing.
	LineSpacingSuggested bool `json:"lineSpacingSuggested,omitempty"`

	// NamedStyleTypeSuggested: Indicates if there was a suggested change to
	// named_style_type.
	NamedStyleTypeSuggested bool `json:"namedStyleTypeSuggested,omitempty"`

	// ShadingSuggestionState: A mask that indicates which of the fields in
	// shading have been changed in this suggestion.
	ShadingSuggestionState *ShadingSuggestionState `json:"shadingSuggestionState,omitempty"`

	// SpaceAboveSuggested: Indicates if there was a suggested change to
	// space_above.
	SpaceAboveSuggested bool `json:"spaceAboveSuggested,omitempty"`

	// SpaceBelowSuggested: Indicates if there was a suggested change to
	// space_below.
	SpaceBelowSuggested bool `json:"spaceBelowSuggested,omitempty"`

	// SpacingModeSuggested: Indicates if there was a suggested change to
	// spacing_mode.
	SpacingModeSuggested bool `json:"spacingModeSuggested,omitempty"`

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

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

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

// Person: A person or email address mentioned in a document. These
// mentions behave as a single, immutable element containing the
// person's name or email address.
type Person struct {
	// PersonId: Output only. The unique ID of this link.
	PersonId string `json:"personId,omitempty"`

	// PersonProperties: Output only. The properties of this Person. This
	// field is always present.
	PersonProperties *PersonProperties `json:"personProperties,omitempty"`

	// SuggestedDeletionIds: IDs for suggestions that remove this person
	// link from the document. A Person might have multiple deletion IDs if,
	// for example, multiple users suggest to delete it. If empty, then this
	// person link isn't suggested for deletion.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: IDs for suggestions that insert this person
	// link into the document. A Person might have multiple insertion IDs if
	// it is a nested suggested change (a suggestion within a suggestion
	// made by a different user, for example). If empty, then this person
	// link isn't a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// Person, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this Person.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// PersonProperties: Properties specific to a linked Person.
type PersonProperties struct {
	// Email: Output only. The email address linked to this Person. This
	// field is always present.
	Email string `json:"email,omitempty"`

	// Name: Output only. The name of the person if it is displayed in the
	// link text instead of the person's email address.
	Name string `json:"name,omitempty"`

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

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

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

// PositionedObject: An object that is tethered to a Paragraph and
// positioned relative to the beginning of the paragraph. A
// PositionedObject contains an EmbeddedObject such as an image.
type PositionedObject struct {
	// ObjectId: The ID of this positioned object.
	ObjectId string `json:"objectId,omitempty"`

	// PositionedObjectProperties: The properties of this positioned object.
	PositionedObjectProperties *PositionedObjectProperties `json:"positionedObjectProperties,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionId: The suggested insertion ID. If empty, then this
	// is not a suggested insertion.
	SuggestedInsertionId string `json:"suggestedInsertionId,omitempty"`

	// SuggestedPositionedObjectPropertiesChanges: The suggested changes to
	// the positioned object properties, keyed by suggestion ID.
	SuggestedPositionedObjectPropertiesChanges map[string]SuggestedPositionedObjectProperties `json:"suggestedPositionedObjectPropertiesChanges,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *PositionedObject) MarshalJSON() ([]byte, error) {
	type NoMethod PositionedObject
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PositionedObjectPositioning: The positioning of a PositionedObject.
// The positioned object is positioned relative to the beginning of the
// Paragraph it is tethered to.
type PositionedObjectPositioning struct {
	// Layout: The layout of this positioned object.
	//
	// Possible values:
	//   "POSITIONED_OBJECT_LAYOUT_UNSPECIFIED" - The layout is unspecified.
	//   "WRAP_TEXT" - The text wraps around the positioned object.
	//   "BREAK_LEFT" - Breaks text such that the positioned object is on
	// the left and text is on the right.
	//   "BREAK_RIGHT" - Breaks text such that the positioned object is on
	// the right and text is on the left.
	//   "BREAK_LEFT_RIGHT" - Breaks text such that there is no text on the
	// left or right of the positioned object.
	//   "IN_FRONT_OF_TEXT" - The positioned object is in front of the text.
	//   "BEHIND_TEXT" - The positioned object is behind the text.
	Layout string `json:"layout,omitempty"`

	// LeftOffset: The offset of the left edge of the positioned object
	// relative to the beginning of the Paragraph it is tethered to. The
	// exact positioning of the object can depend on other content in the
	// document and the document's styling.
	LeftOffset *Dimension `json:"leftOffset,omitempty"`

	// TopOffset: The offset of the top edge of the positioned object
	// relative to the beginning of the Paragraph it is tethered to. The
	// exact positioning of the object can depend on other content in the
	// document and the document's styling.
	TopOffset *Dimension `json:"topOffset,omitempty"`

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

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

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

// PositionedObjectPositioningSuggestionState: A mask that indicates
// which of the fields on the base PositionedObjectPositioning have been
// changed in this suggestion. For any field set to true, there is a new
// suggested value.
type PositionedObjectPositioningSuggestionState struct {
	// LayoutSuggested: Indicates if there was a suggested change to layout.
	LayoutSuggested bool `json:"layoutSuggested,omitempty"`

	// LeftOffsetSuggested: Indicates if there was a suggested change to
	// left_offset.
	LeftOffsetSuggested bool `json:"leftOffsetSuggested,omitempty"`

	// TopOffsetSuggested: Indicates if there was a suggested change to
	// top_offset.
	TopOffsetSuggested bool `json:"topOffsetSuggested,omitempty"`

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

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

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

// PositionedObjectProperties: Properties of a PositionedObject.
type PositionedObjectProperties struct {
	// EmbeddedObject: The embedded object of this positioned object.
	EmbeddedObject *EmbeddedObject `json:"embeddedObject,omitempty"`

	// Positioning: The positioning of this positioned object relative to
	// the newline of the Paragraph that references this positioned object.
	Positioning *PositionedObjectPositioning `json:"positioning,omitempty"`

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

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

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

// PositionedObjectPropertiesSuggestionState: A mask that indicates
// which of the fields on the base PositionedObjectProperties have been
// changed in this suggestion. For any field set to true, there is a new
// suggested value.
type PositionedObjectPropertiesSuggestionState struct {
	// EmbeddedObjectSuggestionState: A mask that indicates which of the
	// fields in embedded_object have been changed in this suggestion.
	EmbeddedObjectSuggestionState *EmbeddedObjectSuggestionState `json:"embeddedObjectSuggestionState,omitempty"`

	// PositioningSuggestionState: A mask that indicates which of the fields
	// in positioning have been changed in this suggestion.
	PositioningSuggestionState *PositionedObjectPositioningSuggestionState `json:"positioningSuggestionState,omitempty"`

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

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

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

// Range: Specifies a contiguous range of text.
type Range struct {
	// EndIndex: The zero-based end index of this range, exclusive, in
	// UTF-16 code units. In all current uses, an end index must be
	// provided. This field is an Int32Value in order to accommodate future
	// use cases with open-ended ranges.
	EndIndex int64 `json:"endIndex,omitempty"`

	// SegmentId: The ID of the header, footer or footnote that this range
	// is contained in. An empty segment ID signifies the document's body.
	SegmentId string `json:"segmentId,omitempty"`

	// StartIndex: The zero-based start index of this range, in UTF-16 code
	// units. In all current uses, a start index must be provided. This
	// field is an Int32Value in order to accommodate future use cases with
	// open-ended ranges.
	StartIndex int64 `json:"startIndex,omitempty"`

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

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

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

// ReplaceAllTextRequest: Replaces all instances of text matching a
// criteria with replace text.
type ReplaceAllTextRequest struct {
	// ContainsText: Finds text in the document matching this substring.
	ContainsText *SubstringMatchCriteria `json:"containsText,omitempty"`

	// ReplaceText: The text that will replace the matched text.
	ReplaceText string `json:"replaceText,omitempty"`

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

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

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

// ReplaceAllTextResponse: The result of replacing text.
type ReplaceAllTextResponse struct {
	// OccurrencesChanged: The number of occurrences changed by replacing
	// all text.
	OccurrencesChanged int64 `json:"occurrencesChanged,omitempty"`

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

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

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

// ReplaceImageRequest: Replaces an existing image with a new image.
// Replacing an image removes some image effects from the existing image
// in order to mirror the behavior of the Docs editor.
type ReplaceImageRequest struct {
	// ImageObjectId: The ID of the existing image that will be replaced.
	// The ID can be retrieved from the response of a get request.
	ImageObjectId string `json:"imageObjectId,omitempty"`

	// ImageReplaceMethod: The replacement method.
	//
	// Possible values:
	//   "IMAGE_REPLACE_METHOD_UNSPECIFIED" - Unspecified image replace
	// method. This value must not be used.
	//   "CENTER_CROP" - Scales and centers the image to fill the bounds of
	// the original image. The image may be cropped in order to fill the
	// original image's bounds. The rendered size of the image will be the
	// same as the original image.
	ImageReplaceMethod string `json:"imageReplaceMethod,omitempty"`

	// Uri: The URI of the new image. The image is fetched once at insertion
	// time and a copy is stored for display inside the document. Images
	// must be less than 50MB, cannot exceed 25 megapixels, and must be in
	// PNG, JPEG, or GIF format. The provided URI can't surpass 2 KB in
	// length. The URI is saved with the image, and exposed through the
	// ImageProperties.source_uri field.
	Uri string `json:"uri,omitempty"`

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

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

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

// ReplaceNamedRangeContentRequest: Replaces the contents of the
// specified NamedRange or NamedRanges with the given replacement
// content. Note that an individual NamedRange may consist of multiple
// discontinuous ranges. In this case, only the content in the first
// range will be replaced. The other ranges and their content will be
// deleted. In cases where replacing or deleting any ranges would result
// in an invalid document structure, a 400 bad request error is
// returned.
type ReplaceNamedRangeContentRequest struct {
	// NamedRangeId: The ID of the named range whose content will be
	// replaced. If there is no named range with the given ID a 400 bad
	// request error is returned.
	NamedRangeId string `json:"namedRangeId,omitempty"`

	// NamedRangeName: The name of the NamedRanges whose content will be
	// replaced. If there are multiple named ranges with the given name,
	// then the content of each one will be replaced. If there are no named
	// ranges with the given name, then the request will be a no-op.
	NamedRangeName string `json:"namedRangeName,omitempty"`

	// Text: Replaces the content of the specified named range(s) with the
	// given text.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NamedRangeId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *ReplaceNamedRangeContentRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceNamedRangeContentRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Request: A single update to apply to a document.
type Request struct {
	// CreateFooter: Creates a footer.
	CreateFooter *CreateFooterRequest `json:"createFooter,omitempty"`

	// CreateFootnote: Creates a footnote.
	CreateFootnote *CreateFootnoteRequest `json:"createFootnote,omitempty"`

	// CreateHeader: Creates a header.
	CreateHeader *CreateHeaderRequest `json:"createHeader,omitempty"`

	// CreateNamedRange: Creates a named range.
	CreateNamedRange *CreateNamedRangeRequest `json:"createNamedRange,omitempty"`

	// CreateParagraphBullets: Creates bullets for paragraphs.
	CreateParagraphBullets *CreateParagraphBulletsRequest `json:"createParagraphBullets,omitempty"`

	// DeleteContentRange: Deletes content from the document.
	DeleteContentRange *DeleteContentRangeRequest `json:"deleteContentRange,omitempty"`

	// DeleteFooter: Deletes a footer from the document.
	DeleteFooter *DeleteFooterRequest `json:"deleteFooter,omitempty"`

	// DeleteHeader: Deletes a header from the document.
	DeleteHeader *DeleteHeaderRequest `json:"deleteHeader,omitempty"`

	// DeleteNamedRange: Deletes a named range.
	DeleteNamedRange *DeleteNamedRangeRequest `json:"deleteNamedRange,omitempty"`

	// DeleteParagraphBullets: Deletes bullets from paragraphs.
	DeleteParagraphBullets *DeleteParagraphBulletsRequest `json:"deleteParagraphBullets,omitempty"`

	// DeletePositionedObject: Deletes a positioned object from the
	// document.
	DeletePositionedObject *DeletePositionedObjectRequest `json:"deletePositionedObject,omitempty"`

	// DeleteTableColumn: Deletes a column from a table.
	DeleteTableColumn *DeleteTableColumnRequest `json:"deleteTableColumn,omitempty"`

	// DeleteTableRow: Deletes a row from a table.
	DeleteTableRow *DeleteTableRowRequest `json:"deleteTableRow,omitempty"`

	// InsertInlineImage: Inserts an inline image at the specified location.
	InsertInlineImage *InsertInlineImageRequest `json:"insertInlineImage,omitempty"`

	// InsertPageBreak: Inserts a page break at the specified location.
	InsertPageBreak *InsertPageBreakRequest `json:"insertPageBreak,omitempty"`

	// InsertSectionBreak: Inserts a section break at the specified
	// location.
	InsertSectionBreak *InsertSectionBreakRequest `json:"insertSectionBreak,omitempty"`

	// InsertTable: Inserts a table at the specified location.
	InsertTable *InsertTableRequest `json:"insertTable,omitempty"`

	// InsertTableColumn: Inserts an empty column into a table.
	InsertTableColumn *InsertTableColumnRequest `json:"insertTableColumn,omitempty"`

	// InsertTableRow: Inserts an empty row into a table.
	InsertTableRow *InsertTableRowRequest `json:"insertTableRow,omitempty"`

	// InsertText: Inserts text at the specified location.
	InsertText *InsertTextRequest `json:"insertText,omitempty"`

	// MergeTableCells: Merges cells in a table.
	MergeTableCells *MergeTableCellsRequest `json:"mergeTableCells,omitempty"`

	// ReplaceAllText: Replaces all instances of the specified text.
	ReplaceAllText *ReplaceAllTextRequest `json:"replaceAllText,omitempty"`

	// ReplaceImage: Replaces an image in the document.
	ReplaceImage *ReplaceImageRequest `json:"replaceImage,omitempty"`

	// ReplaceNamedRangeContent: Replaces the content in a named range.
	ReplaceNamedRangeContent *ReplaceNamedRangeContentRequest `json:"replaceNamedRangeContent,omitempty"`

	// UnmergeTableCells: Unmerges cells in a table.
	UnmergeTableCells *UnmergeTableCellsRequest `json:"unmergeTableCells,omitempty"`

	// UpdateDocumentStyle: Updates the style of the document.
	UpdateDocumentStyle *UpdateDocumentStyleRequest `json:"updateDocumentStyle,omitempty"`

	// UpdateParagraphStyle: Updates the paragraph style at the specified
	// range.
	UpdateParagraphStyle *UpdateParagraphStyleRequest `json:"updateParagraphStyle,omitempty"`

	// UpdateSectionStyle: Updates the section style of the specified range.
	UpdateSectionStyle *UpdateSectionStyleRequest `json:"updateSectionStyle,omitempty"`

	// UpdateTableCellStyle: Updates the style of table cells.
	UpdateTableCellStyle *UpdateTableCellStyleRequest `json:"updateTableCellStyle,omitempty"`

	// UpdateTableColumnProperties: Updates the properties of columns in a
	// table.
	UpdateTableColumnProperties *UpdateTableColumnPropertiesRequest `json:"updateTableColumnProperties,omitempty"`

	// UpdateTableRowStyle: Updates the row style in a table.
	UpdateTableRowStyle *UpdateTableRowStyleRequest `json:"updateTableRowStyle,omitempty"`

	// UpdateTextStyle: Updates the text style at the specified range.
	UpdateTextStyle *UpdateTextStyleRequest `json:"updateTextStyle,omitempty"`

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

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

	// CreateFootnote: The result of creating a footnote.
	CreateFootnote *CreateFootnoteResponse `json:"createFootnote,omitempty"`

	// CreateHeader: The result of creating a header.
	CreateHeader *CreateHeaderResponse `json:"createHeader,omitempty"`

	// CreateNamedRange: The result of creating a named range.
	CreateNamedRange *CreateNamedRangeResponse `json:"createNamedRange,omitempty"`

	// InsertInlineImage: The result of inserting an inline image.
	InsertInlineImage *InsertInlineImageResponse `json:"insertInlineImage,omitempty"`

	// InsertInlineSheetsChart: The result of inserting an inline Google
	// Sheets chart.
	InsertInlineSheetsChart *InsertInlineSheetsChartResponse `json:"insertInlineSheetsChart,omitempty"`

	// ReplaceAllText: The result of replacing text.
	ReplaceAllText *ReplaceAllTextResponse `json:"replaceAllText,omitempty"`

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

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

// RgbColor: An RGB color.
type RgbColor struct {
	// Blue: The blue component of the color, from 0.0 to 1.0.
	Blue float64 `json:"blue,omitempty"`

	// Green: The green component of the color, from 0.0 to 1.0.
	Green float64 `json:"green,omitempty"`

	// Red: The red component of the color, from 0.0 to 1.0.
	Red float64 `json:"red,omitempty"`

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

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

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

func (s *RgbColor) UnmarshalJSON(data []byte) error {
	type NoMethod RgbColor
	var s1 struct {
		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.Blue = float64(s1.Blue)
	s.Green = float64(s1.Green)
	s.Red = float64(s1.Red)
	return nil
}

// RichLink: A link to a Google resource (e.g., a file in Drive, a
// YouTube video, a Calendar event, etc.).
type RichLink struct {
	// RichLinkId: Output only. The ID of this link.
	RichLinkId string `json:"richLinkId,omitempty"`

	// RichLinkProperties: Output only. The properties of this RichLink.
	// This field is always present.
	RichLinkProperties *RichLinkProperties `json:"richLinkProperties,omitempty"`

	// SuggestedDeletionIds: IDs for suggestions that remove this link from
	// the document. A RichLink might have multiple deletion IDs if, for
	// example, multiple users suggest to delete it. If empty, then this
	// person link isn't suggested for deletion.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: IDs for suggestions that insert this link into
	// the document. A RichLink might have multiple insertion IDs if it is a
	// nested suggested change (a suggestion within a suggestion made by a
	// different user, for example). If empty, then this person link isn't a
	// suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// RichLink, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this RichLink.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// RichLinkProperties: Properties specific to a RichLink.
type RichLinkProperties struct {
	// MimeType: Output only. The MIME type
	// (https://developers.google.com/drive/api/v3/mime-types) of the
	// RichLink, if there is one (i.e., when it is a file in Drive).
	MimeType string `json:"mimeType,omitempty"`

	// Title: Output only. The title of the RichLink as displayed in the
	// link. This title matches the title of the linked resource at the time
	// of the insertion or last update of the link. This field is always
	// present.
	Title string `json:"title,omitempty"`

	// Uri: Output only. The URI to the RichLink. This is always present.
	Uri string `json:"uri,omitempty"`

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

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

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

// SectionBreak: A StructuralElement representing a section break. A
// section is a range of content which has the same SectionStyle. A
// section break represents the start of a new section, and the section
// style applies to the section after the section break. The document
// body always begins with a section break.
type SectionBreak struct {
	// SectionStyle: The style of the section after this section break.
	SectionStyle *SectionStyle `json:"sectionStyle,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A SectionBreak
	// may have multiple insertion IDs if it is a nested suggested change.
	// If empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

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

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

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

// SectionColumnProperties: Properties that apply to a section's column.
type SectionColumnProperties struct {
	// PaddingEnd: The padding at the end of the column.
	PaddingEnd *Dimension `json:"paddingEnd,omitempty"`

	// Width: Output only. The width of the column.
	Width *Dimension `json:"width,omitempty"`

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

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

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

// SectionStyle: The styling that applies to a section.
type SectionStyle struct {
	// ColumnProperties: The section's columns properties. If empty, the
	// section contains one column with the default properties in the Docs
	// editor. A section can be updated to have no more than three columns.
	// When updating this property, setting a concrete value is required.
	// Unsetting this property will result in a 400 bad request error.
	ColumnProperties []*SectionColumnProperties `json:"columnProperties,omitempty"`

	// ColumnSeparatorStyle: The style of column separators. This style can
	// be set even when there is one column in the section. When updating
	// this property, setting a concrete value is required. Unsetting this
	// property results in a 400 bad request error.
	//
	// Possible values:
	//   "COLUMN_SEPARATOR_STYLE_UNSPECIFIED" - An unspecified column
	// separator style.
	//   "NONE" - No column separator lines between columns.
	//   "BETWEEN_EACH_COLUMN" - Renders a column separator line between
	// each column.
	ColumnSeparatorStyle string `json:"columnSeparatorStyle,omitempty"`

	// ContentDirection: The content direction of this section. If unset,
	// the value defaults to LEFT_TO_RIGHT. When updating this property,
	// setting a concrete value is required. Unsetting this property results
	// in a 400 bad request error.
	//
	// Possible values:
	//   "CONTENT_DIRECTION_UNSPECIFIED" - The content direction is
	// unspecified.
	//   "LEFT_TO_RIGHT" - The content goes from left to right.
	//   "RIGHT_TO_LEFT" - The content goes from right to left.
	ContentDirection string `json:"contentDirection,omitempty"`

	// DefaultFooterId: The ID of the default footer. If unset, the value
	// inherits from the previous SectionBreak's SectionStyle. If the value
	// is unset in the first SectionBreak, it inherits from DocumentStyle's
	// default_footer_id. This property is read-only.
	DefaultFooterId string `json:"defaultFooterId,omitempty"`

	// DefaultHeaderId: The ID of the default header. If unset, the value
	// inherits from the previous SectionBreak's SectionStyle. If the value
	// is unset in the first SectionBreak, it inherits from DocumentStyle's
	// default_header_id. This property is read-only.
	DefaultHeaderId string `json:"defaultHeaderId,omitempty"`

	// EvenPageFooterId: The ID of the footer used only for even pages. If
	// the value of DocumentStyle's use_even_page_header_footer is true,
	// this value is used for the footers on even pages in the section. If
	// it is false, the footers on even pages uses the default_footer_id. If
	// unset, the value inherits from the previous SectionBreak's
	// SectionStyle. If the value is unset in the first SectionBreak, it
	// inherits from DocumentStyle's even_page_footer_id. This property is
	// read-only.
	EvenPageFooterId string `json:"evenPageFooterId,omitempty"`

	// EvenPageHeaderId: The ID of the header used only for even pages. If
	// the value of DocumentStyle's use_even_page_header_footer is true,
	// this value is used for the headers on even pages in the section. If
	// it is false, the headers on even pages uses the default_header_id. If
	// unset, the value inherits from the previous SectionBreak's
	// SectionStyle. If the value is unset in the first SectionBreak, it
	// inherits from DocumentStyle's even_page_header_id. This property is
	// read-only.
	EvenPageHeaderId string `json:"evenPageHeaderId,omitempty"`

	// FirstPageFooterId: The ID of the footer used only for the first page
	// of the section. If use_first_page_header_footer is true, this value
	// is used for the footer on the first page of the section. If it is
	// false, the footer on the first page of the section uses the
	// default_footer_id. If unset, the value inherits from the previous
	// SectionBreak's SectionStyle. If the value is unset in the first
	// SectionBreak, it inherits from DocumentStyle's first_page_footer_id.
	// This property is read-only.
	FirstPageFooterId string `json:"firstPageFooterId,omitempty"`

	// FirstPageHeaderId: The ID of the header used only for the first page
	// of the section. If use_first_page_header_footer is true, this value
	// is used for the header on the first page of the section. If it is
	// false, the header on the first page of the section uses the
	// default_header_id. If unset, the value inherits from the previous
	// SectionBreak's SectionStyle. If the value is unset in the first
	// SectionBreak, it inherits from DocumentStyle's first_page_header_id.
	// This property is read-only.
	FirstPageHeaderId string `json:"firstPageHeaderId,omitempty"`

	// MarginBottom: The bottom page margin of the section. If unset, uses
	// margin_bottom from DocumentStyle. When updating this property,
	// setting a concrete value is required. Unsetting this property results
	// in a 400 bad request error.
	MarginBottom *Dimension `json:"marginBottom,omitempty"`

	// MarginFooter: The footer margin of the section. If unset, uses
	// margin_footer from DocumentStyle. If updated,
	// use_custom_header_footer_margins is set to true on DocumentStyle. The
	// value of use_custom_header_footer_margins on DocumentStyle indicates
	// if a footer margin is being respected for this section When updating
	// this property, setting a concrete value is required. Unsetting this
	// property results in a 400 bad request error.
	MarginFooter *Dimension `json:"marginFooter,omitempty"`

	// MarginHeader: The header margin of the section. If unset, uses
	// margin_header from DocumentStyle. If updated,
	// use_custom_header_footer_margins is set to true on DocumentStyle. The
	// value of use_custom_header_footer_margins on DocumentStyle indicates
	// if a header margin is being respected for this section. When updating
	// this property, setting a concrete value is required. Unsetting this
	// property results in a 400 bad request error.
	MarginHeader *Dimension `json:"marginHeader,omitempty"`

	// MarginLeft: The left page margin of the section. If unset, uses
	// margin_left from DocumentStyle. Updating left margin causes columns
	// in this section to resize. Since the margin affects column width, it
	// is applied before column properties. When updating this property,
	// setting a concrete value is required. Unsetting this property results
	// in a 400 bad request error.
	MarginLeft *Dimension `json:"marginLeft,omitempty"`

	// MarginRight: The right page margin of the section. If unset, uses
	// margin_right from DocumentStyle. Updating right margin causes columns
	// in this section to resize. Since the margin affects column width, it
	// is applied before column properties. When updating this property,
	// setting a concrete value is required. Unsetting this property results
	// in a 400 bad request error.
	MarginRight *Dimension `json:"marginRight,omitempty"`

	// MarginTop: The top page margin of the section. If unset, uses
	// margin_top from DocumentStyle. When updating this property, setting a
	// concrete value is required. Unsetting this property results in a 400
	// bad request error.
	MarginTop *Dimension `json:"marginTop,omitempty"`

	// PageNumberStart: The page number from which to start counting the
	// number of pages for this section. If unset, page numbering continues
	// from the previous section. If the value is unset in the first
	// SectionBreak, refer to DocumentStyle's page_number_start. When
	// updating this property, setting a concrete value is required.
	// Unsetting this property results in a 400 bad request error.
	PageNumberStart int64 `json:"pageNumberStart,omitempty"`

	// SectionType: Output only. The type of section.
	//
	// Possible values:
	//   "SECTION_TYPE_UNSPECIFIED" - The section type is unspecified.
	//   "CONTINUOUS" - The section starts immediately after the last
	// paragraph of the previous section.
	//   "NEXT_PAGE" - The section starts on the next page.
	SectionType string `json:"sectionType,omitempty"`

	// UseFirstPageHeaderFooter: Indicates whether to use the first page
	// header / footer IDs for the first page of the section. If unset, it
	// inherits from DocumentStyle's use_first_page_header_footer for the
	// first section. If the value is unset for subsequent sectors, it
	// should be interpreted as false. When updating this property, setting
	// a concrete value is required. Unsetting this property results in a
	// 400 bad request error.
	UseFirstPageHeaderFooter bool `json:"useFirstPageHeaderFooter,omitempty"`

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

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

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

// Shading: The shading of a paragraph.
type Shading struct {
	// BackgroundColor: The background color of this paragraph shading.
	BackgroundColor *OptionalColor `json:"backgroundColor,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackgroundColor") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *Shading) MarshalJSON() ([]byte, error) {
	type NoMethod Shading
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShadingSuggestionState: A mask that indicates which of the fields on
// the base Shading have been changed in this suggested change. For any
// field set to true, there is a new suggested value.
type ShadingSuggestionState struct {
	// BackgroundColorSuggested: Indicates if there was a suggested change
	// to the Shading.
	BackgroundColorSuggested bool `json:"backgroundColorSuggested,omitempty"`

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

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

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

// SheetsChartReference: A reference to a linked chart embedded from
// Google Sheets.
type SheetsChartReference struct {
	// ChartId: The ID of the specific chart in the Google Sheets
	// spreadsheet that is embedded.
	ChartId int64 `json:"chartId,omitempty"`

	// SpreadsheetId: The ID of the Google Sheets spreadsheet that contains
	// the source chart.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChartId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *SheetsChartReference) MarshalJSON() ([]byte, error) {
	type NoMethod SheetsChartReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SheetsChartReferenceSuggestionState: A mask that indicates which of
// the fields on the base SheetsChartReference have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type SheetsChartReferenceSuggestionState struct {
	// ChartIdSuggested: Indicates if there was a suggested change to
	// chart_id.
	ChartIdSuggested bool `json:"chartIdSuggested,omitempty"`

	// SpreadsheetIdSuggested: Indicates if there was a suggested change to
	// spreadsheet_id.
	SpreadsheetIdSuggested bool `json:"spreadsheetIdSuggested,omitempty"`

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

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

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

// Size: A width and height.
type Size struct {
	// Height: The height of the object.
	Height *Dimension `json:"height,omitempty"`

	// Width: The width of the object.
	Width *Dimension `json:"width,omitempty"`

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

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

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

// SizeSuggestionState: A mask that indicates which of the fields on the
// base Size have been changed in this suggestion. For any field set to
// true, the Size has a new suggested value.
type SizeSuggestionState struct {
	// HeightSuggested: Indicates if there was a suggested change to height.
	HeightSuggested bool `json:"heightSuggested,omitempty"`

	// WidthSuggested: Indicates if there was a suggested change to width.
	WidthSuggested bool `json:"widthSuggested,omitempty"`

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

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

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

// StructuralElement: A StructuralElement describes content that
// provides structure to the document.
type StructuralElement struct {
	// EndIndex: The zero-based end index of this structural element,
	// exclusive, in UTF-16 code units.
	EndIndex int64 `json:"endIndex,omitempty"`

	// Paragraph: A paragraph type of structural element.
	Paragraph *Paragraph `json:"paragraph,omitempty"`

	// SectionBreak: A section break type of structural element.
	SectionBreak *SectionBreak `json:"sectionBreak,omitempty"`

	// StartIndex: The zero-based start index of this structural element, in
	// UTF-16 code units.
	StartIndex int64 `json:"startIndex,omitempty"`

	// Table: A table type of structural element.
	Table *Table `json:"table,omitempty"`

	// TableOfContents: A table of contents type of structural element.
	TableOfContents *TableOfContents `json:"tableOfContents,omitempty"`

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

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

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

// SubstringMatchCriteria: A criteria that matches a specific string of
// text in the document.
type SubstringMatchCriteria struct {
	// MatchCase: Indicates whether the search should respect case: -
	// `True`: the search is case sensitive. - `False`: the search is case
	// insensitive.
	MatchCase bool `json:"matchCase,omitempty"`

	// Text: The text to search for in the document.
	Text string `json:"text,omitempty"`

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

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

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

// SuggestedBullet: A suggested change to a Bullet.
type SuggestedBullet struct {
	// Bullet: A Bullet that only includes the changes made in this
	// suggestion. This can be used along with the bullet_suggestion_state
	// to see which fields have changed and their new values.
	Bullet *Bullet `json:"bullet,omitempty"`

	// BulletSuggestionState: A mask that indicates which of the fields on
	// the base Bullet have been changed in this suggestion.
	BulletSuggestionState *BulletSuggestionState `json:"bulletSuggestionState,omitempty"`

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

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

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

// SuggestedDocumentStyle: A suggested change to the DocumentStyle.
type SuggestedDocumentStyle struct {
	// DocumentStyle: A DocumentStyle that only includes the changes made in
	// this suggestion. This can be used along with the
	// document_style_suggestion_state to see which fields have changed and
	// their new values.
	DocumentStyle *DocumentStyle `json:"documentStyle,omitempty"`

	// DocumentStyleSuggestionState: A mask that indicates which of the
	// fields on the base DocumentStyle have been changed in this
	// suggestion.
	DocumentStyleSuggestionState *DocumentStyleSuggestionState `json:"documentStyleSuggestionState,omitempty"`

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

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

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

// SuggestedInlineObjectProperties: A suggested change to
// InlineObjectProperties.
type SuggestedInlineObjectProperties struct {
	// InlineObjectProperties: An InlineObjectProperties that only includes
	// the changes made in this suggestion. This can be used along with the
	// inline_object_properties_suggestion_state to see which fields have
	// changed and their new values.
	InlineObjectProperties *InlineObjectProperties `json:"inlineObjectProperties,omitempty"`

	// InlineObjectPropertiesSuggestionState: A mask that indicates which of
	// the fields on the base InlineObjectProperties have been changed in
	// this suggestion.
	InlineObjectPropertiesSuggestionState *InlineObjectPropertiesSuggestionState `json:"inlineObjectPropertiesSuggestionState,omitempty"`

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

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

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

// SuggestedListProperties: A suggested change to ListProperties.
type SuggestedListProperties struct {
	// ListProperties: A ListProperties that only includes the changes made
	// in this suggestion. This can be used along with the
	// list_properties_suggestion_state to see which fields have changed and
	// their new values.
	ListProperties *ListProperties `json:"listProperties,omitempty"`

	// ListPropertiesSuggestionState: A mask that indicates which of the
	// fields on the base ListProperties have been changed in this
	// suggestion.
	ListPropertiesSuggestionState *ListPropertiesSuggestionState `json:"listPropertiesSuggestionState,omitempty"`

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

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

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

// SuggestedNamedStyles: A suggested change to the NamedStyles.
type SuggestedNamedStyles struct {
	// NamedStyles: A NamedStyles that only includes the changes made in
	// this suggestion. This can be used along with the
	// named_styles_suggestion_state to see which fields have changed and
	// their new values.
	NamedStyles *NamedStyles `json:"namedStyles,omitempty"`

	// NamedStylesSuggestionState: A mask that indicates which of the fields
	// on the base NamedStyles have been changed in this suggestion.
	NamedStylesSuggestionState *NamedStylesSuggestionState `json:"namedStylesSuggestionState,omitempty"`

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

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

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

// SuggestedParagraphStyle: A suggested change to a ParagraphStyle.
type SuggestedParagraphStyle struct {
	// ParagraphStyle: A ParagraphStyle that only includes the changes made
	// in this suggestion. This can be used along with the
	// paragraph_suggestion_state to see which fields have changed and their
	// new values.
	ParagraphStyle *ParagraphStyle `json:"paragraphStyle,omitempty"`

	// ParagraphStyleSuggestionState: A mask that indicates which of the
	// fields on the base ParagraphStyle have been changed in this
	// suggestion.
	ParagraphStyleSuggestionState *ParagraphStyleSuggestionState `json:"paragraphStyleSuggestionState,omitempty"`

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

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

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

// SuggestedPositionedObjectProperties: A suggested change to
// PositionedObjectProperties.
type SuggestedPositionedObjectProperties struct {
	// PositionedObjectProperties: A PositionedObjectProperties that only
	// includes the changes made in this suggestion. This can be used along
	// with the positioned_object_properties_suggestion_state to see which
	// fields have changed and their new values.
	PositionedObjectProperties *PositionedObjectProperties `json:"positionedObjectProperties,omitempty"`

	// PositionedObjectPropertiesSuggestionState: A mask that indicates
	// which of the fields on the base PositionedObjectProperties have been
	// changed in this suggestion.
	PositionedObjectPropertiesSuggestionState *PositionedObjectPropertiesSuggestionState `json:"positionedObjectPropertiesSuggestionState,omitempty"`

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

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

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

// SuggestedTableCellStyle: A suggested change to a TableCellStyle.
type SuggestedTableCellStyle struct {
	// TableCellStyle: A TableCellStyle that only includes the changes made
	// in this suggestion. This can be used along with the
	// table_cell_style_suggestion_state to see which fields have changed
	// and their new values.
	TableCellStyle *TableCellStyle `json:"tableCellStyle,omitempty"`

	// TableCellStyleSuggestionState: A mask that indicates which of the
	// fields on the base TableCellStyle have been changed in this
	// suggestion.
	TableCellStyleSuggestionState *TableCellStyleSuggestionState `json:"tableCellStyleSuggestionState,omitempty"`

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

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

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

// SuggestedTableRowStyle: A suggested change to a TableRowStyle.
type SuggestedTableRowStyle struct {
	// TableRowStyle: A TableRowStyle that only includes the changes made in
	// this suggestion. This can be used along with the
	// table_row_style_suggestion_state to see which fields have changed and
	// their new values.
	TableRowStyle *TableRowStyle `json:"tableRowStyle,omitempty"`

	// TableRowStyleSuggestionState: A mask that indicates which of the
	// fields on the base TableRowStyle have been changed in this
	// suggestion.
	TableRowStyleSuggestionState *TableRowStyleSuggestionState `json:"tableRowStyleSuggestionState,omitempty"`

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

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

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

// SuggestedTextStyle: A suggested change to a TextStyle.
type SuggestedTextStyle struct {
	// TextStyle: A TextStyle that only includes the changes made in this
	// suggestion. This can be used along with the
	// text_style_suggestion_state to see which fields have changed and
	// their new values.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

	// TextStyleSuggestionState: A mask that indicates which of the fields
	// on the base TextStyle have been changed in this suggestion.
	TextStyleSuggestionState *TextStyleSuggestionState `json:"textStyleSuggestionState,omitempty"`

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

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

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

// TabStop: A tab stop within a paragraph.
type TabStop struct {
	// Alignment: The alignment of this tab stop. If unset, the value
	// defaults to START.
	//
	// Possible values:
	//   "TAB_STOP_ALIGNMENT_UNSPECIFIED" - The tab stop alignment is
	// unspecified.
	//   "START" - The tab stop is aligned to the start of the line. This is
	// the default.
	//   "CENTER" - The tab stop is aligned to the center of the line.
	//   "END" - The tab stop is aligned to the end of the line.
	Alignment string `json:"alignment,omitempty"`

	// Offset: The offset between this tab stop and the start margin.
	Offset *Dimension `json:"offset,omitempty"`

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

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

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

// Table: A StructuralElement representing a table.
type Table struct {
	// Columns: Number of columns in the table. It is possible for a table
	// to be non-rectangular, so some rows may have a different number of
	// cells.
	Columns int64 `json:"columns,omitempty"`

	// Rows: Number of rows in the table.
	Rows int64 `json:"rows,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A Table may have
	// multiple insertion IDs if it is a nested suggested change. If empty,
	// then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// TableRows: The contents and style of each row.
	TableRows []*TableRow `json:"tableRows,omitempty"`

	// TableStyle: The style of the table.
	TableStyle *TableStyle `json:"tableStyle,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Columns") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *Table) MarshalJSON() ([]byte, error) {
	type NoMethod Table
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCell: The contents and style of a cell in a Table.
type TableCell struct {
	// Content: The content of the cell.
	Content []*StructuralElement `json:"content,omitempty"`

	// EndIndex: The zero-based end index of this cell, exclusive, in UTF-16
	// code units.
	EndIndex int64 `json:"endIndex,omitempty"`

	// StartIndex: The zero-based start index of this cell, in UTF-16 code
	// units.
	StartIndex int64 `json:"startIndex,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A TableCell may
	// have multiple insertion IDs if it is a nested suggested change. If
	// empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTableCellStyleChanges: The suggested changes to the table
	// cell style, keyed by suggestion ID.
	SuggestedTableCellStyleChanges map[string]SuggestedTableCellStyle `json:"suggestedTableCellStyleChanges,omitempty"`

	// TableCellStyle: The style of the cell.
	TableCellStyle *TableCellStyle `json:"tableCellStyle,omitempty"`

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

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

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

// TableCellBorder: A border around a table cell. Table cell borders
// cannot be transparent. To hide a table cell border, make its width 0.
type TableCellBorder struct {
	// Color: The color of the border. This color cannot be transparent.
	Color *OptionalColor `json:"color,omitempty"`

	// DashStyle: The dash style of the border.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'. This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	DashStyle string `json:"dashStyle,omitempty"`

	// Width: The width of the border.
	Width *Dimension `json:"width,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Color") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *TableCellBorder) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellBorder
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellLocation: Location of a single cell within a table.
type TableCellLocation struct {
	// ColumnIndex: The zero-based column index. For example, the second
	// column in the table has a column index of 1.
	ColumnIndex int64 `json:"columnIndex,omitempty"`

	// RowIndex: The zero-based row index. For example, the second row in
	// the table has a row index of 1.
	RowIndex int64 `json:"rowIndex,omitempty"`

	// TableStartLocation: The location where the table starts in the
	// document.
	TableStartLocation *Location `json:"tableStartLocation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *TableCellLocation) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellLocation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellStyle: The style of a TableCell. Inherited table cell styles
// are represented as unset fields in this message. A table cell style
// can inherit from the table's style.
type TableCellStyle struct {
	// BackgroundColor: The background color of the cell.
	BackgroundColor *OptionalColor `json:"backgroundColor,omitempty"`

	// BorderBottom: The bottom border of the cell.
	BorderBottom *TableCellBorder `json:"borderBottom,omitempty"`

	// BorderLeft: The left border of the cell.
	BorderLeft *TableCellBorder `json:"borderLeft,omitempty"`

	// BorderRight: The right border of the cell.
	BorderRight *TableCellBorder `json:"borderRight,omitempty"`

	// BorderTop: The top border of the cell.
	BorderTop *TableCellBorder `json:"borderTop,omitempty"`

	// ColumnSpan: The column span of the cell. This property is read-only.
	ColumnSpan int64 `json:"columnSpan,omitempty"`

	// ContentAlignment: The alignment of the content in the table cell. The
	// default alignment matches the alignment for newly created table cells
	// in the Docs editor.
	//
	// Possible values:
	//   "CONTENT_ALIGNMENT_UNSPECIFIED" - An unspecified content alignment.
	// The content alignment is inherited from the parent if one exists.
	//   "CONTENT_ALIGNMENT_UNSUPPORTED" - An unsupported content alignment.
	//   "TOP" - An alignment that aligns the content to the top of the
	// content holder. Corresponds to ECMA-376 ST_TextAnchoringType 't'.
	//   "MIDDLE" - An alignment that aligns the content to the middle of
	// the content holder. Corresponds to ECMA-376 ST_TextAnchoringType
	// 'ctr'.
	//   "BOTTOM" - An alignment that aligns the content to the bottom of
	// the content holder. Corresponds to ECMA-376 ST_TextAnchoringType 'b'.
	ContentAlignment string `json:"contentAlignment,omitempty"`

	// PaddingBottom: The bottom padding of the cell.
	PaddingBottom *Dimension `json:"paddingBottom,omitempty"`

	// PaddingLeft: The left padding of the cell.
	PaddingLeft *Dimension `json:"paddingLeft,omitempty"`

	// PaddingRight: The right padding of the cell.
	PaddingRight *Dimension `json:"paddingRight,omitempty"`

	// PaddingTop: The top padding of the cell.
	PaddingTop *Dimension `json:"paddingTop,omitempty"`

	// RowSpan: The row span of the cell. This property is read-only.
	RowSpan int64 `json:"rowSpan,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackgroundColor") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *TableCellStyle) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellStyle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellStyleSuggestionState: A mask that indicates which of the
// fields on the base TableCellStyle have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type TableCellStyleSuggestionState struct {
	// BackgroundColorSuggested: Indicates if there was a suggested change
	// to background_color.
	BackgroundColorSuggested bool `json:"backgroundColorSuggested,omitempty"`

	// BorderBottomSuggested: Indicates if there was a suggested change to
	// border_bottom.
	BorderBottomSuggested bool `json:"borderBottomSuggested,omitempty"`

	// BorderLeftSuggested: Indicates if there was a suggested change to
	// border_left.
	BorderLeftSuggested bool `json:"borderLeftSuggested,omitempty"`

	// BorderRightSuggested: Indicates if there was a suggested change to
	// border_right.
	BorderRightSuggested bool `json:"borderRightSuggested,omitempty"`

	// BorderTopSuggested: Indicates if there was a suggested change to
	// border_top.
	BorderTopSuggested bool `json:"borderTopSuggested,omitempty"`

	// ColumnSpanSuggested: Indicates if there was a suggested change to
	// column_span.
	ColumnSpanSuggested bool `json:"columnSpanSuggested,omitempty"`

	// ContentAlignmentSuggested: Indicates if there was a suggested change
	// to content_alignment.
	ContentAlignmentSuggested bool `json:"contentAlignmentSuggested,omitempty"`

	// PaddingBottomSuggested: Indicates if there was a suggested change to
	// padding_bottom.
	PaddingBottomSuggested bool `json:"paddingBottomSuggested,omitempty"`

	// PaddingLeftSuggested: Indicates if there was a suggested change to
	// padding_left.
	PaddingLeftSuggested bool `json:"paddingLeftSuggested,omitempty"`

	// PaddingRightSuggested: Indicates if there was a suggested change to
	// padding_right.
	PaddingRightSuggested bool `json:"paddingRightSuggested,omitempty"`

	// PaddingTopSuggested: Indicates if there was a suggested change to
	// padding_top.
	PaddingTopSuggested bool `json:"paddingTopSuggested,omitempty"`

	// RowSpanSuggested: Indicates if there was a suggested change to
	// row_span.
	RowSpanSuggested bool `json:"rowSpanSuggested,omitempty"`

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

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

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

// TableColumnProperties: The properties of a column in a table.
type TableColumnProperties struct {
	// Width: The width of the column. Set when the column's `width_type` is
	// FIXED_WIDTH.
	Width *Dimension `json:"width,omitempty"`

	// WidthType: The width type of the column.
	//
	// Possible values:
	//   "WIDTH_TYPE_UNSPECIFIED" - The column width type is unspecified.
	//   "EVENLY_DISTRIBUTED" - The column width is evenly distributed among
	// the other evenly distrubted columns. The width of the column is
	// automatically determined and will have an equal portion of the width
	// remaining for the table after accounting for all columns with
	// specified widths.
	//   "FIXED_WIDTH" - A fixed column width. The width property contains
	// the column's width.
	WidthType string `json:"widthType,omitempty"`

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

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

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

// TableOfContents: A StructuralElement representing a table of
// contents.
type TableOfContents struct {
	// Content: The content of the table of contents.
	Content []*StructuralElement `json:"content,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A TableOfContents
	// may have multiple insertion IDs if it is a nested suggested change.
	// If empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

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

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

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

// TableRange: A table range represents a reference to a subset of a
// table. It's important to note that the cells specified by a table
// range do not necessarily form a rectangle. For example, let's say we
// have a 3 x 3 table where all the cells of the last row are merged
// together. The table looks like this: [ ] A table range with table
// cell location = (table_start_location, row = 0, column = 0), row span
// = 3 and column span = 2 specifies the following cells: x x [ x x x ]
type TableRange struct {
	// ColumnSpan: The column span of the table range.
	ColumnSpan int64 `json:"columnSpan,omitempty"`

	// RowSpan: The row span of the table range.
	RowSpan int64 `json:"rowSpan,omitempty"`

	// TableCellLocation: The cell location where the table range starts.
	TableCellLocation *TableCellLocation `json:"tableCellLocation,omitempty"`

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

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

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

// TableRow: The contents and style of a row in a Table.
type TableRow struct {
	// EndIndex: The zero-based end index of this row, exclusive, in UTF-16
	// code units.
	EndIndex int64 `json:"endIndex,omitempty"`

	// StartIndex: The zero-based start index of this row, in UTF-16 code
	// units.
	StartIndex int64 `json:"startIndex,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A TableRow may
	// have multiple insertion IDs if it is a nested suggested change. If
	// empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTableRowStyleChanges: The suggested style changes to this
	// row, keyed by suggestion ID.
	SuggestedTableRowStyleChanges map[string]SuggestedTableRowStyle `json:"suggestedTableRowStyleChanges,omitempty"`

	// TableCells: The contents and style of each cell in this row. It is
	// possible for a table to be non-rectangular, so some rows may have a
	// different number of cells than other rows in the same table.
	TableCells []*TableCell `json:"tableCells,omitempty"`

	// TableRowStyle: The style of the table row.
	TableRowStyle *TableRowStyle `json:"tableRowStyle,omitempty"`

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

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

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

// TableRowStyle: Styles that apply to a table row.
type TableRowStyle struct {
	// MinRowHeight: The minimum height of the row. The row will be rendered
	// in the Docs editor at a height equal to or greater than this value in
	// order to show all the content in the row's cells.
	MinRowHeight *Dimension `json:"minRowHeight,omitempty"`

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

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

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

// TableRowStyleSuggestionState: A mask that indicates which of the
// fields on the base TableRowStyle have been changed in this
// suggestion. For any field set to true, there is a new suggested
// value.
type TableRowStyleSuggestionState struct {
	// MinRowHeightSuggested: Indicates if there was a suggested change to
	// min_row_height.
	MinRowHeightSuggested bool `json:"minRowHeightSuggested,omitempty"`

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

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

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

// TableStyle: Styles that apply to a table.
type TableStyle struct {
	// TableColumnProperties: The properties of each column. Note that in
	// Docs, tables contain rows and rows contain cells, similar to HTML. So
	// the properties for a row can be found on the row's table_row_style.
	TableColumnProperties []*TableColumnProperties `json:"tableColumnProperties,omitempty"`

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

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

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

// TextRun: A ParagraphElement that represents a run of text that all
// has the same styling.
type TextRun struct {
	// Content: The text of this run. Any non-text elements in the run are
	// replaced with the Unicode character U+E907.
	Content string `json:"content,omitempty"`

	// SuggestedDeletionIds: The suggested deletion IDs. If empty, then
	// there are no suggested deletions of this content.
	SuggestedDeletionIds []string `json:"suggestedDeletionIds,omitempty"`

	// SuggestedInsertionIds: The suggested insertion IDs. A TextRun may
	// have multiple insertion IDs if it is a nested suggested change. If
	// empty, then this is not a suggested insertion.
	SuggestedInsertionIds []string `json:"suggestedInsertionIds,omitempty"`

	// SuggestedTextStyleChanges: The suggested text style changes to this
	// run, keyed by suggestion ID.
	SuggestedTextStyleChanges map[string]SuggestedTextStyle `json:"suggestedTextStyleChanges,omitempty"`

	// TextStyle: The text style of this run.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

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

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

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

// TextStyle: Represents the styling that can be applied to text.
// Inherited text styles are represented as unset fields in this
// message. A text style's parent depends on where the text style is
// defined: * The TextStyle of text in a Paragraph inherits from the
// paragraph's corresponding named style type. * The TextStyle on a
// named style inherits from the normal text named style. * The
// TextStyle of the normal text named style inherits from the default
// text style in the Docs editor. * The TextStyle on a Paragraph element
// that is contained in a table may inherit its text style from the
// table style. If the text style does not inherit from a parent,
// unsetting fields will revert the style to a value matching the
// defaults in the Docs editor.
type TextStyle struct {
	// BackgroundColor: The background color of the text. If set, the color
	// is either an RGB color or transparent, depending on the `color`
	// field.
	BackgroundColor *OptionalColor `json:"backgroundColor,omitempty"`

	// BaselineOffset: The text's vertical offset from its normal position.
	// Text with `SUPERSCRIPT` or `SUBSCRIPT` baseline offsets is
	// automatically rendered in a smaller font size, computed based on the
	// `font_size` field. The `font_size` itself is not affected by changes
	// in this field.
	//
	// Possible values:
	//   "BASELINE_OFFSET_UNSPECIFIED" - The text's baseline offset is
	// inherited from the parent.
	//   "NONE" - The text is not vertically offset.
	//   "SUPERSCRIPT" - The text is vertically offset upwards
	// (superscript).
	//   "SUBSCRIPT" - The text is vertically offset downwards (subscript).
	BaselineOffset string `json:"baselineOffset,omitempty"`

	// Bold: Whether or not the text is rendered as bold.
	Bold bool `json:"bold,omitempty"`

	// FontSize: The size of the text's font.
	FontSize *Dimension `json:"fontSize,omitempty"`

	// ForegroundColor: The foreground color of the text. If set, the color
	// is either an RGB color or transparent, depending on the `color`
	// field.
	ForegroundColor *OptionalColor `json:"foregroundColor,omitempty"`

	// Italic: Whether or not the text is italicized.
	Italic bool `json:"italic,omitempty"`

	// Link: The hyperlink destination of the text. If unset, there is no
	// link. Links are not inherited from parent text. Changing the link in
	// an update request causes some other changes to the text style of the
	// range: * When setting a link, the text foreground color will be
	// updated to the default link color and the text will be underlined. If
	// these fields are modified in the same request, those values will be
	// used instead of the link defaults. * Setting a link on a text range
	// that overlaps with an existing link will also update the existing
	// link to point to the new URL. * Links are not settable on newline
	// characters. As a result, setting a link on a text range that crosses
	// a paragraph boundary, such as "ABC\n123", will separate the newline
	// character(s) into their own text runs. The link will be applied
	// separately to the runs before and after the newline. * Removing a
	// link will update the text style of the range to match the style of
	// the preceding text (or the default text styles if the preceding text
	// is another link) unless different styles are being set in the same
	// request.
	Link *Link `json:"link,omitempty"`

	// SmallCaps: Whether or not the text is in small capital letters.
	SmallCaps bool `json:"smallCaps,omitempty"`

	// Strikethrough: Whether or not the text is struck through.
	Strikethrough bool `json:"strikethrough,omitempty"`

	// Underline: Whether or not the text is underlined.
	Underline bool `json:"underline,omitempty"`

	// WeightedFontFamily: The font family and rendered weight of the text.
	// If an update request specifies values for both `weighted_font_family`
	// and `bold`, the `weighted_font_family` is applied first, then `bold`.
	// If `weighted_font_family#weight` is not set, it defaults to `400`. If
	// `weighted_font_family` is set, then
	// `weighted_font_family#font_family` must also be set with a non-empty
	// value. Otherwise, a 400 bad request error is returned.
	WeightedFontFamily *WeightedFontFamily `json:"weightedFontFamily,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackgroundColor") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *TextStyle) MarshalJSON() ([]byte, error) {
	type NoMethod TextStyle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextStyleSuggestionState: A mask that indicates which of the fields
// on the base TextStyle have been changed in this suggestion. For any
// field set to true, there is a new suggested value.
type TextStyleSuggestionState struct {
	// BackgroundColorSuggested: Indicates if there was a suggested change
	// to background_color.
	BackgroundColorSuggested bool `json:"backgroundColorSuggested,omitempty"`

	// BaselineOffsetSuggested: Indicates if there was a suggested change to
	// baseline_offset.
	BaselineOffsetSuggested bool `json:"baselineOffsetSuggested,omitempty"`

	// BoldSuggested: Indicates if there was a suggested change to bold.
	BoldSuggested bool `json:"boldSuggested,omitempty"`

	// FontSizeSuggested: Indicates if there was a suggested change to
	// font_size.
	FontSizeSuggested bool `json:"fontSizeSuggested,omitempty"`

	// ForegroundColorSuggested: Indicates if there was a suggested change
	// to foreground_color.
	ForegroundColorSuggested bool `json:"foregroundColorSuggested,omitempty"`

	// ItalicSuggested: Indicates if there was a suggested change to italic.
	ItalicSuggested bool `json:"italicSuggested,omitempty"`

	// LinkSuggested: Indicates if there was a suggested change to link.
	LinkSuggested bool `json:"linkSuggested,omitempty"`

	// SmallCapsSuggested: Indicates if there was a suggested change to
	// small_caps.
	SmallCapsSuggested bool `json:"smallCapsSuggested,omitempty"`

	// StrikethroughSuggested: Indicates if there was a suggested change to
	// strikethrough.
	StrikethroughSuggested bool `json:"strikethroughSuggested,omitempty"`

	// UnderlineSuggested: Indicates if there was a suggested change to
	// underline.
	UnderlineSuggested bool `json:"underlineSuggested,omitempty"`

	// WeightedFontFamilySuggested: Indicates if there was a suggested
	// change to weighted_font_family.
	WeightedFontFamilySuggested bool `json:"weightedFontFamilySuggested,omitempty"`

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

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

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

// UnmergeTableCellsRequest: Unmerges cells in a Table.
type UnmergeTableCellsRequest struct {
	// TableRange: The table range specifying which cells of the table to
	// unmerge. All merged cells in this range will be unmerged, and cells
	// that are already unmerged will not be affected. If the range has no
	// merged cells, the request will do nothing. If there is text in any of
	// the merged cells, the text will remain in the "head" cell of the
	// resulting block of unmerged cells. The "head" cell is the upper-left
	// cell when the content direction is from left to right, and the
	// upper-right otherwise.
	TableRange *TableRange `json:"tableRange,omitempty"`

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

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

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

// UpdateDocumentStyleRequest: Updates the DocumentStyle.
type UpdateDocumentStyleRequest struct {
	// DocumentStyle: The styles to set on the document. Certain document
	// style changes may cause other changes in order to mirror the behavior
	// of the Docs editor. See the documentation of DocumentStyle for more
	// information.
	DocumentStyle *DocumentStyle `json:"documentStyle,omitempty"`

	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `document_style` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field. For example to update the background, set `fields` to
	// "background".
	Fields string `json:"fields,omitempty"`

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

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

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

// UpdateParagraphStyleRequest: Update the styling of all paragraphs
// that overlap with the given range.
type UpdateParagraphStyleRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `paragraph_style` is implied and should not be
	// specified. For example, to update the paragraph style's alignment
	// property, set `fields` to "alignment". To reset a property to its
	// default value, include its field name in the field mask but leave the
	// field itself unset.
	Fields string `json:"fields,omitempty"`

	// ParagraphStyle: The styles to set on the paragraphs. Certain
	// paragraph style changes may cause other changes in order to mirror
	// the behavior of the Docs editor. See the documentation of
	// ParagraphStyle for more information.
	ParagraphStyle *ParagraphStyle `json:"paragraphStyle,omitempty"`

	// Range: The range overlapping the paragraphs to style.
	Range *Range `json:"range,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *UpdateParagraphStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateParagraphStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateSectionStyleRequest: Updates the SectionStyle.
type UpdateSectionStyleRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `section_style` is implied and must not be
	// specified. A single "*" can be used as short-hand for listing every
	// field. For example to update the left margin, set `fields` to
	// "margin_left".
	Fields string `json:"fields,omitempty"`

	// Range: The range overlapping the sections to style. Because section
	// breaks can only be inserted inside the body, the segment ID field
	// must be empty.
	Range *Range `json:"range,omitempty"`

	// SectionStyle: The styles to be set on the section. Certain section
	// style changes may cause other changes in order to mirror the behavior
	// of the Docs editor. See the documentation of SectionStyle for more
	// information.
	SectionStyle *SectionStyle `json:"sectionStyle,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *UpdateSectionStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateSectionStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableCellStyleRequest: Updates the style of a range of table
// cells.
type UpdateTableCellStyleRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `tableCellStyle` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field. For example to update the table cell background color, set
	// `fields` to "backgroundColor". To reset a property to its default
	// value, include its field name in the field mask but leave the field
	// itself unset.
	Fields string `json:"fields,omitempty"`

	// TableCellStyle: The style to set on the table cells. When updating
	// borders, if a cell shares a border with an adjacent cell, the
	// corresponding border property of the adjacent cell is updated as
	// well. Borders that are merged and invisible are not updated. Since
	// updating a border shared by adjacent cells in the same request can
	// cause conflicting border updates, border updates are applied in the
	// following order: - `border_right` - `border_left` - `border_bottom` -
	// `border_top`
	TableCellStyle *TableCellStyle `json:"tableCellStyle,omitempty"`

	// TableRange: The table range representing the subset of the table to
	// which the updates are applied.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// TableStartLocation: The location where the table starts in the
	// document. When specified, the updates are applied to all the cells in
	// the table.
	TableStartLocation *Location `json:"tableStartLocation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *UpdateTableCellStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableCellStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableColumnPropertiesRequest: Updates the TableColumnProperties
// of columns in a table.
type UpdateTableColumnPropertiesRequest struct {
	// ColumnIndices: The list of zero-based column indices whose property
	// should be updated. If no indices are specified, all columns will be
	// updated.
	ColumnIndices []int64 `json:"columnIndices,omitempty"`

	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `tableColumnProperties` is implied and should not
	// be specified. A single "*" can be used as short-hand for listing
	// every field. For example to update the column width, set `fields` to
	// "width".
	Fields string `json:"fields,omitempty"`

	// TableColumnProperties: The table column properties to update. If the
	// value of `table_column_properties#width` is less than 5 points (5/72
	// inch), a 400 bad request error is returned.
	TableColumnProperties *TableColumnProperties `json:"tableColumnProperties,omitempty"`

	// TableStartLocation: The location where the table starts in the
	// document.
	TableStartLocation *Location `json:"tableStartLocation,omitempty"`

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

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

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

// UpdateTableRowStyleRequest: Updates the TableRowStyle of rows in a
// table.
type UpdateTableRowStyleRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `tableRowStyle` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field. For example to update the minimum row height, set `fields` to
	// "min_row_height".
	Fields string `json:"fields,omitempty"`

	// RowIndices: The list of zero-based row indices whose style should be
	// updated. If no indices are specified, all rows will be updated.
	RowIndices []int64 `json:"rowIndices,omitempty"`

	// TableRowStyle: The styles to be set on the rows.
	TableRowStyle *TableRowStyle `json:"tableRowStyle,omitempty"`

	// TableStartLocation: The location where the table starts in the
	// document.
	TableStartLocation *Location `json:"tableStartLocation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *UpdateTableRowStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableRowStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTextStyleRequest: Update the styling of text.
type UpdateTextStyleRequest struct {
	// Fields: The fields that should be updated. At least one field must be
	// specified. The root `text_style` is implied and should not be
	// specified. A single "*" can be used as short-hand for listing every
	// field. For example, to update the text style to bold, set `fields` to
	// "bold". To reset a property to its default value, include its field
	// name in the field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// Range: The range of text to style. The range may be extended to
	// include adjacent newlines. If the range fully contains a paragraph
	// belonging to a list, the paragraph's bullet is also updated with the
	// matching text style. Ranges cannot be inserted inside a relative
	// UpdateTextStyleRequest.
	Range *Range `json:"range,omitempty"`

	// TextStyle: The styles to set on the text. If the value for a
	// particular style matches that of the parent, that style will be set
	// to inherit. Certain text style changes may cause other changes in
	// order to to mirror the behavior of the Docs editor. See the
	// documentation of TextStyle for more information.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 *UpdateTextStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTextStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WeightedFontFamily: Represents a font family and weight of text.
type WeightedFontFamily struct {
	// FontFamily: The font family of the text. The font family can be any
	// font from the Font menu in Docs or from [Google Fonts]
	// (https://fonts.google.com/). If the font name is unrecognized, the
	// text is rendered in `Arial`.
	FontFamily string `json:"fontFamily,omitempty"`

	// Weight: The weight of the font. This field can have any value that is
	// a multiple of `100` between `100` and `900`, inclusive. This range
	// corresponds to the numerical values described in the CSS 2.1
	// Specification, section 15.6
	// (https://www.w3.org/TR/CSS21/fonts.html#font-boldness), with
	// non-numerical values disallowed. The default value is `400`
	// ("normal"). The font weight makes up just one component of the
	// rendered font weight. The rendered weight is determined by a
	// combination of the `weight` and the text style's resolved `bold`
	// value, after accounting for inheritance: * If the text is bold and
	// the weight is less than `400`, the rendered weight is 400. * If the
	// text is bold and the weight is greater than or equal to `400` but is
	// less than `700`, the rendered weight is `700`. * If the weight is
	// greater than or equal to `700`, the rendered weight is equal to the
	// weight. * If the text is not bold, the rendered weight is equal to
	// the weight.
	Weight int64 `json:"weight,omitempty"`

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

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

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

// WriteControl: Provides control over how write requests are executed.
type WriteControl struct {
	// RequiredRevisionId: The optional revision ID of the document the
	// write request is applied to. If this is not the latest revision of
	// the document, the request is not processed and returns a 400 bad
	// request error. When a required revision ID is returned in a response,
	// it indicates the revision ID of the document after the request was
	// applied.
	RequiredRevisionId string `json:"requiredRevisionId,omitempty"`

	// TargetRevisionId: The optional target revision ID of the document the
	// write request is applied to. If collaborator changes have occurred
	// after the document was read using the API, the changes produced by
	// this write request are applied against the collaborator changes. This
	// results in a new revision of the document that incorporates both the
	// collaborator changes and the changes in the request, with the Docs
	// server resolving conflicting changes. When using target revision ID,
	// the API client can be thought of as another collaborator of the
	// document. The target revision ID can only be used to write to recent
	// versions of a document. If the target revision is too far behind the
	// latest revision, the request is not processed and returns a 400 bad
	// request error. The request should be tried again after retrieving the
	// latest version of the document. Usually a revision ID remains valid
	// for use as a target revision for several minutes after it's read, but
	// for frequently edited documents this window might be shorter.
	TargetRevisionId string `json:"targetRevisionId,omitempty"`

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

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

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

// method id "docs.documents.batchUpdate":

type DocumentsBatchUpdateCall struct {
	s                          *Service
	documentId                 string
	batchupdatedocumentrequest *BatchUpdateDocumentRequest
	urlParams_                 gensupport.URLParams
	ctx_                       context.Context
	header_                    http.Header
}

// BatchUpdate: Applies one or more updates to the document. 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. Other requests do not need to return information;
// these each return an empty reply. The order of replies matches that
// of the requests. For example, suppose you call batchUpdate with four
// updates, and only the third one returns information. The response
// would have two empty replies, the reply to the third request, and
// another empty reply, in that order. Because other users may be
// editing the document, the document might not exactly reflect your
// changes: your changes may be altered with respect to collaborator
// changes. If there are no collaborators, the document should reflect
// your changes. In any case, the updates in your request are guaranteed
// to be applied together atomically.
//
// - documentId: The ID of the document to update.
func (r *DocumentsService) BatchUpdate(documentId string, batchupdatedocumentrequest *BatchUpdateDocumentRequest) *DocumentsBatchUpdateCall {
	c := &DocumentsBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.documentId = documentId
	c.batchupdatedocumentrequest = batchupdatedocumentrequest
	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 *DocumentsBatchUpdateCall) Fields(s ...googleapi.Field) *DocumentsBatchUpdateCall {
	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 *DocumentsBatchUpdateCall) Context(ctx context.Context) *DocumentsBatchUpdateCall {
	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 *DocumentsBatchUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.batchupdatedocumentrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/documents/{documentId}: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{
		"documentId": c.documentId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "docs.documents.batchUpdate" call.
// Exactly one of *BatchUpdateDocumentResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *BatchUpdateDocumentResponse.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 *DocumentsBatchUpdateCall) Do(opts ...googleapi.CallOption) (*BatchUpdateDocumentResponse, 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 := &BatchUpdateDocumentResponse{
		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 document. 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. Other requests do not need to return information; these each return an empty reply. The order of replies matches that of the requests. For example, suppose you call batchUpdate with four updates, and only the third one returns information. The response would have two empty replies, the reply to the third request, and another empty reply, in that order. Because other users may be editing the document, the document might not exactly reflect your changes: your changes may be altered with respect to collaborator changes. If there are no collaborators, the document should reflect your changes. In any case, the updates in your request are guaranteed to be applied together atomically.",
	//   "flatPath": "v1/documents/{documentId}:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "docs.documents.batchUpdate",
	//   "parameterOrder": [
	//     "documentId"
	//   ],
	//   "parameters": {
	//     "documentId": {
	//       "description": "The ID of the document to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/documents/{documentId}:batchUpdate",
	//   "request": {
	//     "$ref": "BatchUpdateDocumentRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchUpdateDocumentResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/documents",
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file"
	//   ]
	// }

}

// method id "docs.documents.create":

type DocumentsCreateCall struct {
	s          *Service
	document   *Document
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a blank document using the title given in the
// request. Other fields in the request, including any provided content,
// are ignored. Returns the created document.
func (r *DocumentsService) Create(document *Document) *DocumentsCreateCall {
	c := &DocumentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.document = document
	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 *DocumentsCreateCall) Fields(s ...googleapi.Field) *DocumentsCreateCall {
	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 *DocumentsCreateCall) Context(ctx context.Context) *DocumentsCreateCall {
	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 *DocumentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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.document)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/documents")
	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 "docs.documents.create" call.
// Exactly one of *Document or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Document.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 *DocumentsCreateCall) Do(opts ...googleapi.CallOption) (*Document, 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 := &Document{
		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 blank document using the title given in the request. Other fields in the request, including any provided content, are ignored. Returns the created document.",
	//   "flatPath": "v1/documents",
	//   "httpMethod": "POST",
	//   "id": "docs.documents.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/documents",
	//   "request": {
	//     "$ref": "Document"
	//   },
	//   "response": {
	//     "$ref": "Document"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/documents",
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file"
	//   ]
	// }

}

// method id "docs.documents.get":

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

// Get: Gets the latest version of the specified document.
//
// - documentId: The ID of the document to retrieve.
func (r *DocumentsService) Get(documentId string) *DocumentsGetCall {
	c := &DocumentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.documentId = documentId
	return c
}

// SuggestionsViewMode sets the optional parameter
// "suggestionsViewMode": The suggestions view mode to apply to the
// document. This allows viewing the document with all suggestions
// inline, accepted or rejected. If one is not specified,
// DEFAULT_FOR_CURRENT_ACCESS is used.
//
// Possible values:
//   "DEFAULT_FOR_CURRENT_ACCESS" - The SuggestionsViewMode applied to
// the returned document depends on the user's current access level. If
// the user only has view access, PREVIEW_WITHOUT_SUGGESTIONS is
// applied. Otherwise, SUGGESTIONS_INLINE is applied. This is the
// default suggestions view mode.
//   "SUGGESTIONS_INLINE" - The returned document has suggestions
// inline. Suggested changes will be differentiated from base content
// within the document. Requests to retrieve a document using this mode
// will return a 403 error if the user does not have permission to view
// suggested changes.
//   "PREVIEW_SUGGESTIONS_ACCEPTED" - The returned document is a preview
// with all suggested changes accepted. Requests to retrieve a document
// using this mode will return a 403 error if the user does not have
// permission to view suggested changes.
//   "PREVIEW_WITHOUT_SUGGESTIONS" - The returned document is a preview
// with all suggested changes rejected if there are any suggestions in
// the document.
func (c *DocumentsGetCall) SuggestionsViewMode(suggestionsViewMode string) *DocumentsGetCall {
	c.urlParams_.Set("suggestionsViewMode", suggestionsViewMode)
	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 *DocumentsGetCall) Fields(s ...googleapi.Field) *DocumentsGetCall {
	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 *DocumentsGetCall) IfNoneMatch(entityTag string) *DocumentsGetCall {
	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 *DocumentsGetCall) Context(ctx context.Context) *DocumentsGetCall {
	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 *DocumentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/documents/{documentId}")
	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{
		"documentId": c.documentId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "docs.documents.get" call.
// Exactly one of *Document or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Document.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 *DocumentsGetCall) Do(opts ...googleapi.CallOption) (*Document, 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 := &Document{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest version of the specified document.",
	//   "flatPath": "v1/documents/{documentId}",
	//   "httpMethod": "GET",
	//   "id": "docs.documents.get",
	//   "parameterOrder": [
	//     "documentId"
	//   ],
	//   "parameters": {
	//     "documentId": {
	//       "description": "The ID of the document to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "suggestionsViewMode": {
	//       "description": "The suggestions view mode to apply to the document. This allows viewing the document with all suggestions inline, accepted or rejected. If one is not specified, DEFAULT_FOR_CURRENT_ACCESS is used.",
	//       "enum": [
	//         "DEFAULT_FOR_CURRENT_ACCESS",
	//         "SUGGESTIONS_INLINE",
	//         "PREVIEW_SUGGESTIONS_ACCEPTED",
	//         "PREVIEW_WITHOUT_SUGGESTIONS"
	//       ],
	//       "enumDescriptions": [
	//         "The SuggestionsViewMode applied to the returned document depends on the user's current access level. If the user only has view access, PREVIEW_WITHOUT_SUGGESTIONS is applied. Otherwise, SUGGESTIONS_INLINE is applied. This is the default suggestions view mode.",
	//         "The returned document has suggestions inline. Suggested changes will be differentiated from base content within the document. Requests to retrieve a document using this mode will return a 403 error if the user does not have permission to view suggested changes.",
	//         "The returned document is a preview with all suggested changes accepted. Requests to retrieve a document using this mode will return a 403 error if the user does not have permission to view suggested changes.",
	//         "The returned document is a preview with all suggested changes rejected if there are any suggestions in the document."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/documents/{documentId}",
	//   "response": {
	//     "$ref": "Document"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/documents",
	//     "https://www.googleapis.com/auth/documents.readonly",
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly"
	//   ]
	// }

}
