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

// Code generated file. DO NOT EDIT.

// Package docs provides access to the Google Docs API.
//
// For product documentation, see: https://developers.google.com/docs/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/docs/v1"
//   ...
//   ctx := context.Background()
//   docsService, err := docs.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   docsService, err := docs.NewService(ctx, option.WithScopes(docs.DriveReadonlyScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   docsService, err := docs.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   docsService, err := docs.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package docs // import "google.golang.org/api/docs/v1"

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

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

// CreateFooterRequest: Creates a Footer. The new footer is applied
// to
// the DocumentStyle.
//
// If a footer of the specified type already exists, a 400 bad request
// error
// is returned.
type CreateFooterRequest struct {
	// Type: The type of footer to create.
	//
	// Possible values:
	//   "HEADER_FOOTER_TYPE_UNSPECIFIED" - The header/footer type is
	// unspecified.
	//   "DEFAULT" - A default header/footer.
	Type string `json:"type,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// CreateHeaderRequest: Creates a Header. The new header is applied
// to
// the DocumentStyle.
//
// If a header of the specified type already exists, a 400 bad request
// error
// is returned.
type CreateHeaderRequest struct {
	// Type: The type of header to create.
	//
	// Possible values:
	//   "HEADER_FOOTER_TYPE_UNSPECIFIED" - The header/footer type is
	// unspecified.
	//   "DEFAULT" - A default header/footer.
	Type string `json:"type,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

// CreateNamedRangeResponse: The result of creating a named range.
type CreateNamedRangeResponse struct {
	// NamedRangeId: The ID of the created named range.
	NamedRangeId string `json:"namedRangeId,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// UseEvenPageHeaderFooter: Indicates whether to use the even page
	// header / footer IDs for the even
	// pages.
	//
	// This property is read-only.
	UseEvenPageHeaderFooter bool `json:"useEvenPageHeaderFooter,omitempty"`

	// UseFirstPageHeaderFooter: Indicates whether to use the first page
	// header / footer IDs for the first
	// page.
	//
	// This property is read-only.
	UseFirstPageHeaderFooter bool `json:"useFirstPageHeaderFooter,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	// ObjectId: The ID of this inline object.
	ObjectId string `json:"objectId,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Response: A single response from an update.
type Response struct {
	// CreateFooter: The result of creating a footer.
	CreateFooter *CreateFooterResponse `json:"createFooter,omitempty"`

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Table: A StructuralElement representing a
// table.
type Table struct {
	// Columns: Number of columns in the table.
	//
	// It is possible for a table to be non-rectangular, so some rows may
	// have a
	// different number of cells.
	Columns int64 `json:"columns,omitempty"`

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

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

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

	// TableRows: The contents and style of each row.
	TableRows []*TableRow `json:"tableRows,omitempty"`

	// TableStyle: The style of the table.
	TableStyle *TableStyle `json:"tableStyle,omitempty"`

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

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

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

// TableCell: The contents and style of a cell in a Table.
type TableCell struct {
	// Content: The content of the cell.
	Content []*StructuralElement `json:"content,omitempty"`

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

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

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

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

	// SuggestedTableCellStyleChanges: The suggested changes to the table
	// cell style, keyed by suggestion ID.
	SuggestedTableCellStyleChanges map[string]SuggestedTableCellStyle `json:"suggestedTableCellStyleChanges,omitempty"`

	// TableCellStyle: The style of the cell.
	TableCellStyle *TableCellStyle `json:"tableCellStyle,omitempty"`

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

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

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

// TableCellBorder: A border around a table cell.
//
// Table cell borders cannot be transparent. To hide a table cell
// border, make
// its width 0.
type TableCellBorder struct {
	// Color: The color of the border.
	//
	// This color cannot be transparent.
	Color *OptionalColor `json:"color,omitempty"`

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

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

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

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

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

// TableCellLocation: Location of a single cell within a table.
type TableCellLocation struct {
	// ColumnIndex: The zero-based column index. For example, the second
	// column in the table
	// has a column index of 1.
	ColumnIndex int64 `json:"columnIndex,omitempty"`

	// RowIndex: The zero-based row index. For example, the second row in
	// the table has a
	// row index of 1.
	RowIndex int64 `json:"rowIndex,omitempty"`

	// TableStartLocation: The location where the table starts in the
	// document.
	TableStartLocation *Location `json:"tableStartLocation,omitempty"`

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

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

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

// TableCellStyle: The style of a TableCell.
//
// Inherited table cell styles are represented as unset fields in this
// message.
// A table cell style can inherit from the table's style.
type TableCellStyle struct {
	// BackgroundColor: The background color of the cell.
	BackgroundColor *OptionalColor `json:"backgroundColor,omitempty"`

	// BorderBottom: The bottom border of the cell.
	BorderBottom *TableCellBorder `json:"borderBottom,omitempty"`

	// BorderLeft: The left border of the cell.
	BorderLeft *TableCellBorder `json:"borderLeft,omitempty"`

	// BorderRight: The right border of the cell.
	BorderRight *TableCellBorder `json:"borderRight,omitempty"`

	// BorderTop: The top border of the cell.
	BorderTop *TableCellBorder `json:"borderTop,omitempty"`

	// ColumnSpan: The column span of the cell.
	//
	// This property is read-only.
	ColumnSpan int64 `json:"columnSpan,omitempty"`

	// ContentAlignment: The alignment of the content in the table cell. The
	// default alignment
	// matches the alignment for newly created table cells in the Docs
	// editor.
	//
	// Possible values:
	//   "CONTENT_ALIGNMENT_UNSPECIFIED" - An unspecified content alignment.
	// The content alignment is inherited from
	// the parent if one exists.
	//   "CONTENT_ALIGNMENT_UNSUPPORTED" - An unsupported content alignment.
	//   "TOP" - An alignment that aligns the content to the top of the
	// content holder.
	// Corresponds to ECMA-376 ST_TextAnchoringType 't'.
	//   "MIDDLE" - An alignment that aligns the content to the middle of
	// the content holder.
	// Corresponds to ECMA-376 ST_TextAnchoringType 'ctr'.
	//   "BOTTOM" - An alignment that aligns the content to the bottom of
	// the content holder.
	// Corresponds to ECMA-376 ST_TextAnchoringType 'b'.
	ContentAlignment string `json:"contentAlignment,omitempty"`

	// PaddingBottom: The bottom padding of the cell.
	PaddingBottom *Dimension `json:"paddingBottom,omitempty"`

	// PaddingLeft: The left padding of the cell.
	PaddingLeft *Dimension `json:"paddingLeft,omitempty"`

	// PaddingRight: The right padding of the cell.
	PaddingRight *Dimension `json:"paddingRight,omitempty"`

	// PaddingTop: The top padding of the cell.
	PaddingTop *Dimension `json:"paddingTop,omitempty"`

	// RowSpan: The row span of the cell.
	//
	// This property is read-only.
	RowSpan int64 `json:"rowSpan,omitempty"`

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

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

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

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

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

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

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

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

	// ColumnSpanSuggested: Indicates if there was a suggested change to
	// column_span.
	ColumnSpanSuggested bool `json:"columnSpanSuggested,omitempty"`

	// ContentAlignmentSuggested: Indicates if there was a suggested change
	// to content_alignment.
	ContentAlignmentSuggested bool `json:"contentAlignmentSuggested,omitempty"`

	// PaddingBottomSuggested: Indicates if there was a suggested change to
	// padding_bottom.
	PaddingBottomSuggested bool `json:"paddingBottomSuggested,omitempty"`

	// PaddingLeftSuggested: Indicates if there was a suggested change to
	// padding_left.
	PaddingLeftSuggested bool `json:"paddingLeftSuggested,omitempty"`

	// PaddingRightSuggested: Indicates if there was a suggested change to
	// padding_right.
	PaddingRightSuggested bool `json:"paddingRightSuggested,omitempty"`

	// PaddingTopSuggested: Indicates if there was a suggested change to
	// padding_top.
	PaddingTopSuggested bool `json:"paddingTopSuggested,omitempty"`

	// RowSpanSuggested: Indicates if there was a suggested change to
	// row_span.
	RowSpanSuggested bool `json:"rowSpanSuggested,omitempty"`

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

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

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

// TableColumnProperties: The properties of a column in a table.
type TableColumnProperties struct {
	// Width: The width of the column. Set when the column's `width_type`
	// is
	// FIXED_WIDTH.
	Width *Dimension `json:"width,omitempty"`

	// WidthType: The width type of the column.
	//
	// Possible values:
	//   "WIDTH_TYPE_UNSPECIFIED" - The column width type is unspecified.
	//   "EVENLY_DISTRIBUTED" - The column width is evenly distributed among
	// the other evenly distrubted
	// columns.
	//
	// The width of the column is automatically determined and will
	// have an equal portion of the width remaining for the table
	// after
	// accounting for all columns with specified widths.
	//   "FIXED_WIDTH" - A fixed column width. The
	// width property
	// contains the column's width.
	WidthType string `json:"widthType,omitempty"`

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

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

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

// TableOfContents: A StructuralElement representing
// a table of contents.
type TableOfContents struct {
	// Content: The content of the table of contents.
	Content []*StructuralElement `json:"content,omitempty"`

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

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

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

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

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

// TableRange: A table range represents a reference to a subset of a
// table.
//
// It's important to note that the cells specified by a table range do
// not
// necessarily form a rectangle. For example, let's say we have a 3 x 3
// table
// where all the cells of the last row are merged together. The table
// looks
// like this:
//
//
//      [             ]
//
// A table range with table cell location = (table_start_location, row =
// 0,
// column = 0), row span = 3 and column span = 2 specifies the following
// cells:
//
//       x     x
//      [ x    x    x ]
type TableRange struct {
	// ColumnSpan: The column span of the table range.
	ColumnSpan int64 `json:"columnSpan,omitempty"`

	// RowSpan: The row span of the table range.
	RowSpan int64 `json:"rowSpan,omitempty"`

	// TableCellLocation: The cell location where the table range starts.
	TableCellLocation *TableCellLocation `json:"tableCellLocation,omitempty"`

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

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

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

// TableRow: The contents and style of a row in a Table.
type TableRow struct {
	// EndIndex: The zero-based end index of this row, exclusive, in UTF-16
	// code units.
	EndIndex int64 `json:"endIndex,omitempty"`

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

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

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

	// SuggestedTableRowStyleChanges: The suggested style changes to this
	// row, keyed by suggestion ID.
	SuggestedTableRowStyleChanges map[string]SuggestedTableRowStyle `json:"suggestedTableRowStyleChanges,omitempty"`

	// TableCells: The contents and style of each cell in this row.
	//
	// It is possible for a table to be non-rectangular, so some rows may
	// have a
	// different number of cells than other rows in the same table.
	TableCells []*TableCell `json:"tableCells,omitempty"`

	// TableRowStyle: The style of the table row.
	TableRowStyle *TableRowStyle `json:"tableRowStyle,omitempty"`

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

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

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

// TableRowStyle: Styles that apply to a table row.
type TableRowStyle struct {
	// MinRowHeight: The minimum height of the row. The row will be rendered
	// in the Docs editor
	// at a height equal to or greater than this value in order to show all
	// the
	// content in the row's cells.
	MinRowHeight *Dimension `json:"minRowHeight,omitempty"`

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

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

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

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

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

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

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

// TableStyle: Styles that apply to a table.
type TableStyle struct {
	// TableColumnProperties: The properties of each column.
	//
	// Note that in Docs, tables contain rows and rows contain cells,
	// similar to
	// HTML. So the properties for a row can be found on the
	// row's
	// table_row_style.
	TableColumnProperties []*TableColumnProperties `json:"tableColumnProperties,omitempty"`

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

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

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

// TextRun: A ParagraphElement that represents a
// run of text that all has the same styling.
type TextRun struct {
	// Content: The text of this run.
	//
	// Any non-text elements in the run are replaced with the Unicode
	// character
	// U+E907.
	Content string `json:"content,omitempty"`

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

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

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

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

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

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

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

// TextStyle: Represents the styling that can be applied to
// text.
//
// Inherited text styles are represented as unset fields in this
// message. A
// text style's parent depends on where the text style is defined:
//
//   * The TextStyle of text in a Paragraph
//     inherits from the paragraph's corresponding named style type.
//   * The TextStyle on a named style
//     inherits from the normal text named style.
//   * The TextStyle of the normal text named style inherits
//     from the default text style in the Docs editor.
//   * The TextStyle on a Paragraph element
//     that is contained in a table may inherit its text style from the
// table
//     style.
//
// If the text style does not inherit from a parent, unsetting fields
// will
// revert the style to a value matching the defaults in the Docs editor.
type TextStyle struct {
	// BackgroundColor: The background color of the text. If set, the color
	// is either an RGB color
	// or transparent, depending on the `color` field.
	BackgroundColor *OptionalColor `json:"backgroundColor,omitempty"`

	// BaselineOffset: The text's vertical offset from its normal
	// position.
	//
	// Text with `SUPERSCRIPT` or `SUBSCRIPT` baseline offsets is
	// automatically
	// rendered in a smaller font size, computed based on the `font_size`
	// field.
	// The `font_size` itself is not affected by changes in this field.
	//
	// Possible values:
	//   "BASELINE_OFFSET_UNSPECIFIED" - The text's baseline offset is
	// inherited from the parent.
	//   "NONE" - The text is not vertically offset.
	//   "SUPERSCRIPT" - The text is vertically offset upwards
	// (superscript).
	//   "SUBSCRIPT" - The text is vertically offset downwards (subscript).
	BaselineOffset string `json:"baselineOffset,omitempty"`

	// Bold: Whether or not the text is rendered as bold.
	Bold bool `json:"bold,omitempty"`

	// FontSize: The size of the text's font.
	FontSize *Dimension `json:"fontSize,omitempty"`

	// ForegroundColor: The foreground color of the text. If set, the color
	// is either an RGB color
	// or transparent, depending on the `color` field.
	ForegroundColor *OptionalColor `json:"foregroundColor,omitempty"`

	// Italic: Whether or not the text is italicized.
	Italic bool `json:"italic,omitempty"`

	// Link: The hyperlink destination of the text. If unset, there is no
	// link. Links
	// are not inherited from parent text.
	//
	// Changing the link in an update request causes some other changes to
	// the
	// text style of the range:
	//
	// * When setting a link, the text foreground color will be updated to
	// the
	//   default link color and the text will be underlined. If these fields
	// are
	//   modified in the same request, those values will be used instead of
	// the
	//   link defaults.
	// * Setting a link on a text range that overlaps with an existing link
	// will
	//   also update the existing link to point to the new URL.
	// * Links are not settable on newline characters. As a result, setting
	// a link
	//   on a text range that crosses a paragraph boundary, such as
	// "ABC\n123",
	//   will separate the newline character(s) into their own text runs.
	// The
	//   link will be applied separately to the runs before and after the
	// newline.
	// * Removing a link will update the text style of the range to match
	// the
	//   style of the preceding text (or the default text styles if the
	// preceding
	//   text is another link) unless different styles are being set in the
	// same
	//   request.
	Link *Link `json:"link,omitempty"`

	// SmallCaps: Whether or not the text is in small capital letters.
	SmallCaps bool `json:"smallCaps,omitempty"`

	// Strikethrough: Whether or not the text is struck through.
	Strikethrough bool `json:"strikethrough,omitempty"`

	// Underline: Whether or not the text is underlined.
	Underline bool `json:"underline,omitempty"`

	// WeightedFontFamily: The font family and rendered weight of the
	// text.
	//
	// If an update request specifies values for both `weighted_font_family`
	// and
	// `bold`, the `weighted_font_family` is applied first, then `bold`.
	//
	// If `weighted_font_family#weight` is not set, it defaults to
	// `400`.
	//
	// If `weighted_font_family` is set, then
	// `weighted_font_family#font_family`
	// must also be set with a non-empty value. Otherwise, a 400 bad request
	// error
	// is returned.
	WeightedFontFamily *WeightedFontFamily `json:"weightedFontFamily,omitempty"`

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

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

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

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

	// BaselineOffsetSuggested: Indicates if there was a suggested change to
	// baseline_offset.
	BaselineOffsetSuggested bool `json:"baselineOffsetSuggested,omitempty"`

	// BoldSuggested: Indicates if there was a suggested change to bold.
	BoldSuggested bool `json:"boldSuggested,omitempty"`

	// FontSizeSuggested: Indicates if there was a suggested change to
	// font_size.
	FontSizeSuggested bool `json:"fontSizeSuggested,omitempty"`

	// ForegroundColorSuggested: Indicates if there was a suggested change
	// to foreground_color.
	ForegroundColorSuggested bool `json:"foregroundColorSuggested,omitempty"`

	// ItalicSuggested: Indicates if there was a suggested change to italic.
	ItalicSuggested bool `json:"italicSuggested,omitempty"`

	// LinkSuggested: Indicates if there was a suggested change to link.
	LinkSuggested bool `json:"linkSuggested,omitempty"`

	// SmallCapsSuggested: Indicates if there was a suggested change to
	// small_caps.
	SmallCapsSuggested bool `json:"smallCapsSuggested,omitempty"`

	// StrikethroughSuggested: Indicates if there was a suggested change to
	// strikethrough.
	StrikethroughSuggested bool `json:"strikethroughSuggested,omitempty"`

	// UnderlineSuggested: Indicates if there was a suggested change to
	// underline.
	UnderlineSuggested bool `json:"underlineSuggested,omitempty"`

	// WeightedFontFamilySuggested: Indicates if there was a suggested
	// change to weighted_font_family.
	WeightedFontFamilySuggested bool `json:"weightedFontFamilySuggested,omitempty"`

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

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

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

// UnmergeTableCellsRequest: Unmerges cells in a Table.
type UnmergeTableCellsRequest struct {
	// TableRange: The table range specifying which cells of the table to
	// unmerge.
	//
	// All merged cells in this range will be unmerged, and cells that are
	// already
	// unmerged will not be affected. If the range has no merged cells,
	// the
	// request will do nothing.
	//
	// If there is text in any of the merged cells, the text will remain in
	// the
	// "head" cell of the resulting block of unmerged cells. The "head" cell
	// is
	// the upper-left cell when the content direction is from left to right,
	// and
	// the upper-right otherwise.
	TableRange *TableRange `json:"tableRange,omitempty"`

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

	// NullFields is a list of field names (e.g. "TableRange") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UnmergeTableCellsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UnmergeTableCellsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateDocumentStyleRequest: Updates the DocumentStyle.
type UpdateDocumentStyleRequest struct {
	// DocumentStyle: The styles to set on the document.
	//
	// Certain document style changes may cause other changes in order to
	// mirror
	// the behavior of the Docs editor. See the documentation of
	// DocumentStyle for more information.
	DocumentStyle *DocumentStyle `json:"documentStyle,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `document_style`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the background, set `fields` to "background".
	Fields string `json:"fields,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DocumentStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DocumentStyle") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateDocumentStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateDocumentStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateParagraphStyleRequest: Update the styling of all paragraphs
// that overlap with the given range.
type UpdateParagraphStyleRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `paragraph_style` is
	// implied
	// and should not be specified.
	//
	// For example, to update the paragraph style's alignment property,
	// set
	// `fields` to "alignment".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ParagraphStyle: The styles to set on the paragraphs.
	//
	// Certain paragraph style changes may cause other changes in order to
	// mirror
	// the behavior of the Docs editor. See the documentation of
	// ParagraphStyle for more information.
	ParagraphStyle *ParagraphStyle `json:"paragraphStyle,omitempty"`

	// Range: The range overlapping the paragraphs to style.
	Range *Range `json:"range,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateParagraphStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateParagraphStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateSectionStyleRequest: Updates the SectionStyle.
type UpdateSectionStyleRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `section_style`
	// is
	// implied and must not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the left margin, set `fields` to
	// "margin_left".
	Fields string `json:"fields,omitempty"`

	// Range: The range overlapping the sections to style.
	//
	// Because section breaks can only be inserted inside the body, the
	// segment
	// ID field must be empty.
	Range *Range `json:"range,omitempty"`

	// SectionStyle: The styles to  be set on the section.
	//
	// Certain section style changes may cause other changes in order to
	// mirror
	// the behavior of the Docs editor. See the documentation of
	// SectionStyle for more information.
	SectionStyle *SectionStyle `json:"sectionStyle,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateSectionStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateSectionStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableCellStyleRequest: Updates the style of a range of table
// cells.
type UpdateTableCellStyleRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `tableCellStyle` is
	// implied
	// and should not be specified. A single "*" can be used as short-hand
	// for
	// listing every field.
	//
	// For example to update the table cell background color, set `fields`
	// to
	// "backgroundColor".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// TableCellStyle: The style to set on the table cells.
	//
	// When updating borders, if a cell shares a border with an adjacent
	// cell, the
	// corresponding border property of the adjacent cell is updated as
	// well.
	// Borders that are merged and invisible are not updated.
	//
	// Since updating a border shared by adjacent cells in the same request
	// can
	// cause conflicting border updates, border updates are applied in
	// the
	// following order:
	//
	// - `border_right`
	// - `border_left`
	// - `border_bottom`
	// - `border_top`
	TableCellStyle *TableCellStyle `json:"tableCellStyle,omitempty"`

	// TableRange: The table range representing the subset of the table to
	// which the updates
	// are applied.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// TableStartLocation: The location where the table starts in the
	// document. When specified, the
	// updates are applied to all the cells in the table.
	TableStartLocation *Location `json:"tableStartLocation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableCellStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableCellStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableColumnPropertiesRequest: Updates the
// TableColumnProperties of columns
// in a table.
type UpdateTableColumnPropertiesRequest struct {
	// ColumnIndices: The list of zero-based column indices whose property
	// should be updated. If
	// no indices are specified, all columns will be updated.
	ColumnIndices []int64 `json:"columnIndices,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root
	// `tableColumnProperties` is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the column width, set `fields` to "width".
	Fields string `json:"fields,omitempty"`

	// TableColumnProperties: The table column properties to update.
	//
	// If the value of `table_column_properties#width` is less than 5
	// points
	// (5/72 inch), a 400 bad request error is returned.
	TableColumnProperties *TableColumnProperties `json:"tableColumnProperties,omitempty"`

	// TableStartLocation: The location where the table starts in the
	// document.
	TableStartLocation *Location `json:"tableStartLocation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnIndices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnIndices") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableColumnPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableColumnPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableRowStyleRequest: Updates the TableRowStyle of rows in
// a
// table.
type UpdateTableRowStyleRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `tableRowStyle` is
	// implied
	// and should not be specified. A single "*" can be used as short-hand
	// for
	// listing every field.
	//
	// For example to update the minimum row height, set `fields`
	// to
	// "min_row_height".
	Fields string `json:"fields,omitempty"`

	// RowIndices: The list of zero-based row indices whose style should be
	// updated. If no
	// indices are specified, all rows will be updated.
	RowIndices []int64 `json:"rowIndices,omitempty"`

	// TableRowStyle: The styles to be set on the rows.
	TableRowStyle *TableRowStyle `json:"tableRowStyle,omitempty"`

	// TableStartLocation: The location where the table starts in the
	// document.
	TableStartLocation *Location `json:"tableStartLocation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableRowStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableRowStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTextStyleRequest: Update the styling of text.
type UpdateTextStyleRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `text_style` is
	// implied and
	// should not be specified. A single "*" can be used as short-hand
	// for
	// listing every field.
	//
	// For example, to update the text style to bold, set `fields` to
	// "bold".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// Range: The range of text to style.
	//
	// The range may be extended to include adjacent newlines.
	//
	// If the range fully contains a paragraph belonging to a list,
	// the
	// paragraph's bullet is also updated with the matching text
	// style.
	//
	// Ranges cannot be inserted inside a relative UpdateTextStyleRequest.
	Range *Range `json:"range,omitempty"`

	// TextStyle: The styles to set on the text.
	//
	// If the value for a particular style matches that of the parent, that
	// style
	// will be set to inherit.
	//
	// Certain text style changes may cause other changes in order to to
	// mirror
	// the behavior of the Docs editor. See the documentation of
	// TextStyle for more information.
	TextStyle *TextStyle `json:"textStyle,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTextStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTextStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WeightedFontFamily: Represents a font family and weight of text.
type WeightedFontFamily struct {
	// FontFamily: The font family of the text.
	//
	// The font family can be any font from the Font menu in Docs or
	// from
	// [Google Fonts] (https://fonts.google.com/). If the font name
	// is
	// unrecognized, the text is rendered in `Arial`.
	FontFamily string `json:"fontFamily,omitempty"`

	// Weight: The weight of the font. This field can have any value that is
	// a multiple of
	// `100` between `100` and `900`, inclusive. This range corresponds to
	// the
	// numerical values described in the CSS 2.1 Specification,
	// [section 15.6](https://www.w3.org/TR/CSS21/fonts.html#font-boldness),
	// with
	// non-numerical values disallowed.
	//
	// The default value is `400` ("normal").
	//
	// The font weight makes up just one component of the rendered font
	// weight.
	// The rendered weight is determined by a combination of the `weight`
	// and the
	// text style's resolved `bold` value, after accounting for
	// inheritance:
	//
	// * If the text is bold and the weight is less than `400`, the
	// rendered
	//   weight is 400.
	// * If the text is bold and the weight is greater than or equal to
	// `400` but
	//   is less than `700`, the rendered weight is `700`.
	// * If the weight is greater than or equal to `700`, the rendered
	// weight is
	//   equal to the weight.
	// * If the text is not bold, the rendered weight is equal to the
	// weight.
	Weight int64 `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FontFamily") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "FontFamily") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *WeightedFontFamily) MarshalJSON() ([]byte, error) {
	type NoMethod WeightedFontFamily
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WriteControl: Provides control over how write requests are executed.
type WriteControl struct {
	// RequiredRevisionId: The revision ID of the
	// document that the write request will be applied to. If this is not
	// the
	// latest revision of the document, the request will not be processed
	// and
	// will return a 400 bad request error.
	//
	// When a required revision ID is returned in a response, it indicates
	// the
	// revision ID of the document after the request was applied.
	RequiredRevisionId string `json:"requiredRevisionId,omitempty"`

	// TargetRevisionId: The target revision ID of the
	// document that the write request will be applied to.
	//
	// If collaborator changes have occurred after the document was read
	// using
	// the API, the changes produced by this write request will be
	// transformed
	// against the collaborator changes. This results in a new revision of
	// the
	// document which incorporates both the changes in the request and
	// the
	// collaborator changes, and the Docs server will resolve
	// conflicting
	// changes. When using `target_revision_id`, the API client can be
	// thought
	// of as another collaborator of the document.
	//
	// The target revision ID may only be used to write to recent versions
	// of a
	// document. If the target revision is too far behind the latest
	// revision,
	// the request will not be processed and will return a 400 bad request
	// error
	// and the request should be retried after reading the latest version of
	// the
	// document. In most cases a `revision_id` will remain valid for use as
	// a
	// target revision for several minutes after it is read, but
	// for
	// frequently-edited documents this window may be shorter.
	TargetRevisionId string `json:"targetRevisionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RequiredRevisionId")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RequiredRevisionId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *WriteControl) MarshalJSON() ([]byte, error) {
	type NoMethod WriteControl
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "docs.documents.batchUpdate":

type DocumentsBatchUpdateCall struct {
	s                          *Service
	documentId                 string
	batchupdatedocumentrequest *BatchUpdateDocumentRequest
	urlParams_                 gensupport.URLParams
	ctx_                       context.Context
	header_                    http.Header
}

// BatchUpdate: Applies one or more updates to the document.
//
// Each request is validated before
// being applied. If any request is not valid, then the entire request
// will
// fail and nothing will be applied.
//
// Some requests have replies to
// give you some information about how they are applied. Other requests
// do
// not need to return information; these each return an empty reply.
// The order of replies matches that of the requests.
//
// For example, suppose you call batchUpdate with four updates, and only
// the
// third one returns information. The response would have two empty
// replies,
// the reply to the third request, and another empty reply, in that
// order.
//
// Because other users may be editing the document, the document
// might not exactly reflect your changes: your changes may
// be altered with respect to collaborator changes. If there are
// no
// collaborators, the document should reflect your changes. In any
// case,
// the updates in your request are guaranteed to be applied
// together
// atomically.
func (r *DocumentsService) BatchUpdate(documentId string, batchupdatedocumentrequest *BatchUpdateDocumentRequest) *DocumentsBatchUpdateCall {
	c := &DocumentsBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.documentId = documentId
	c.batchupdatedocumentrequest = batchupdatedocumentrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DocumentsBatchUpdateCall) Fields(s ...googleapi.Field) *DocumentsBatchUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DocumentsBatchUpdateCall) Context(ctx context.Context) *DocumentsBatchUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DocumentsBatchUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200120")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.batchupdatedocumentrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/documents/{documentId}:batchUpdate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"documentId": c.documentId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "docs.documents.batchUpdate" call.
// Exactly one of *BatchUpdateDocumentResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *BatchUpdateDocumentResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DocumentsBatchUpdateCall) Do(opts ...googleapi.CallOption) (*BatchUpdateDocumentResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchUpdateDocumentResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Applies one or more updates to the document.\n\nEach request is validated before\nbeing applied. If any request is not valid, then the entire request will\nfail and nothing will be applied.\n\nSome requests have replies to\ngive you some information about how they are applied. Other requests do\nnot need to return information; these each return an empty reply.\nThe order of replies matches that of the requests.\n\nFor example, suppose you call batchUpdate with four updates, and only the\nthird one returns information. The response would have two empty replies,\nthe reply to the third request, and another empty reply, in that order.\n\nBecause other users may be editing the document, the document\nmight not exactly reflect your changes: your changes may\nbe altered with respect to collaborator changes. If there are no\ncollaborators, the document should reflect your changes. In any case,\nthe updates in your request are guaranteed to be applied together\natomically.",
	//   "flatPath": "v1/documents/{documentId}:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "docs.documents.batchUpdate",
	//   "parameterOrder": [
	//     "documentId"
	//   ],
	//   "parameters": {
	//     "documentId": {
	//       "description": "The ID of the document to update.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/documents/{documentId}:batchUpdate",
	//   "request": {
	//     "$ref": "BatchUpdateDocumentRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchUpdateDocumentResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/documents",
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file"
	//   ]
	// }

}

// method id "docs.documents.create":

type DocumentsCreateCall struct {
	s          *Service
	document   *Document
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a blank document using the title given in the
// request. Other fields
// in the request, including any provided content, are ignored.
//
// Returns the created document.
func (r *DocumentsService) Create(document *Document) *DocumentsCreateCall {
	c := &DocumentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.document = document
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DocumentsCreateCall) Fields(s ...googleapi.Field) *DocumentsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DocumentsCreateCall) Context(ctx context.Context) *DocumentsCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DocumentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200120")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.document)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/documents")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "docs.documents.create" call.
// Exactly one of *Document or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Document.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *DocumentsCreateCall) Do(opts ...googleapi.CallOption) (*Document, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Document{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a blank document using the title given in the request. Other fields\nin the request, including any provided content, are ignored.\n\nReturns the created document.",
	//   "flatPath": "v1/documents",
	//   "httpMethod": "POST",
	//   "id": "docs.documents.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/documents",
	//   "request": {
	//     "$ref": "Document"
	//   },
	//   "response": {
	//     "$ref": "Document"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/documents",
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file"
	//   ]
	// }

}

// method id "docs.documents.get":

type DocumentsGetCall struct {
	s            *Service
	documentId   string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the latest version of the specified document.
func (r *DocumentsService) Get(documentId string) *DocumentsGetCall {
	c := &DocumentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.documentId = documentId
	return c
}

// SuggestionsViewMode sets the optional parameter
// "suggestionsViewMode": The suggestions view mode to apply to the
// document. This allows viewing the
// document with all suggestions inline, accepted or rejected. If one is
// not
// specified, DEFAULT_FOR_CURRENT_ACCESS is
// used.
//
// Possible values:
//   "DEFAULT_FOR_CURRENT_ACCESS"
//   "SUGGESTIONS_INLINE"
//   "PREVIEW_SUGGESTIONS_ACCEPTED"
//   "PREVIEW_WITHOUT_SUGGESTIONS"
func (c *DocumentsGetCall) SuggestionsViewMode(suggestionsViewMode string) *DocumentsGetCall {
	c.urlParams_.Set("suggestionsViewMode", suggestionsViewMode)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DocumentsGetCall) Fields(s ...googleapi.Field) *DocumentsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DocumentsGetCall) IfNoneMatch(entityTag string) *DocumentsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DocumentsGetCall) Context(ctx context.Context) *DocumentsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DocumentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200120")
	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"
	//   ]
	// }

}
