// Package language provides access to the Cloud Natural Language API.
//
// This package is DEPRECATED. Use package cloud.google.com/go/language/apiv1 instead.
//
// See https://cloud.google.com/natural-language/
//
// Usage example:
//
//   import "google.golang.org/api/language/v1beta2"
//   ...
//   languageService, err := language.New(oauthHttpClient)
package language // import "google.golang.org/api/language/v1beta2"

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	context "golang.org/x/net/context"
	ctxhttp "golang.org/x/net/context/ctxhttp"
	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = ctxhttp.Do

const apiId = "language:v1beta2"
const apiName = "language"
const apiVersion = "v1beta2"
const basePath = "https://language.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// Apply machine learning models to reveal the structure and meaning of
	// text
	CloudLanguageScope = "https://www.googleapis.com/auth/cloud-language"

	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

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
}

// AnalyzeEntitiesRequest: The entity analysis request message.
type AnalyzeEntitiesRequest struct {
	// Document: Input document.
	Document *Document `json:"document,omitempty"`

	// EncodingType: The encoding type used by the API to calculate offsets.
	//
	// Possible values:
	//   "NONE" - If `EncodingType` is not specified, encoding-dependent
	// information (such as
	// `begin_offset`) will be set at `-1`.
	//   "UTF8" - Encoding-dependent information (such as `begin_offset`) is
	// calculated based
	// on the UTF-8 encoding of the input. C++ and Go are examples of
	// languages
	// that use this encoding natively.
	//   "UTF16" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-16 encoding of the input. Java and Javascript are examples
	// of
	// languages that use this encoding natively.
	//   "UTF32" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-32 encoding of the input. Python is an example of a
	// language
	// that uses this encoding natively.
	EncodingType string `json:"encodingType,omitempty"`

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

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

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

// AnalyzeEntitiesResponse: The entity analysis response message.
type AnalyzeEntitiesResponse struct {
	// Entities: The recognized entities in the input document.
	Entities []*Entity `json:"entities,omitempty"`

	// Language: The language of the text, which will be the same as the
	// language specified
	// in the request or, if not specified, the automatically-detected
	// language.
	// See Document.language field for more details.
	Language string `json:"language,omitempty"`

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

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

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

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

// AnalyzeEntitySentimentRequest: The entity-level sentiment analysis
// request message.
type AnalyzeEntitySentimentRequest struct {
	// Document: Input document.
	Document *Document `json:"document,omitempty"`

	// EncodingType: The encoding type used by the API to calculate offsets.
	//
	// Possible values:
	//   "NONE" - If `EncodingType` is not specified, encoding-dependent
	// information (such as
	// `begin_offset`) will be set at `-1`.
	//   "UTF8" - Encoding-dependent information (such as `begin_offset`) is
	// calculated based
	// on the UTF-8 encoding of the input. C++ and Go are examples of
	// languages
	// that use this encoding natively.
	//   "UTF16" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-16 encoding of the input. Java and Javascript are examples
	// of
	// languages that use this encoding natively.
	//   "UTF32" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-32 encoding of the input. Python is an example of a
	// language
	// that uses this encoding natively.
	EncodingType string `json:"encodingType,omitempty"`

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

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

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

// AnalyzeEntitySentimentResponse: The entity-level sentiment analysis
// response message.
type AnalyzeEntitySentimentResponse struct {
	// Entities: The recognized entities in the input document with
	// associated sentiments.
	Entities []*Entity `json:"entities,omitempty"`

	// Language: The language of the text, which will be the same as the
	// language specified
	// in the request or, if not specified, the automatically-detected
	// language.
	// See Document.language field for more details.
	Language string `json:"language,omitempty"`

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

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

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

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

// AnalyzeSentimentRequest: The sentiment analysis request message.
type AnalyzeSentimentRequest struct {
	// Document: Input document.
	Document *Document `json:"document,omitempty"`

	// EncodingType: The encoding type used by the API to calculate sentence
	// offsets for the
	// sentence sentiment.
	//
	// Possible values:
	//   "NONE" - If `EncodingType` is not specified, encoding-dependent
	// information (such as
	// `begin_offset`) will be set at `-1`.
	//   "UTF8" - Encoding-dependent information (such as `begin_offset`) is
	// calculated based
	// on the UTF-8 encoding of the input. C++ and Go are examples of
	// languages
	// that use this encoding natively.
	//   "UTF16" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-16 encoding of the input. Java and Javascript are examples
	// of
	// languages that use this encoding natively.
	//   "UTF32" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-32 encoding of the input. Python is an example of a
	// language
	// that uses this encoding natively.
	EncodingType string `json:"encodingType,omitempty"`

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

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

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

// AnalyzeSentimentResponse: The sentiment analysis response message.
type AnalyzeSentimentResponse struct {
	// DocumentSentiment: The overall sentiment of the input document.
	DocumentSentiment *Sentiment `json:"documentSentiment,omitempty"`

	// Language: The language of the text, which will be the same as the
	// language specified
	// in the request or, if not specified, the automatically-detected
	// language.
	// See Document.language field for more details.
	Language string `json:"language,omitempty"`

	// Sentences: The sentiment for all the sentences in the document.
	Sentences []*Sentence `json:"sentences,omitempty"`

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

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

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

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

// AnalyzeSyntaxRequest: The syntax analysis request message.
type AnalyzeSyntaxRequest struct {
	// Document: Input document.
	Document *Document `json:"document,omitempty"`

	// EncodingType: The encoding type used by the API to calculate offsets.
	//
	// Possible values:
	//   "NONE" - If `EncodingType` is not specified, encoding-dependent
	// information (such as
	// `begin_offset`) will be set at `-1`.
	//   "UTF8" - Encoding-dependent information (such as `begin_offset`) is
	// calculated based
	// on the UTF-8 encoding of the input. C++ and Go are examples of
	// languages
	// that use this encoding natively.
	//   "UTF16" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-16 encoding of the input. Java and Javascript are examples
	// of
	// languages that use this encoding natively.
	//   "UTF32" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-32 encoding of the input. Python is an example of a
	// language
	// that uses this encoding natively.
	EncodingType string `json:"encodingType,omitempty"`

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

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

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

// AnalyzeSyntaxResponse: The syntax analysis response message.
type AnalyzeSyntaxResponse struct {
	// Language: The language of the text, which will be the same as the
	// language specified
	// in the request or, if not specified, the automatically-detected
	// language.
	// See Document.language field for more details.
	Language string `json:"language,omitempty"`

	// Sentences: Sentences in the input document.
	Sentences []*Sentence `json:"sentences,omitempty"`

	// Tokens: Tokens, along with their syntactic information, in the input
	// document.
	Tokens []*Token `json:"tokens,omitempty"`

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

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

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

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

// AnnotateTextRequest: The request message for the text annotation API,
// which can perform multiple
// analysis types (sentiment, entities, and syntax) in one call.
type AnnotateTextRequest struct {
	// Document: Input document.
	Document *Document `json:"document,omitempty"`

	// EncodingType: The encoding type used by the API to calculate offsets.
	//
	// Possible values:
	//   "NONE" - If `EncodingType` is not specified, encoding-dependent
	// information (such as
	// `begin_offset`) will be set at `-1`.
	//   "UTF8" - Encoding-dependent information (such as `begin_offset`) is
	// calculated based
	// on the UTF-8 encoding of the input. C++ and Go are examples of
	// languages
	// that use this encoding natively.
	//   "UTF16" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-16 encoding of the input. Java and Javascript are examples
	// of
	// languages that use this encoding natively.
	//   "UTF32" - Encoding-dependent information (such as `begin_offset`)
	// is calculated based
	// on the UTF-32 encoding of the input. Python is an example of a
	// language
	// that uses this encoding natively.
	EncodingType string `json:"encodingType,omitempty"`

	// Features: The enabled features.
	Features *Features `json:"features,omitempty"`

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

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

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

// AnnotateTextResponse: The text annotations response message.
type AnnotateTextResponse struct {
	// Categories: Categories identified in the input document.
	Categories []*ClassificationCategory `json:"categories,omitempty"`

	// DocumentSentiment: The overall sentiment for the document. Populated
	// if the user
	// enables
	// AnnotateTextRequest.Features.extract_document_sentiment.
	DocumentSentiment *Sentiment `json:"documentSentiment,omitempty"`

	// Entities: Entities, along with their semantic information, in the
	// input document.
	// Populated if the user
	// enables
	// AnnotateTextRequest.Features.extract_entities.
	Entities []*Entity `json:"entities,omitempty"`

	// Language: The language of the text, which will be the same as the
	// language specified
	// in the request or, if not specified, the automatically-detected
	// language.
	// See Document.language field for more details.
	Language string `json:"language,omitempty"`

	// Sentences: Sentences in the input document. Populated if the user
	// enables
	// AnnotateTextRequest.Features.extract_syntax.
	Sentences []*Sentence `json:"sentences,omitempty"`

	// Tokens: Tokens, along with their syntactic information, in the input
	// document.
	// Populated if the user
	// enables
	// AnnotateTextRequest.Features.extract_syntax.
	Tokens []*Token `json:"tokens,omitempty"`

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

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

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

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

// ClassificationCategory: Represents a category returned from the text
// classifier.
type ClassificationCategory struct {
	// Confidence: The classifier's confidence of the category. Number
	// represents how certain
	// the classifier is that this category represents the given text.
	Confidence float64 `json:"confidence,omitempty"`

	// Name: The name of the category representing the document, from the
	// [predefined
	// taxonomy](/natural-language/docs/categories).
	Name string `json:"name,omitempty"`

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

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

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

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

// ClassifyTextRequest: The document classification request message.
type ClassifyTextRequest struct {
	// Document: Input document.
	Document *Document `json:"document,omitempty"`

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

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

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

// ClassifyTextResponse: The document classification response message.
type ClassifyTextResponse struct {
	// Categories: Categories representing the input document.
	Categories []*ClassificationCategory `json:"categories,omitempty"`

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

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

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

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

// DependencyEdge: Represents dependency parse tree information for a
// token.
type DependencyEdge struct {
	// HeadTokenIndex: Represents the head of this token in the dependency
	// tree.
	// This is the index of the token which has an arc going to this
	// token.
	// The index is the position of the token in the array of tokens
	// returned
	// by the API method. If this token is a root token, then
	// the
	// `head_token_index` is its own index.
	HeadTokenIndex int64 `json:"headTokenIndex,omitempty"`

	// Label: The parse label for the token.
	//
	// Possible values:
	//   "UNKNOWN" - Unknown
	//   "ABBREV" - Abbreviation modifier
	//   "ACOMP" - Adjectival complement
	//   "ADVCL" - Adverbial clause modifier
	//   "ADVMOD" - Adverbial modifier
	//   "AMOD" - Adjectival modifier of an NP
	//   "APPOS" - Appositional modifier of an NP
	//   "ATTR" - Attribute dependent of a copular verb
	//   "AUX" - Auxiliary (non-main) verb
	//   "AUXPASS" - Passive auxiliary
	//   "CC" - Coordinating conjunction
	//   "CCOMP" - Clausal complement of a verb or adjective
	//   "CONJ" - Conjunct
	//   "CSUBJ" - Clausal subject
	//   "CSUBJPASS" - Clausal passive subject
	//   "DEP" - Dependency (unable to determine)
	//   "DET" - Determiner
	//   "DISCOURSE" - Discourse
	//   "DOBJ" - Direct object
	//   "EXPL" - Expletive
	//   "GOESWITH" - Goes with (part of a word in a text not well edited)
	//   "IOBJ" - Indirect object
	//   "MARK" - Marker (word introducing a subordinate clause)
	//   "MWE" - Multi-word expression
	//   "MWV" - Multi-word verbal expression
	//   "NEG" - Negation modifier
	//   "NN" - Noun compound modifier
	//   "NPADVMOD" - Noun phrase used as an adverbial modifier
	//   "NSUBJ" - Nominal subject
	//   "NSUBJPASS" - Passive nominal subject
	//   "NUM" - Numeric modifier of a noun
	//   "NUMBER" - Element of compound number
	//   "P" - Punctuation mark
	//   "PARATAXIS" - Parataxis relation
	//   "PARTMOD" - Participial modifier
	//   "PCOMP" - The complement of a preposition is a clause
	//   "POBJ" - Object of a preposition
	//   "POSS" - Possession modifier
	//   "POSTNEG" - Postverbal negative particle
	//   "PRECOMP" - Predicate complement
	//   "PRECONJ" - Preconjunt
	//   "PREDET" - Predeterminer
	//   "PREF" - Prefix
	//   "PREP" - Prepositional modifier
	//   "PRONL" - The relationship between a verb and verbal morpheme
	//   "PRT" - Particle
	//   "PS" - Associative or possessive marker
	//   "QUANTMOD" - Quantifier phrase modifier
	//   "RCMOD" - Relative clause modifier
	//   "RCMODREL" - Complementizer in relative clause
	//   "RDROP" - Ellipsis without a preceding predicate
	//   "REF" - Referent
	//   "REMNANT" - Remnant
	//   "REPARANDUM" - Reparandum
	//   "ROOT" - Root
	//   "SNUM" - Suffix specifying a unit of number
	//   "SUFF" - Suffix
	//   "TMOD" - Temporal modifier
	//   "TOPIC" - Topic marker
	//   "VMOD" - Clause headed by an infinite form of the verb that
	// modifies a noun
	//   "VOCATIVE" - Vocative
	//   "XCOMP" - Open clausal complement
	//   "SUFFIX" - Name suffix
	//   "TITLE" - Name title
	//   "ADVPHMOD" - Adverbial phrase modifier
	//   "AUXCAUS" - Causative auxiliary
	//   "AUXVV" - Helper auxiliary
	//   "DTMOD" - Rentaishi (Prenominal modifier)
	//   "FOREIGN" - Foreign words
	//   "KW" - Keyword
	//   "LIST" - List for chains of comparable items
	//   "NOMC" - Nominalized clause
	//   "NOMCSUBJ" - Nominalized clausal subject
	//   "NOMCSUBJPASS" - Nominalized clausal passive
	//   "NUMC" - Compound of numeric modifier
	//   "COP" - Copula
	//   "DISLOCATED" - Dislocated relation (for fronted/topicalized
	// elements)
	//   "ASP" - Aspect marker
	//   "GMOD" - Genitive modifier
	//   "GOBJ" - Genitive object
	//   "INFMOD" - Infinitival modifier
	//   "MES" - Measure
	//   "NCOMP" - Nominal complement of a noun
	Label string `json:"label,omitempty"`

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

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

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

// Document:
// ################################################################
// #
//
// Represents the input to API methods.
type Document struct {
	// Content: The content of the input in string format.
	// Cloud audit logging exempt since it is based on user data.
	Content string `json:"content,omitempty"`

	// GcsContentUri: The Google Cloud Storage URI where the file content is
	// located.
	// This URI must be of the form: gs://bucket_name/object_name. For
	// more
	// details, see
	// https://cloud.google.com/storage/docs/reference-uris.
	// NOTE: Cloud Storage object versioning is not supported.
	GcsContentUri string `json:"gcsContentUri,omitempty"`

	// Language: The language of the document (if not specified, the
	// language is
	// automatically detected). Both ISO and BCP-47 language codes
	// are
	// accepted.<br>
	// [Language Support](/natural-language/docs/languages)
	// lists currently supported languages for each API method.
	// If the language (either specified by the caller or automatically
	// detected)
	// is not supported by the called API method, an `INVALID_ARGUMENT`
	// error
	// is returned.
	Language string `json:"language,omitempty"`

	// Type: Required. If the type is not set or is
	// `TYPE_UNSPECIFIED`,
	// returns an `INVALID_ARGUMENT` error.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The content type is not specified.
	//   "PLAIN_TEXT" - Plain text
	//   "HTML" - HTML
	Type string `json:"type,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 *Document) MarshalJSON() ([]byte, error) {
	type NoMethod Document
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Entity: Represents a phrase in the text that is a known entity, such
// as
// a person, an organization, or location. The API associates
// information, such
// as salience and mentions, with entities.
type Entity struct {
	// Mentions: The mentions of this entity in the input document. The API
	// currently
	// supports proper noun mentions.
	Mentions []*EntityMention `json:"mentions,omitempty"`

	// Metadata: Metadata associated with the entity.
	//
	// Currently, Wikipedia URLs and Knowledge Graph MIDs are provided,
	// if
	// available. The associated keys are "wikipedia_url" and "mid",
	// respectively.
	Metadata map[string]string `json:"metadata,omitempty"`

	// Name: The representative name for the entity.
	Name string `json:"name,omitempty"`

	// Salience: The salience score associated with the entity in the [0,
	// 1.0] range.
	//
	// The salience score for an entity provides information about
	// the
	// importance or centrality of that entity to the entire document
	// text.
	// Scores closer to 0 are less salient, while scores closer to 1.0 are
	// highly
	// salient.
	Salience float64 `json:"salience,omitempty"`

	// Sentiment: For calls to AnalyzeEntitySentiment or
	// if
	// AnnotateTextRequest.Features.extract_entity_sentiment is set to
	// true, this field will contain the aggregate sentiment expressed for
	// this
	// entity in the provided document.
	Sentiment *Sentiment `json:"sentiment,omitempty"`

	// Type: The entity type.
	//
	// Possible values:
	//   "UNKNOWN" - Unknown
	//   "PERSON" - Person
	//   "LOCATION" - Location
	//   "ORGANIZATION" - Organization
	//   "EVENT" - Event
	//   "WORK_OF_ART" - Work of art
	//   "CONSUMER_GOOD" - Consumer goods
	//   "OTHER" - Other types
	Type string `json:"type,omitempty"`

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

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

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

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

// EntityMention: Represents a mention for an entity in the text.
// Currently, proper noun
// mentions are supported.
type EntityMention struct {
	// Sentiment: For calls to AnalyzeEntitySentiment or
	// if
	// AnnotateTextRequest.Features.extract_entity_sentiment is set to
	// true, this field will contain the sentiment expressed for this
	// mention of
	// the entity in the provided document.
	Sentiment *Sentiment `json:"sentiment,omitempty"`

	// Text: The mention text.
	Text *TextSpan `json:"text,omitempty"`

	// Type: The type of the entity mention.
	//
	// Possible values:
	//   "TYPE_UNKNOWN" - Unknown
	//   "PROPER" - Proper name
	//   "COMMON" - Common noun (or noun compound)
	Type string `json:"type,omitempty"`

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

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

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

// Features: All available features for sentiment, syntax, and semantic
// analysis.
// Setting each one to true will enable that specific analysis for the
// input.
// Next ID: 10
type Features struct {
	// ClassifyText: Classify the full document into categories. If this is
	// true,
	// the API will use the default model which classifies into
	// a
	// [predefined taxonomy](/natural-language/docs/categories).
	ClassifyText bool `json:"classifyText,omitempty"`

	// ExtractDocumentSentiment: Extract document-level sentiment.
	ExtractDocumentSentiment bool `json:"extractDocumentSentiment,omitempty"`

	// ExtractEntities: Extract entities.
	ExtractEntities bool `json:"extractEntities,omitempty"`

	// ExtractEntitySentiment: Extract entities and their associated
	// sentiment.
	ExtractEntitySentiment bool `json:"extractEntitySentiment,omitempty"`

	// ExtractSyntax: Extract syntax information.
	ExtractSyntax bool `json:"extractSyntax,omitempty"`

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

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

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

// PartOfSpeech: Represents part of speech information for a token.
type PartOfSpeech struct {
	// Aspect: The grammatical aspect.
	//
	// Possible values:
	//   "ASPECT_UNKNOWN" - Aspect is not applicable in the analyzed
	// language or is not predicted.
	//   "PERFECTIVE" - Perfective
	//   "IMPERFECTIVE" - Imperfective
	//   "PROGRESSIVE" - Progressive
	Aspect string `json:"aspect,omitempty"`

	// Case: The grammatical case.
	//
	// Possible values:
	//   "CASE_UNKNOWN" - Case is not applicable in the analyzed language or
	// is not predicted.
	//   "ACCUSATIVE" - Accusative
	//   "ADVERBIAL" - Adverbial
	//   "COMPLEMENTIVE" - Complementive
	//   "DATIVE" - Dative
	//   "GENITIVE" - Genitive
	//   "INSTRUMENTAL" - Instrumental
	//   "LOCATIVE" - Locative
	//   "NOMINATIVE" - Nominative
	//   "OBLIQUE" - Oblique
	//   "PARTITIVE" - Partitive
	//   "PREPOSITIONAL" - Prepositional
	//   "REFLEXIVE_CASE" - Reflexive
	//   "RELATIVE_CASE" - Relative
	//   "VOCATIVE" - Vocative
	Case string `json:"case,omitempty"`

	// Form: The grammatical form.
	//
	// Possible values:
	//   "FORM_UNKNOWN" - Form is not applicable in the analyzed language or
	// is not predicted.
	//   "ADNOMIAL" - Adnomial
	//   "AUXILIARY" - Auxiliary
	//   "COMPLEMENTIZER" - Complementizer
	//   "FINAL_ENDING" - Final ending
	//   "GERUND" - Gerund
	//   "REALIS" - Realis
	//   "IRREALIS" - Irrealis
	//   "SHORT" - Short form
	//   "LONG" - Long form
	//   "ORDER" - Order form
	//   "SPECIFIC" - Specific form
	Form string `json:"form,omitempty"`

	// Gender: The grammatical gender.
	//
	// Possible values:
	//   "GENDER_UNKNOWN" - Gender is not applicable in the analyzed
	// language or is not predicted.
	//   "FEMININE" - Feminine
	//   "MASCULINE" - Masculine
	//   "NEUTER" - Neuter
	Gender string `json:"gender,omitempty"`

	// Mood: The grammatical mood.
	//
	// Possible values:
	//   "MOOD_UNKNOWN" - Mood is not applicable in the analyzed language or
	// is not predicted.
	//   "CONDITIONAL_MOOD" - Conditional
	//   "IMPERATIVE" - Imperative
	//   "INDICATIVE" - Indicative
	//   "INTERROGATIVE" - Interrogative
	//   "JUSSIVE" - Jussive
	//   "SUBJUNCTIVE" - Subjunctive
	Mood string `json:"mood,omitempty"`

	// Number: The grammatical number.
	//
	// Possible values:
	//   "NUMBER_UNKNOWN" - Number is not applicable in the analyzed
	// language or is not predicted.
	//   "SINGULAR" - Singular
	//   "PLURAL" - Plural
	//   "DUAL" - Dual
	Number string `json:"number,omitempty"`

	// Person: The grammatical person.
	//
	// Possible values:
	//   "PERSON_UNKNOWN" - Person is not applicable in the analyzed
	// language or is not predicted.
	//   "FIRST" - First
	//   "SECOND" - Second
	//   "THIRD" - Third
	//   "REFLEXIVE_PERSON" - Reflexive
	Person string `json:"person,omitempty"`

	// Proper: The grammatical properness.
	//
	// Possible values:
	//   "PROPER_UNKNOWN" - Proper is not applicable in the analyzed
	// language or is not predicted.
	//   "PROPER" - Proper
	//   "NOT_PROPER" - Not proper
	Proper string `json:"proper,omitempty"`

	// Reciprocity: The grammatical reciprocity.
	//
	// Possible values:
	//   "RECIPROCITY_UNKNOWN" - Reciprocity is not applicable in the
	// analyzed language or is not
	// predicted.
	//   "RECIPROCAL" - Reciprocal
	//   "NON_RECIPROCAL" - Non-reciprocal
	Reciprocity string `json:"reciprocity,omitempty"`

	// Tag: The part of speech tag.
	//
	// Possible values:
	//   "UNKNOWN" - Unknown
	//   "ADJ" - Adjective
	//   "ADP" - Adposition (preposition and postposition)
	//   "ADV" - Adverb
	//   "CONJ" - Conjunction
	//   "DET" - Determiner
	//   "NOUN" - Noun (common and proper)
	//   "NUM" - Cardinal number
	//   "PRON" - Pronoun
	//   "PRT" - Particle or other function word
	//   "PUNCT" - Punctuation
	//   "VERB" - Verb (all tenses and modes)
	//   "X" - Other: foreign words, typos, abbreviations
	//   "AFFIX" - Affix
	Tag string `json:"tag,omitempty"`

	// Tense: The grammatical tense.
	//
	// Possible values:
	//   "TENSE_UNKNOWN" - Tense is not applicable in the analyzed language
	// or is not predicted.
	//   "CONDITIONAL_TENSE" - Conditional
	//   "FUTURE" - Future
	//   "PAST" - Past
	//   "PRESENT" - Present
	//   "IMPERFECT" - Imperfect
	//   "PLUPERFECT" - Pluperfect
	Tense string `json:"tense,omitempty"`

	// Voice: The grammatical voice.
	//
	// Possible values:
	//   "VOICE_UNKNOWN" - Voice is not applicable in the analyzed language
	// or is not predicted.
	//   "ACTIVE" - Active
	//   "CAUSATIVE" - Causative
	//   "PASSIVE" - Passive
	Voice string `json:"voice,omitempty"`

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

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

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

// Sentence: Represents a sentence in the input document.
type Sentence struct {
	// Sentiment: For calls to AnalyzeSentiment or
	// if
	// AnnotateTextRequest.Features.extract_document_sentiment is set
	// to
	// true, this field will contain the sentiment for the sentence.
	Sentiment *Sentiment `json:"sentiment,omitempty"`

	// Text: The sentence text.
	Text *TextSpan `json:"text,omitempty"`

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

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

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

// Sentiment: Represents the feeling associated with the entire text or
// entities in
// the text.
// Next ID: 5
type Sentiment struct {
	// Magnitude: A non-negative number in the [0, +inf) range, which
	// represents
	// the absolute magnitude of sentiment regardless of score (positive
	// or
	// negative).
	Magnitude float64 `json:"magnitude,omitempty"`

	// Score: Sentiment score between -1.0 (negative sentiment) and
	// 1.0
	// (positive sentiment).
	Score float64 `json:"score,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 *Sentiment) MarshalJSON() ([]byte, error) {
	type NoMethod Sentiment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// Status: The `Status` type defines a logical error model that is
// suitable for different
// programming environments, including REST APIs and RPC APIs. It is
// used by
// [gRPC](https://github.com/grpc). The error model is designed to
// be:
//
// - Simple to use and understand for most users
// - Flexible enough to meet unexpected needs
//
// # Overview
//
// The `Status` message contains three pieces of data: error code, error
// message,
// and error details. The error code should be an enum value
// of
// google.rpc.Code, but it may accept additional error codes if needed.
// The
// error message should be a developer-facing English message that
// helps
// developers *understand* and *resolve* the error. If a localized
// user-facing
// error message is needed, put the localized message in the error
// details or
// localize it in the client. The optional error details may contain
// arbitrary
// information about the error. There is a predefined set of error
// detail types
// in the package `google.rpc` that can be used for common error
// conditions.
//
// # Language mapping
//
// The `Status` message is the logical representation of the error
// model, but it
// is not necessarily the actual wire format. When the `Status` message
// is
// exposed in different client libraries and different wire protocols,
// it can be
// mapped differently. For example, it will likely be mapped to some
// exceptions
// in Java, but more likely mapped to some error codes in C.
//
// # Other uses
//
// The error model and the `Status` message can be used in a variety
// of
// environments, either with or without APIs, to provide a
// consistent developer experience across different
// environments.
//
// Example uses of this error model include:
//
// - Partial errors. If a service needs to return partial errors to the
// client,
//     it may embed the `Status` in the normal response to indicate the
// partial
//     errors.
//
// - Workflow errors. A typical workflow has multiple steps. Each step
// may
//     have a `Status` message for error reporting.
//
// - Batch operations. If a client uses batch request and batch
// response, the
//     `Status` message should be used directly inside batch response,
// one for
//     each error sub-response.
//
// - Asynchronous operations. If an API call embeds asynchronous
// operation
//     results in its response, the status of those operations should
// be
//     represented directly using the `Status` message.
//
// - Logging. If some API errors are stored in logs, the message
// `Status` could
//     be used directly after any stripping needed for security/privacy
// reasons.
type Status struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details.  There is a
	// common set of
	// message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any
	// user-facing error message should be localized and sent in
	// the
	// google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

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

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

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

// TextSpan: Represents an output piece of text.
type TextSpan struct {
	// BeginOffset: The API calculates the beginning offset of the content
	// in the original
	// document according to the EncodingType specified in the API request.
	BeginOffset int64 `json:"beginOffset,omitempty"`

	// Content: The content of the output text.
	Content string `json:"content,omitempty"`

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

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

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

// Token: Represents the smallest syntactic building block of the text.
type Token struct {
	// DependencyEdge: Dependency tree parse for this token.
	DependencyEdge *DependencyEdge `json:"dependencyEdge,omitempty"`

	// Lemma: [Lemma](https://en.wikipedia.org/wiki/Lemma_%28morphology%29)
	// of the token.
	Lemma string `json:"lemma,omitempty"`

	// PartOfSpeech: Parts of speech tag for this token.
	PartOfSpeech *PartOfSpeech `json:"partOfSpeech,omitempty"`

	// Text: The token text.
	Text *TextSpan `json:"text,omitempty"`

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

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

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

// method id "language.documents.analyzeEntities":

type DocumentsAnalyzeEntitiesCall struct {
	s                      *Service
	analyzeentitiesrequest *AnalyzeEntitiesRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// AnalyzeEntities: Finds named entities (currently proper names and
// common nouns) in the text
// along with entity types, salience, mentions for each entity,
// and
// other properties.
func (r *DocumentsService) AnalyzeEntities(analyzeentitiesrequest *AnalyzeEntitiesRequest) *DocumentsAnalyzeEntitiesCall {
	c := &DocumentsAnalyzeEntitiesCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.analyzeentitiesrequest = analyzeentitiesrequest
	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 *DocumentsAnalyzeEntitiesCall) Fields(s ...googleapi.Field) *DocumentsAnalyzeEntitiesCall {
	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 *DocumentsAnalyzeEntitiesCall) Context(ctx context.Context) *DocumentsAnalyzeEntitiesCall {
	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 *DocumentsAnalyzeEntitiesCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsAnalyzeEntitiesCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.analyzeentitiesrequest)
	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, "v1beta2/documents:analyzeEntities")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "language.documents.analyzeEntities" call.
// Exactly one of *AnalyzeEntitiesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AnalyzeEntitiesResponse.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 *DocumentsAnalyzeEntitiesCall) Do(opts ...googleapi.CallOption) (*AnalyzeEntitiesResponse, 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 := &AnalyzeEntitiesResponse{
		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": "Finds named entities (currently proper names and common nouns) in the text\nalong with entity types, salience, mentions for each entity, and\nother properties.",
	//   "flatPath": "v1beta2/documents:analyzeEntities",
	//   "httpMethod": "POST",
	//   "id": "language.documents.analyzeEntities",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1beta2/documents:analyzeEntities",
	//   "request": {
	//     "$ref": "AnalyzeEntitiesRequest"
	//   },
	//   "response": {
	//     "$ref": "AnalyzeEntitiesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-language",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "language.documents.analyzeEntitySentiment":

type DocumentsAnalyzeEntitySentimentCall struct {
	s                             *Service
	analyzeentitysentimentrequest *AnalyzeEntitySentimentRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// AnalyzeEntitySentiment: Finds entities, similar to AnalyzeEntities in
// the text and analyzes
// sentiment associated with each entity and its mentions.
func (r *DocumentsService) AnalyzeEntitySentiment(analyzeentitysentimentrequest *AnalyzeEntitySentimentRequest) *DocumentsAnalyzeEntitySentimentCall {
	c := &DocumentsAnalyzeEntitySentimentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.analyzeentitysentimentrequest = analyzeentitysentimentrequest
	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 *DocumentsAnalyzeEntitySentimentCall) Fields(s ...googleapi.Field) *DocumentsAnalyzeEntitySentimentCall {
	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 *DocumentsAnalyzeEntitySentimentCall) Context(ctx context.Context) *DocumentsAnalyzeEntitySentimentCall {
	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 *DocumentsAnalyzeEntitySentimentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsAnalyzeEntitySentimentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.analyzeentitysentimentrequest)
	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, "v1beta2/documents:analyzeEntitySentiment")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "language.documents.analyzeEntitySentiment" call.
// Exactly one of *AnalyzeEntitySentimentResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AnalyzeEntitySentimentResponse.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 *DocumentsAnalyzeEntitySentimentCall) Do(opts ...googleapi.CallOption) (*AnalyzeEntitySentimentResponse, 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 := &AnalyzeEntitySentimentResponse{
		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": "Finds entities, similar to AnalyzeEntities in the text and analyzes\nsentiment associated with each entity and its mentions.",
	//   "flatPath": "v1beta2/documents:analyzeEntitySentiment",
	//   "httpMethod": "POST",
	//   "id": "language.documents.analyzeEntitySentiment",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1beta2/documents:analyzeEntitySentiment",
	//   "request": {
	//     "$ref": "AnalyzeEntitySentimentRequest"
	//   },
	//   "response": {
	//     "$ref": "AnalyzeEntitySentimentResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-language",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "language.documents.analyzeSentiment":

type DocumentsAnalyzeSentimentCall struct {
	s                       *Service
	analyzesentimentrequest *AnalyzeSentimentRequest
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// AnalyzeSentiment: Analyzes the sentiment of the provided text.
func (r *DocumentsService) AnalyzeSentiment(analyzesentimentrequest *AnalyzeSentimentRequest) *DocumentsAnalyzeSentimentCall {
	c := &DocumentsAnalyzeSentimentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.analyzesentimentrequest = analyzesentimentrequest
	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 *DocumentsAnalyzeSentimentCall) Fields(s ...googleapi.Field) *DocumentsAnalyzeSentimentCall {
	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 *DocumentsAnalyzeSentimentCall) Context(ctx context.Context) *DocumentsAnalyzeSentimentCall {
	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 *DocumentsAnalyzeSentimentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsAnalyzeSentimentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.analyzesentimentrequest)
	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, "v1beta2/documents:analyzeSentiment")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "language.documents.analyzeSentiment" call.
// Exactly one of *AnalyzeSentimentResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *AnalyzeSentimentResponse.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 *DocumentsAnalyzeSentimentCall) Do(opts ...googleapi.CallOption) (*AnalyzeSentimentResponse, 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 := &AnalyzeSentimentResponse{
		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": "Analyzes the sentiment of the provided text.",
	//   "flatPath": "v1beta2/documents:analyzeSentiment",
	//   "httpMethod": "POST",
	//   "id": "language.documents.analyzeSentiment",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1beta2/documents:analyzeSentiment",
	//   "request": {
	//     "$ref": "AnalyzeSentimentRequest"
	//   },
	//   "response": {
	//     "$ref": "AnalyzeSentimentResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-language",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "language.documents.analyzeSyntax":

type DocumentsAnalyzeSyntaxCall struct {
	s                    *Service
	analyzesyntaxrequest *AnalyzeSyntaxRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// AnalyzeSyntax: Analyzes the syntax of the text and provides sentence
// boundaries and
// tokenization along with part of speech tags, dependency trees, and
// other
// properties.
func (r *DocumentsService) AnalyzeSyntax(analyzesyntaxrequest *AnalyzeSyntaxRequest) *DocumentsAnalyzeSyntaxCall {
	c := &DocumentsAnalyzeSyntaxCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.analyzesyntaxrequest = analyzesyntaxrequest
	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 *DocumentsAnalyzeSyntaxCall) Fields(s ...googleapi.Field) *DocumentsAnalyzeSyntaxCall {
	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 *DocumentsAnalyzeSyntaxCall) Context(ctx context.Context) *DocumentsAnalyzeSyntaxCall {
	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 *DocumentsAnalyzeSyntaxCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsAnalyzeSyntaxCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.analyzesyntaxrequest)
	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, "v1beta2/documents:analyzeSyntax")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "language.documents.analyzeSyntax" call.
// Exactly one of *AnalyzeSyntaxResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AnalyzeSyntaxResponse.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 *DocumentsAnalyzeSyntaxCall) Do(opts ...googleapi.CallOption) (*AnalyzeSyntaxResponse, 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 := &AnalyzeSyntaxResponse{
		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": "Analyzes the syntax of the text and provides sentence boundaries and\ntokenization along with part of speech tags, dependency trees, and other\nproperties.",
	//   "flatPath": "v1beta2/documents:analyzeSyntax",
	//   "httpMethod": "POST",
	//   "id": "language.documents.analyzeSyntax",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1beta2/documents:analyzeSyntax",
	//   "request": {
	//     "$ref": "AnalyzeSyntaxRequest"
	//   },
	//   "response": {
	//     "$ref": "AnalyzeSyntaxResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-language",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "language.documents.annotateText":

type DocumentsAnnotateTextCall struct {
	s                   *Service
	annotatetextrequest *AnnotateTextRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// AnnotateText: A convenience method that provides all syntax,
// sentiment, entity, and
// classification features in one call.
func (r *DocumentsService) AnnotateText(annotatetextrequest *AnnotateTextRequest) *DocumentsAnnotateTextCall {
	c := &DocumentsAnnotateTextCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.annotatetextrequest = annotatetextrequest
	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 *DocumentsAnnotateTextCall) Fields(s ...googleapi.Field) *DocumentsAnnotateTextCall {
	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 *DocumentsAnnotateTextCall) Context(ctx context.Context) *DocumentsAnnotateTextCall {
	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 *DocumentsAnnotateTextCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsAnnotateTextCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.annotatetextrequest)
	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, "v1beta2/documents:annotateText")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "language.documents.annotateText" call.
// Exactly one of *AnnotateTextResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AnnotateTextResponse.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 *DocumentsAnnotateTextCall) Do(opts ...googleapi.CallOption) (*AnnotateTextResponse, 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 := &AnnotateTextResponse{
		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": "A convenience method that provides all syntax, sentiment, entity, and\nclassification features in one call.",
	//   "flatPath": "v1beta2/documents:annotateText",
	//   "httpMethod": "POST",
	//   "id": "language.documents.annotateText",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1beta2/documents:annotateText",
	//   "request": {
	//     "$ref": "AnnotateTextRequest"
	//   },
	//   "response": {
	//     "$ref": "AnnotateTextResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-language",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "language.documents.classifyText":

type DocumentsClassifyTextCall struct {
	s                   *Service
	classifytextrequest *ClassifyTextRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// ClassifyText: Classifies a document into categories.
func (r *DocumentsService) ClassifyText(classifytextrequest *ClassifyTextRequest) *DocumentsClassifyTextCall {
	c := &DocumentsClassifyTextCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.classifytextrequest = classifytextrequest
	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 *DocumentsClassifyTextCall) Fields(s ...googleapi.Field) *DocumentsClassifyTextCall {
	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 *DocumentsClassifyTextCall) Context(ctx context.Context) *DocumentsClassifyTextCall {
	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 *DocumentsClassifyTextCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DocumentsClassifyTextCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.classifytextrequest)
	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, "v1beta2/documents:classifyText")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "language.documents.classifyText" call.
// Exactly one of *ClassifyTextResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ClassifyTextResponse.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 *DocumentsClassifyTextCall) Do(opts ...googleapi.CallOption) (*ClassifyTextResponse, 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 := &ClassifyTextResponse{
		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": "Classifies a document into categories.",
	//   "flatPath": "v1beta2/documents:classifyText",
	//   "httpMethod": "POST",
	//   "id": "language.documents.classifyText",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1beta2/documents:classifyText",
	//   "request": {
	//     "$ref": "ClassifyTextRequest"
	//   },
	//   "response": {
	//     "$ref": "ClassifyTextResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-language",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
