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

// Code generated file. DO NOT EDIT.

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

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

	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

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

const apiId = "commentanalyzer:v1alpha1"
const apiName = "commentanalyzer"
const apiVersion = "v1alpha1"
const basePath = "https://commentanalyzer.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View your email address
	UserinfoEmailScope = "https://www.googleapis.com/auth/userinfo.email"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/userinfo.email",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Comments = NewCommentsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Comments *CommentsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewCommentsService(s *Service) *CommentsService {
	rs := &CommentsService{s: s}
	return rs
}

type CommentsService struct {
	s *Service
}

// AnalyzeCommentRequest: The comment analysis request message.
type AnalyzeCommentRequest struct {
	// ClientToken: Opaque token that is echoed from the request to the
	// response.
	ClientToken string `json:"clientToken,omitempty"`

	// Comment: The comment to analyze.
	Comment *TextEntry `json:"comment,omitempty"`

	// CommunityId: Optional identifier associating this
	// AnalyzeCommentRequest with a
	// particular client's community. Different communities may have
	// different
	// norms and rules. Specifying this value enables us to explore
	// building
	// community-specific models for clients.
	CommunityId string `json:"communityId,omitempty"`

	// Context: The context of the comment.
	Context *Context `json:"context,omitempty"`

	// DoNotStore: Do not store the comment or context sent in this request.
	// By default, the
	// service may store comments/context for debugging purposes.
	DoNotStore bool `json:"doNotStore,omitempty"`

	// Languages: The language(s) of the comment and context (if none are
	// specified, the
	// language is automatically detected). If multiple languages are
	// specified,
	// the text is checked in all of them that are supported. Both ISO and
	// BCP-47
	// language codes are accepted.
	// Current Language Restrictions:
	//  * Only English text ("en") is supported.
	// If none of the languages specified by the caller are supported,
	// an
	// `UNIMPLEMENTED` error is returned.
	Languages []string `json:"languages,omitempty"`

	// RequestedAttributes: Specification of requested attributes. The
	// AttributeParameters serve as
	// configuration for each associated attribute. The map keys are
	// attribute
	// names. The following attributes are available:
	// "ATTACK_ON_AUTHOR" - Attack on author of original article or
	// post.
	// "ATTACK_ON_COMMENTER" - Attack on fellow
	// commenter.
	// "ATTACK_ON_PUBLISHER" - Attack on publisher of
	// article/post.
	// "INCOHERENT" - Difficult to understand, nonsensical.
	// "INFLAMMATORY" - Intending to provoke or inflame.
	// "OBSCENE" - Obscene, such as cursing.
	// "OFF_TOPIC" - Not related to the original topic.
	// "SPAM" - Commercial/advertising spam content.
	// "UNSUBSTANTIAL" - Trivial.
	RequestedAttributes map[string]AttributeParameters `json:"requestedAttributes,omitempty"`

	// SessionId: Session ID. Used to join related RPCs into a single
	// session. For example,
	// an interactive tool that calls both the AnalyzeComment
	// and
	// SuggestCommentScore RPCs should set all invocations of both RPCs to
	// the
	// same Session ID, typically a random 64-bit integer.
	SessionId string `json:"sessionId,omitempty"`

	// SpanAnnotations: An advisory parameter that will return span
	// annotations if the model
	// is capable of providing scores with sub-comment resolution. This
	// will
	// likely increase the size of the returned message.
	SpanAnnotations bool `json:"spanAnnotations,omitempty"`

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

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

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

// AnalyzeCommentResponse: The comment analysis response message.
type AnalyzeCommentResponse struct {
	// AttributeScores: Scores for the requested attributes. The map keys
	// are attribute names (same
	// as the requested_attribute field in AnalyzeCommentRequest, for
	// example
	// "ATTACK_ON_AUTHOR", "INFLAMMATORY", etc).
	AttributeScores map[string]AttributeScores `json:"attributeScores,omitempty"`

	// ClientToken: Same token from the original AnalyzeCommentRequest.
	ClientToken string `json:"clientToken,omitempty"`

	// DetectedLanguages: Contains the language as detected from the text
	// content.  If no language
	// was specified in the request, the first (the most likely) language is
	// used
	// to select an appropriate model.  Sorted in order of likelihood.
	DetectedLanguages []string `json:"detectedLanguages,omitempty"`

	// Languages: The language(s) requested by the client, as specified in
	// the request. If
	// the request did not specify any language, this will be empty and
	// the
	// detected_languages field will be populated.
	Languages []string `json:"languages,omitempty"`

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

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

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

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

// ArticleAndParentComment: A type of context specific to a comment left
// on a single-threaded comment
// message board, where comments are either a top level comment or the
// child of
// a top level comment.
type ArticleAndParentComment struct {
	// Article: The source content about which the comment was made (article
	// text, article
	// summary, video transcript, etc).
	Article *TextEntry `json:"article,omitempty"`

	// ParentComment: Refers to text that is a direct parent of the source
	// comment, such as in a
	// one-deep threaded message board. This field will only be present
	// for
	// comments that are replies to other comments and will not be populated
	// for
	// direct comments on the article_text.
	ParentComment *TextEntry `json:"parentComment,omitempty"`

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

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

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

// AttributeParameters: Configurable parameters for attribute scoring.
type AttributeParameters struct {
	// ScoreThreshold: Don't return scores for this attribute that are below
	// this threshold. If
	// unset, a default threshold will be applied. A FloatValue wrapper is
	// used to
	// distinguish between 0 vs. default/unset.
	ScoreThreshold float64 `json:"scoreThreshold,omitempty"`

	// ScoreType: What type of scores to return. If unset, defaults to
	// probability scores.
	//
	// Possible values:
	//   "SCORE_TYPE_UNSPECIFIED" - Unspecified. Defaults to PROBABILITY
	// scores if available, and otherwise
	// RAW. Every model has a RAW score.
	//   "PROBABILITY" - Probability scores are in the range [0, 1] and
	// indicate level of confidence
	// in the attribute label.
	//   "STD_DEV_SCORE" - Standard deviation scores are in the range (-inf,
	// +inf).
	//   "PERCENTILE" - Percentile scores are in the range [0, 1] and
	// indicate the percentile of
	// the raw score, normalized with a test dataset. This is not
	// generally
	// recommended, as the normalization is dependent on the dataset used,
	// which
	// may not match other usecases.
	//   "RAW" - Raw scores are the raw values from the model, and may take
	// any value. This
	// is primarily for debugging/testing, and not generally recommended.
	ScoreType string `json:"scoreType,omitempty"`

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

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

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

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

// AttributeScores: This holds score values for a single attribute. It
// contains both per-span
// scores as well as an overall summary score..
type AttributeScores struct {
	// SpanScores: Per-span scores.
	SpanScores []*SpanScore `json:"spanScores,omitempty"`

	// SummaryScore: Overall score for comment as a whole.
	SummaryScore *Score `json:"summaryScore,omitempty"`

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

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

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

// Context: Context is typically something that a Comment is referencing
// or replying to
// (such as an article, or previous comment).
// Note: Populate only ONE OF the following fields. The oneof syntax
// cannot be
// used because that would require nesting entries inside another
// message and
// breaking backwards compatibility. The server will return an error if
// more
// than one of the following fields is present.
type Context struct {
	// ArticleAndParentComment: Information about the source for which the
	// original comment was made, and
	// any parent comment info.
	ArticleAndParentComment *ArticleAndParentComment `json:"articleAndParentComment,omitempty"`

	// Entries: A list of messages. For example, a linear comments section
	// or forum thread.
	Entries []*TextEntry `json:"entries,omitempty"`

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

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

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

// Score: Analysis scores are described by a value and a ScoreType.
type Score struct {
	// Type: The type of the above value.
	//
	// Possible values:
	//   "SCORE_TYPE_UNSPECIFIED" - Unspecified. Defaults to PROBABILITY
	// scores if available, and otherwise
	// RAW. Every model has a RAW score.
	//   "PROBABILITY" - Probability scores are in the range [0, 1] and
	// indicate level of confidence
	// in the attribute label.
	//   "STD_DEV_SCORE" - Standard deviation scores are in the range (-inf,
	// +inf).
	//   "PERCENTILE" - Percentile scores are in the range [0, 1] and
	// indicate the percentile of
	// the raw score, normalized with a test dataset. This is not
	// generally
	// recommended, as the normalization is dependent on the dataset used,
	// which
	// may not match other usecases.
	//   "RAW" - Raw scores are the raw values from the model, and may take
	// any value. This
	// is primarily for debugging/testing, and not generally recommended.
	Type string `json:"type,omitempty"`

	// Value: Score value. Semantics described by type below.
	Value float64 `json:"value,omitempty"`

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

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

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

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

// SpanScore: This is a single score for a given span of text.
type SpanScore struct {
	// Begin: "begin" and "end" describe the span of the original text that
	// the attribute
	// score applies to. The values are the UTF-16 codepoint range. "end"
	// is
	// exclusive. For example, with the text "Hi there", the begin/end pair
	// (0,2)
	// describes the text "Hi".
	//
	// If "begin" and "end" are unset, the score applies to the full text.
	Begin int64 `json:"begin,omitempty"`

	End int64 `json:"end,omitempty"`

	// Score: The score value.
	Score *Score `json:"score,omitempty"`

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

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

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

// SuggestCommentScoreRequest: The comment score suggestion request
// message.
type SuggestCommentScoreRequest struct {
	// AttributeScores: Attribute scores for the comment. The map keys are
	// attribute names, same as
	// the requested_attribute field in AnalyzeCommentRequest (for
	// example
	// "ATTACK_ON_AUTHOR", "INFLAMMATORY", etc.). This field has the same
	// type as
	// the `attribute_scores` field in AnalyzeCommentResponse.
	//
	// To specify an overall attribute score for the entire comment as a
	// whole,
	// use the `summary_score` field of the mapped AttributeScores object.
	// To
	// specify scores on specific subparts of the comment, use the
	// `span_scores`
	// field. All SpanScore objects must have begin and end fields set.
	//
	// All Score objects must be explicitly set (for binary classification,
	// use
	// the score values 0 and 1). If Score objects don't include a
	// ScoreType,
	// `PROBABILITY` is assumed.
	//
	// `attribute_scores` must not be empty. The mapped AttributeScores
	// objects
	// also must not be empty. An `INVALID_ARGUMENT` error is returned for
	// all
	// malformed requests.
	AttributeScores map[string]AttributeScores `json:"attributeScores,omitempty"`

	// ClientToken: Opaque token that is echoed from the request to the
	// response.
	ClientToken string `json:"clientToken,omitempty"`

	// Comment: The comment being scored.
	Comment *TextEntry `json:"comment,omitempty"`

	// CommunityId: Optional identifier associating this comment score
	// suggestion with a
	// particular sub-community. Different communities may have different
	// norms
	// and rules. Specifying this value enables training
	// community-specific
	// models.
	CommunityId string `json:"communityId,omitempty"`

	// Context: The context of the comment.
	Context *Context `json:"context,omitempty"`

	// Languages: The language(s) of the comment and context (if none are
	// specified, the
	// language is automatically detected). If multiple languages are
	// specified,
	// the text is checked in all of them that are supported. Both ISO and
	// BCP-47
	// language codes are accepted.
	// Current Language Restrictions:
	//  * Only English text ("en") is supported.
	// If none of the languages specified by the caller are supported,
	// an
	// `UNIMPLEMENTED` error is returned.
	Languages []string `json:"languages,omitempty"`

	// SessionId: Session ID. Used to join related RPCs into a single
	// session. For example,
	// an interactive tool that calls both the AnalyzeComment
	// and
	// SuggestCommentScore RPCs should set all invocations of both RPCs to
	// the
	// same Session ID, typically a random 64-bit integer.
	SessionId string `json:"sessionId,omitempty"`

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

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

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

// SuggestCommentScoreResponse: The comment score suggestion response
// message.
type SuggestCommentScoreResponse struct {
	// ClientToken: Same token from the original SuggestCommentScoreRequest.
	ClientToken string `json:"clientToken,omitempty"`

	// DetectedLanguages: The list of languages detected from the comment
	// text.
	DetectedLanguages []string `json:"detectedLanguages,omitempty"`

	// RequestedLanguages: The list of languages provided in the request.
	RequestedLanguages []string `json:"requestedLanguages,omitempty"`

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

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

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

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

// TextEntry: Represents a body of text.
type TextEntry struct {
	// Text: UTF-8 encoded text.
	Text string `json:"text,omitempty"`

	// Type: Type of the text field.
	//
	// Possible values:
	//   "TEXT_TYPE_UNSPECIFIED" - The content type is not specified. Text
	// will be interpreted as plain text
	// by default.
	//   "PLAIN_TEXT" - Plain text.
	//   "HTML" - HTML.
	Type string `json:"type,omitempty"`

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

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

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

// method id "commentanalyzer.comments.analyze":

type CommentsAnalyzeCall struct {
	s                     *Service
	analyzecommentrequest *AnalyzeCommentRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Analyze: Analyzes the provided text and returns scores for requested
// attributes.
func (r *CommentsService) Analyze(analyzecommentrequest *AnalyzeCommentRequest) *CommentsAnalyzeCall {
	c := &CommentsAnalyzeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.analyzecommentrequest = analyzecommentrequest
	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 *CommentsAnalyzeCall) Fields(s ...googleapi.Field) *CommentsAnalyzeCall {
	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 *CommentsAnalyzeCall) Context(ctx context.Context) *CommentsAnalyzeCall {
	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 *CommentsAnalyzeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CommentsAnalyzeCall) 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.analyzecommentrequest)
	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, "v1alpha1/comments:analyze")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "commentanalyzer.comments.analyze" call.
// Exactly one of *AnalyzeCommentResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AnalyzeCommentResponse.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 *CommentsAnalyzeCall) Do(opts ...googleapi.CallOption) (*AnalyzeCommentResponse, 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 := &AnalyzeCommentResponse{
		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 provided text and returns scores for requested attributes.",
	//   "flatPath": "v1alpha1/comments:analyze",
	//   "httpMethod": "POST",
	//   "id": "commentanalyzer.comments.analyze",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha1/comments:analyze",
	//   "request": {
	//     "$ref": "AnalyzeCommentRequest"
	//   },
	//   "response": {
	//     "$ref": "AnalyzeCommentResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}

// method id "commentanalyzer.comments.suggestscore":

type CommentsSuggestscoreCall struct {
	s                          *Service
	suggestcommentscorerequest *SuggestCommentScoreRequest
	urlParams_                 gensupport.URLParams
	ctx_                       context.Context
	header_                    http.Header
}

// Suggestscore: Suggest comment scores as training data.
func (r *CommentsService) Suggestscore(suggestcommentscorerequest *SuggestCommentScoreRequest) *CommentsSuggestscoreCall {
	c := &CommentsSuggestscoreCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.suggestcommentscorerequest = suggestcommentscorerequest
	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 *CommentsSuggestscoreCall) Fields(s ...googleapi.Field) *CommentsSuggestscoreCall {
	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 *CommentsSuggestscoreCall) Context(ctx context.Context) *CommentsSuggestscoreCall {
	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 *CommentsSuggestscoreCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CommentsSuggestscoreCall) 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.suggestcommentscorerequest)
	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, "v1alpha1/comments:suggestscore")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "commentanalyzer.comments.suggestscore" call.
// Exactly one of *SuggestCommentScoreResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *SuggestCommentScoreResponse.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 *CommentsSuggestscoreCall) Do(opts ...googleapi.CallOption) (*SuggestCommentScoreResponse, 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 := &SuggestCommentScoreResponse{
		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": "Suggest comment scores as training data.",
	//   "flatPath": "v1alpha1/comments:suggestscore",
	//   "httpMethod": "POST",
	//   "id": "commentanalyzer.comments.suggestscore",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha1/comments:suggestscore",
	//   "request": {
	//     "$ref": "SuggestCommentScoreRequest"
	//   },
	//   "response": {
	//     "$ref": "SuggestCommentScoreResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/userinfo.email"
	//   ]
	// }

}
