// 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/v1"
//   ...
//   languageService, err := language.New(oauthHttpClient)
package language // import "google.golang.org/api/language/v1"

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:v1"
const apiName = "language"
const apiVersion = "v1"
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.
	//
	// 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. (For more
// information on dependency labels,
// see
// http://www.aclweb.org/anthology/P13-2017
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.
type Features struct {
	// ClassifyText: Classify the full document into 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.
// Parts of speech
// are as defined
// in
// http://www.lrec-conf.org/proceedings/lrec2012/pdf/274_Paper.pdf
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.
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, "v1/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": "v1/documents:analyzeEntities",
	//   "httpMethod": "POST",
	//   "id": "language.documents.analyzeEntities",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/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, "v1/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": "v1/documents:analyzeEntitySentiment",
	//   "httpMethod": "POST",
	//   "id": "language.documents.analyzeEntitySentiment",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/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, "v1/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": "v1/documents:analyzeSentiment",
	//   "httpMethod": "POST",
	//   "id": "language.documents.analyzeSentiment",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/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, "v1/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": "v1/documents:analyzeSyntax",
	//   "httpMethod": "POST",
	//   "id": "language.documents.analyzeSyntax",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/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 the features
// that analyzeSentiment,
// analyzeEntities, and analyzeSyntax provide 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, "v1/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 the features that analyzeSentiment,\nanalyzeEntities, and analyzeSyntax provide in one call.",
	//   "flatPath": "v1/documents:annotateText",
	//   "httpMethod": "POST",
	//   "id": "language.documents.annotateText",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/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, "v1/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": "v1/documents:classifyText",
	//   "httpMethod": "POST",
	//   "id": "language.documents.classifyText",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/documents:classifyText",
	//   "request": {
	//     "$ref": "ClassifyTextRequest"
	//   },
	//   "response": {
	//     "$ref": "ClassifyTextResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-language",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
