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

	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
	option "google.golang.org/api/option"
	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

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

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

// 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: The main body of the document.
	Body *Body `json:"body,omitempty"`

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

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

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

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

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

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

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

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

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

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

	// RevisionId: 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: The suggested changes to the style of
	// the document, keyed by suggestion ID.
	SuggestedDocumentStyleChanges map[string]SuggestedDocumentStyle `json:"suggestedDocumentStyleChanges,omitempty"`

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

	// SuggestionsViewMode: 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.
	Background *Background `json:"background,omitempty"`

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

	// DefaultHeaderId: The ID of the default header. If not set, there is
	// no default header.
	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.
	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.
	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.
	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.
	FirstPageHeaderId string `json:"firstPageHeaderId,omitempty"`

	// MarginBottom: The bottom page margin.
	MarginBottom *Dimension `json:"marginBottom,omitempty"`

	// MarginLeft: The left page margin.
	MarginLeft *Dimension `json:"marginLeft,omitempty"`

	// MarginRight: The right page margin.
	MarginRight *Dimension `json:"marginRight,omitempty"`

	// MarginTop: The top page margin.
	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"`

	// 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 size of the embedded object.
	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.
	//
	// After cropping, the image will be stretched to fit in its container.
	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)
}

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

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

// Request: A single update to apply to a document.
type Request struct {
	// 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"`

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

	// InsertTable: Inserts a table at the specified location.
	InsertTable *InsertTableRequest `json:"insertTable,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"`

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

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

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

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

	// NullFields is a list of field names (e.g. "CreateNamedRange") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field 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 {
	// 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. "CreateNamedRange") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

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

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

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

}
