// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

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

// OAuth2 scopes used by this API.
const (
	// View and manage your Google Docs documents
	DocumentsScope = "https://www.googleapis.com/auth/documents"

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

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

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

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"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))
	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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 specificed, 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 specificed, 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 format of the revision ID may change over time, so it should be
	// treated
	// opaquely. 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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"`

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

	// 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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.
	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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from
	// API requests. However, any non-pointer, non-interface field appearing
	// in ForceSendFields will be sent to the server regardless of whether
	// the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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
	// `<prefix>%[nesting_level]<suffix>`. 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
	// <p>`A.`
	// <p>`B.`
	// <p>`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
	// <p>`1.`
	// <p>`2.`
	// <p>`  2.1.`
	// <p>`  2.2.`
	// <p>`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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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"`

	// 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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)
}

// 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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.
	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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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.
	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 that of 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 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.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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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
}

// 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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 revision ID of the
	// document that the write request will be applied to. If this is not
	// the
	// latest revision of the document, the request will not be processed
	// and
	// will return 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 target revision ID of the
	// document that the write request will be applied to.
	//
	// If collaborator changes have occurred after the document was read
	// using
	// the API, the changes produced by this write request will be
	// transformed
	// against the collaborator changes. This results in a new revision of
	// the
	// document which incorporates both the changes in the request and
	// the
	// collaborator changes, and the Docs server will resolve
	// conflicting
	// changes. When using `target_revision_id`, the API client can be
	// thought
	// of as another collaborator of the document.
	//
	// The target revision ID may only be used to write to recent versions
	// of a
	// document. If the target revision is too far behind the latest
	// revision,
	// the request will not be processed and will return a 400 bad request
	// error
	// and the request should be retried after reading the latest version of
	// the
	// document. In most cases a `revision_id` will remain valid for use as
	// a
	// target revision for several minutes after it is read, but
	// for
	// frequently-edited documents this window may 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 values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or 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.
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/1.11.0 gdcl/20200214")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.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.\n\nEach request is validated before\nbeing applied. If any request is not valid, then the entire request will\nfail and nothing will be applied.\n\nSome requests have replies to\ngive you some information about how they are applied. Other requests do\nnot need to return information; these each return an empty reply.\nThe order of replies matches that of the requests.\n\nFor example, suppose you call batchUpdate with four updates, and only the\nthird one returns information. The response would have two empty replies,\nthe reply to the third request, and another empty reply, in that order.\n\nBecause other users may be editing the document, the document\nmight not exactly reflect your changes: your changes may\nbe altered with respect to collaborator changes. If there are no\ncollaborators, the document should reflect your changes. In any case,\nthe updates in your request are guaranteed to be applied together\natomically.",
	//   "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/1.11.0 gdcl/20200214")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.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\nin the request, including any provided content, are ignored.\n\nReturns 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.
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"
//   "SUGGESTIONS_INLINE"
//   "PREVIEW_SUGGESTIONS_ACCEPTED"
//   "PREVIEW_WITHOUT_SUGGESTIONS"
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/1.11.0 gdcl/20200214")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "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\ndocument with all suggestions inline, accepted or rejected. If one is not\nspecified, DEFAULT_FOR_CURRENT_ACCESS is\nused.",
	//       "enum": [
	//         "DEFAULT_FOR_CURRENT_ACCESS",
	//         "SUGGESTIONS_INLINE",
	//         "PREVIEW_SUGGESTIONS_ACCEPTED",
	//         "PREVIEW_WITHOUT_SUGGESTIONS"
	//       ],
	//       "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"
	//   ]
	// }

}
