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

// Code generated file. DO NOT EDIT.

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

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

	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 will be
// applied to the DocumentStyle.
//
// If a footer of the specified type already exists then a 400 bad
// request error
// will be 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)
}

// CreateHeaderRequest: Creates a Header. The new header will be
// applied to the DocumentStyle.
//
// If a header of the specified type already exists then a 400 bad
// request error
// will be 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"`

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

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

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

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

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

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

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

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

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

}
