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

// Code generated file. DO NOT EDIT.

// Package dialogflow provides access to the Dialogflow API.
//
// This package is DEPRECATED. Use package cloud.google.com/go/dialogflow/apiv2 instead.
//
// For product documentation, see: https://cloud.google.com/dialogflow/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/dialogflow/v2"
//   ...
//   ctx := context.Background()
//   dialogflowService, err := dialogflow.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   dialogflowService, err := dialogflow.NewService(ctx, option.WithScopes(dialogflow.DialogflowScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   dialogflowService, err := dialogflow.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, ...)
//   dialogflowService, err := dialogflow.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package dialogflow // import "google.golang.org/api/dialogflow/v2"

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

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	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
var _ = internaloption.WithDefaultEndpoint

const apiId = "dialogflow:v2"
const apiName = "dialogflow"
const apiVersion = "v2"
const basePath = "https://dialogflow.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"

	// View, manage and query your Dialogflow agents
	DialogflowScope = "https://www.googleapis.com/auth/dialogflow"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud-platform",
		"https://www.googleapis.com/auth/dialogflow",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	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.Projects = NewProjectsService(s)
	return s, nil
}

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

	Projects *ProjectsService
}

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

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Agent = NewProjectsAgentService(s)
	rs.Locations = NewProjectsLocationsService(s)
	rs.Operations = NewProjectsOperationsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Agent *ProjectsAgentService

	Locations *ProjectsLocationsService

	Operations *ProjectsOperationsService
}

func NewProjectsAgentService(s *Service) *ProjectsAgentService {
	rs := &ProjectsAgentService{s: s}
	rs.EntityTypes = NewProjectsAgentEntityTypesService(s)
	rs.Environments = NewProjectsAgentEnvironmentsService(s)
	rs.Intents = NewProjectsAgentIntentsService(s)
	rs.Sessions = NewProjectsAgentSessionsService(s)
	return rs
}

type ProjectsAgentService struct {
	s *Service

	EntityTypes *ProjectsAgentEntityTypesService

	Environments *ProjectsAgentEnvironmentsService

	Intents *ProjectsAgentIntentsService

	Sessions *ProjectsAgentSessionsService
}

func NewProjectsAgentEntityTypesService(s *Service) *ProjectsAgentEntityTypesService {
	rs := &ProjectsAgentEntityTypesService{s: s}
	rs.Entities = NewProjectsAgentEntityTypesEntitiesService(s)
	return rs
}

type ProjectsAgentEntityTypesService struct {
	s *Service

	Entities *ProjectsAgentEntityTypesEntitiesService
}

func NewProjectsAgentEntityTypesEntitiesService(s *Service) *ProjectsAgentEntityTypesEntitiesService {
	rs := &ProjectsAgentEntityTypesEntitiesService{s: s}
	return rs
}

type ProjectsAgentEntityTypesEntitiesService struct {
	s *Service
}

func NewProjectsAgentEnvironmentsService(s *Service) *ProjectsAgentEnvironmentsService {
	rs := &ProjectsAgentEnvironmentsService{s: s}
	rs.Users = NewProjectsAgentEnvironmentsUsersService(s)
	return rs
}

type ProjectsAgentEnvironmentsService struct {
	s *Service

	Users *ProjectsAgentEnvironmentsUsersService
}

func NewProjectsAgentEnvironmentsUsersService(s *Service) *ProjectsAgentEnvironmentsUsersService {
	rs := &ProjectsAgentEnvironmentsUsersService{s: s}
	rs.Sessions = NewProjectsAgentEnvironmentsUsersSessionsService(s)
	return rs
}

type ProjectsAgentEnvironmentsUsersService struct {
	s *Service

	Sessions *ProjectsAgentEnvironmentsUsersSessionsService
}

func NewProjectsAgentEnvironmentsUsersSessionsService(s *Service) *ProjectsAgentEnvironmentsUsersSessionsService {
	rs := &ProjectsAgentEnvironmentsUsersSessionsService{s: s}
	rs.Contexts = NewProjectsAgentEnvironmentsUsersSessionsContextsService(s)
	rs.EntityTypes = NewProjectsAgentEnvironmentsUsersSessionsEntityTypesService(s)
	return rs
}

type ProjectsAgentEnvironmentsUsersSessionsService struct {
	s *Service

	Contexts *ProjectsAgentEnvironmentsUsersSessionsContextsService

	EntityTypes *ProjectsAgentEnvironmentsUsersSessionsEntityTypesService
}

func NewProjectsAgentEnvironmentsUsersSessionsContextsService(s *Service) *ProjectsAgentEnvironmentsUsersSessionsContextsService {
	rs := &ProjectsAgentEnvironmentsUsersSessionsContextsService{s: s}
	return rs
}

type ProjectsAgentEnvironmentsUsersSessionsContextsService struct {
	s *Service
}

func NewProjectsAgentEnvironmentsUsersSessionsEntityTypesService(s *Service) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesService {
	rs := &ProjectsAgentEnvironmentsUsersSessionsEntityTypesService{s: s}
	return rs
}

type ProjectsAgentEnvironmentsUsersSessionsEntityTypesService struct {
	s *Service
}

func NewProjectsAgentIntentsService(s *Service) *ProjectsAgentIntentsService {
	rs := &ProjectsAgentIntentsService{s: s}
	return rs
}

type ProjectsAgentIntentsService struct {
	s *Service
}

func NewProjectsAgentSessionsService(s *Service) *ProjectsAgentSessionsService {
	rs := &ProjectsAgentSessionsService{s: s}
	rs.Contexts = NewProjectsAgentSessionsContextsService(s)
	rs.EntityTypes = NewProjectsAgentSessionsEntityTypesService(s)
	return rs
}

type ProjectsAgentSessionsService struct {
	s *Service

	Contexts *ProjectsAgentSessionsContextsService

	EntityTypes *ProjectsAgentSessionsEntityTypesService
}

func NewProjectsAgentSessionsContextsService(s *Service) *ProjectsAgentSessionsContextsService {
	rs := &ProjectsAgentSessionsContextsService{s: s}
	return rs
}

type ProjectsAgentSessionsContextsService struct {
	s *Service
}

func NewProjectsAgentSessionsEntityTypesService(s *Service) *ProjectsAgentSessionsEntityTypesService {
	rs := &ProjectsAgentSessionsEntityTypesService{s: s}
	return rs
}

type ProjectsAgentSessionsEntityTypesService struct {
	s *Service
}

func NewProjectsLocationsService(s *Service) *ProjectsLocationsService {
	rs := &ProjectsLocationsService{s: s}
	rs.Operations = NewProjectsLocationsOperationsService(s)
	return rs
}

type ProjectsLocationsService struct {
	s *Service

	Operations *ProjectsLocationsOperationsService
}

func NewProjectsLocationsOperationsService(s *Service) *ProjectsLocationsOperationsService {
	rs := &ProjectsLocationsOperationsService{s: s}
	return rs
}

type ProjectsLocationsOperationsService struct {
	s *Service
}

func NewProjectsOperationsService(s *Service) *ProjectsOperationsService {
	rs := &ProjectsOperationsService{s: s}
	return rs
}

type ProjectsOperationsService struct {
	s *Service
}

// GoogleCloudDialogflowV2Agent: Represents a conversational agent.
type GoogleCloudDialogflowV2Agent struct {
	// ApiVersion: Optional. API version displayed in Dialogflow console. If
	// not specified,
	// V2 API is assumed. Clients are free to query different service
	// endpoints
	// for different API versions. However, bots connectors and webhook
	// calls will
	// follow the specified API version.
	//
	// Possible values:
	//   "API_VERSION_UNSPECIFIED" - Not specified.
	//   "API_VERSION_V1" - Legacy V1 API.
	//   "API_VERSION_V2" - V2 API.
	//   "API_VERSION_V2_BETA_1" - V2beta1 API.
	ApiVersion string `json:"apiVersion,omitempty"`

	// AvatarUri: Optional. The URI of the agent's avatar.
	// Avatars are used throughout the Dialogflow console and in the
	// self-hosted
	// [Web
	// Demo](https://cloud.google.com/dialogflow/docs/integr
	// ations/web-demo)
	// integration.
	AvatarUri string `json:"avatarUri,omitempty"`

	// ClassificationThreshold: Optional. To filter out false positive
	// results and still get variety in
	// matched natural language inputs for your agent, you can tune the
	// machine
	// learning classification threshold. If the returned score value is
	// less than
	// the threshold value, then a fallback intent will be triggered or, if
	// there
	// are no fallback intents defined, no intent will be triggered. The
	// score
	// values range from 0.0 (completely uncertain) to 1.0 (completely
	// certain).
	// If set to 0.0, the default of 0.3 is used.
	ClassificationThreshold float64 `json:"classificationThreshold,omitempty"`

	// DefaultLanguageCode: Required. The default language of the agent as a
	// language tag.
	// See
	// [Language
	// Support](https://cloud.google.com/dialogflow/docs/refere
	// nce/language)
	// for a list of the currently supported language codes. This field
	// cannot be
	// set by the `Update` method.
	DefaultLanguageCode string `json:"defaultLanguageCode,omitempty"`

	// Description: Optional. The description of this agent.
	// The maximum length is 500 characters. If exceeded, the request is
	// rejected.
	Description string `json:"description,omitempty"`

	// DisplayName: Required. The name of this agent.
	DisplayName string `json:"displayName,omitempty"`

	// EnableLogging: Optional. Determines whether this agent should log
	// conversation queries.
	EnableLogging bool `json:"enableLogging,omitempty"`

	// MatchMode: Optional. Determines how intents are detected from user
	// queries.
	//
	// Possible values:
	//   "MATCH_MODE_UNSPECIFIED" - Not specified.
	//   "MATCH_MODE_HYBRID" - Best for agents with a small number of
	// examples in intents and/or wide
	// use of templates syntax and composite entities.
	//   "MATCH_MODE_ML_ONLY" - Can be used for agents with a large number
	// of examples in intents,
	// especially the ones using @sys.any or very large custom entities.
	MatchMode string `json:"matchMode,omitempty"`

	// Parent: Required. The project of this agent.
	// Format: `projects/<Project ID>`.
	Parent string `json:"parent,omitempty"`

	// SupportedLanguageCodes: Optional. The list of all languages supported
	// by this agent (except for the
	// `default_language_code`).
	SupportedLanguageCodes []string `json:"supportedLanguageCodes,omitempty"`

	// Tier: Optional. The agent tier. If not specified, TIER_STANDARD is
	// assumed.
	//
	// Possible values:
	//   "TIER_UNSPECIFIED" - Not specified. This value should never be
	// used.
	//   "TIER_STANDARD" - Standard tier.
	//   "TIER_ENTERPRISE" - Enterprise tier (Essentials).
	//   "TIER_ENTERPRISE_PLUS" - Enterprise tier (Plus).
	Tier string `json:"tier,omitempty"`

	// TimeZone: Required. The time zone of this agent from the
	// [time zone database](https://www.iana.org/time-zones),
	// e.g.,
	// America/New_York, Europe/Paris.
	TimeZone string `json:"timeZone,omitempty"`

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

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

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

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

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

// GoogleCloudDialogflowV2AnnotatedMessagePart: Represents a part of a
// message possibly annotated with an entity. The part
// can be an entity or purely a part of the message between two entities
// or
// message start/end.
type GoogleCloudDialogflowV2AnnotatedMessagePart struct {
	// EntityType: The [Dialogflow system
	// entity
	// type](https://cloud.google.com/dialogflow/docs/reference/system
	// -entities)
	// of this message part. If this is empty, Dialogflow could not annotate
	// the
	// phrase part with a system entity.
	EntityType string `json:"entityType,omitempty"`

	// FormattedValue: The [Dialogflow system entity formatted
	// value
	// ](https://cloud.google.com/dialogflow/docs/reference/system-enti
	// ties) of
	// this message part. For example for a system entity of
	// type
	// `@sys.unit-currency`, this may contain:
	// <pre>
	// {
	//   "amount": 5,
	//   "currency": "USD"
	// }
	// </pre>
	FormattedValue interface{} `json:"formattedValue,omitempty"`

	// Text: A part of a message possibly annotated with an entity.
	Text string `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2BatchCreateEntitiesRequest: The request
// message for EntityTypes.BatchCreateEntities.
type GoogleCloudDialogflowV2BatchCreateEntitiesRequest struct {
	// Entities: Required. The entities to create.
	Entities []*GoogleCloudDialogflowV2EntityTypeEntity `json:"entities,omitempty"`

	// LanguageCode: Optional. The language of entity synonyms defined in
	// `entities`. If not
	// specified, the agent's default language is
	// used.
	// [Many
	// languages](https://cloud.google.com/dialogflow/docs/refere
	// nce/language)
	// are supported. Note: languages must be enabled in the agent before
	// they can
	// be used.
	LanguageCode string `json:"languageCode,omitempty"`

	// 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 *GoogleCloudDialogflowV2BatchCreateEntitiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2BatchCreateEntitiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2BatchDeleteEntitiesRequest: The request
// message for EntityTypes.BatchDeleteEntities.
type GoogleCloudDialogflowV2BatchDeleteEntitiesRequest struct {
	// EntityValues: Required. The reference `values` of the entities to
	// delete. Note that
	// these are not fully-qualified names, i.e. they don't start
	// with
	// `projects/<Project ID>`.
	EntityValues []string `json:"entityValues,omitempty"`

	// LanguageCode: Optional. The language of entity synonyms defined in
	// `entities`. If not
	// specified, the agent's default language is
	// used.
	// [Many
	// languages](https://cloud.google.com/dialogflow/docs/refere
	// nce/language)
	// are supported. Note: languages must be enabled in the agent before
	// they can
	// be used.
	LanguageCode string `json:"languageCode,omitempty"`

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

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

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

// GoogleCloudDialogflowV2BatchDeleteEntityTypesRequest: The request
// message for EntityTypes.BatchDeleteEntityTypes.
type GoogleCloudDialogflowV2BatchDeleteEntityTypesRequest struct {
	// EntityTypeNames: Required. The names entity types to delete. All
	// names must point to the
	// same agent as `parent`.
	EntityTypeNames []string `json:"entityTypeNames,omitempty"`

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

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

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

// GoogleCloudDialogflowV2BatchDeleteIntentsRequest: The request message
// for Intents.BatchDeleteIntents.
type GoogleCloudDialogflowV2BatchDeleteIntentsRequest struct {
	// Intents: Required. The collection of intents to delete. Only intent
	// `name` must be
	// filled in.
	Intents []*GoogleCloudDialogflowV2Intent `json:"intents,omitempty"`

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

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

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

// GoogleCloudDialogflowV2BatchUpdateEntitiesRequest: The request
// message for EntityTypes.BatchUpdateEntities.
type GoogleCloudDialogflowV2BatchUpdateEntitiesRequest struct {
	// Entities: Required. The entities to update or create.
	Entities []*GoogleCloudDialogflowV2EntityTypeEntity `json:"entities,omitempty"`

	// LanguageCode: Optional. The language of entity synonyms defined in
	// `entities`. If not
	// specified, the agent's default language is
	// used.
	// [Many
	// languages](https://cloud.google.com/dialogflow/docs/refere
	// nce/language)
	// are supported. Note: languages must be enabled in the agent before
	// they can
	// be used.
	LanguageCode string `json:"languageCode,omitempty"`

	// UpdateMask: Optional. The mask to control which fields get updated.
	UpdateMask string `json:"updateMask,omitempty"`

	// 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 *GoogleCloudDialogflowV2BatchUpdateEntitiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2BatchUpdateEntitiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2BatchUpdateEntityTypesRequest: The request
// message for EntityTypes.BatchUpdateEntityTypes.
type GoogleCloudDialogflowV2BatchUpdateEntityTypesRequest struct {
	// EntityTypeBatchInline: The collection of entity types to update or
	// create.
	EntityTypeBatchInline *GoogleCloudDialogflowV2EntityTypeBatch `json:"entityTypeBatchInline,omitempty"`

	// EntityTypeBatchUri: The URI to a Google Cloud Storage file containing
	// entity types to update
	// or create. The file format can either be a serialized proto
	// (of
	// EntityBatch type) or a JSON object. Note: The URI must start
	// with
	// "gs://".
	EntityTypeBatchUri string `json:"entityTypeBatchUri,omitempty"`

	// LanguageCode: Optional. The language of entity synonyms defined in
	// `entity_types`. If not
	// specified, the agent's default language is
	// used.
	// [Many
	// languages](https://cloud.google.com/dialogflow/docs/refere
	// nce/language)
	// are supported. Note: languages must be enabled in the agent before
	// they can
	// be used.
	LanguageCode string `json:"languageCode,omitempty"`

	// UpdateMask: Optional. The mask to control which fields get updated.
	UpdateMask string `json:"updateMask,omitempty"`

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

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

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

// GoogleCloudDialogflowV2BatchUpdateEntityTypesResponse: The response
// message for EntityTypes.BatchUpdateEntityTypes.
type GoogleCloudDialogflowV2BatchUpdateEntityTypesResponse struct {
	// EntityTypes: The collection of updated or created entity types.
	EntityTypes []*GoogleCloudDialogflowV2EntityType `json:"entityTypes,omitempty"`

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

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

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

// GoogleCloudDialogflowV2BatchUpdateIntentsRequest: The request message
// for Intents.BatchUpdateIntents.
type GoogleCloudDialogflowV2BatchUpdateIntentsRequest struct {
	// IntentBatchInline: The collection of intents to update or create.
	IntentBatchInline *GoogleCloudDialogflowV2IntentBatch `json:"intentBatchInline,omitempty"`

	// IntentBatchUri: The URI to a Google Cloud Storage file containing
	// intents to update or
	// create. The file format can either be a serialized proto (of
	// IntentBatch
	// type) or JSON object. Note: The URI must start with "gs://".
	IntentBatchUri string `json:"intentBatchUri,omitempty"`

	// IntentView: Optional. The resource view to apply to the returned
	// intent.
	//
	// Possible values:
	//   "INTENT_VIEW_UNSPECIFIED" - Training phrases field is not populated
	// in the response.
	//   "INTENT_VIEW_FULL" - All fields are populated.
	IntentView string `json:"intentView,omitempty"`

	// LanguageCode: Optional. The language of training phrases, parameters
	// and rich messages
	// defined in `intents`. If not specified, the agent's default language
	// is
	// used.
	// [Many
	// languages](https://cloud.google.com/dialogflow/docs/reference/la
	// nguage)
	// are supported. Note: languages must be enabled in the agent before
	// they can
	// be used.
	LanguageCode string `json:"languageCode,omitempty"`

	// UpdateMask: Optional. The mask to control which fields get updated.
	UpdateMask string `json:"updateMask,omitempty"`

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

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

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

// GoogleCloudDialogflowV2BatchUpdateIntentsResponse: The response
// message for Intents.BatchUpdateIntents.
type GoogleCloudDialogflowV2BatchUpdateIntentsResponse struct {
	// Intents: The collection of updated or created intents.
	Intents []*GoogleCloudDialogflowV2Intent `json:"intents,omitempty"`

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

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

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

// GoogleCloudDialogflowV2Context: Represents a context.
type GoogleCloudDialogflowV2Context struct {
	// LifespanCount: Optional. The number of conversational query requests
	// after which the
	// context expires. If set to `0` (the default) the context
	// expires
	// immediately. Contexts expire automatically after 20 minutes if
	// there
	// are no matching queries.
	LifespanCount int64 `json:"lifespanCount,omitempty"`

	// Name: Required. The unique identifier of the context.
	// Format:
	// `projects/<Project ID>/agent/sessions/<Session ID>/contexts/<Context
	// ID>`,
	// or `projects/<Project ID>/agent/environments/<Environment
	// ID>/users/<User
	// ID>/sessions/<Session ID>/contexts/<Context ID>`.
	//
	// The `Context ID` is always converted to lowercase, may only
	// contain
	// characters in a-zA-Z0-9_-% and may be at most 250 bytes long.
	//
	// If `Environment ID` is not specified, we assume default
	// 'draft'
	// environment. If `User ID` is not specified, we assume default '-'
	// user.
	//
	// The following context names are reserved for internal use by
	// Dialogflow.
	// You should not use these contexts or create contexts with these
	// names:
	//
	// * `__system_counters__`
	// * `*_id_dialog_context`
	// * `*_dialog_params_size`
	Name string `json:"name,omitempty"`

	// Parameters: Optional. The collection of parameters associated with
	// this context.
	// Refer to
	// [this
	// doc](https://cloud.google.com/dialogflow/docs/intents-actions-pa
	// rameters)
	// for syntax.
	Parameters googleapi.RawMessage `json:"parameters,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2ConversationEvent: Represents a notification
// sent to Cloud Pub/Sub subscribers for conversation
// lifecycle events.
type GoogleCloudDialogflowV2ConversationEvent struct {
	// Conversation: The unique identifier of the conversation this
	// notification
	// refers to.
	// Format: `projects/<Project ID>/conversations/<Conversation ID>`.
	Conversation string `json:"conversation,omitempty"`

	// ErrorStatus: More detailed information about an error. Only set for
	// type
	// UNRECOVERABLE_ERROR_IN_PHONE_CALL.
	ErrorStatus *GoogleRpcStatus `json:"errorStatus,omitempty"`

	// NewMessagePayload: Payload of NEW_MESSAGE event.
	NewMessagePayload *GoogleCloudDialogflowV2Message `json:"newMessagePayload,omitempty"`

	// Type: The type of the event that this notification refers to.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Type not set.
	//   "CONVERSATION_STARTED" - A new conversation has been opened. This
	// is fired when a telephone call
	// is answered, or a conversation is created via the API.
	//   "CONVERSATION_FINISHED" - An existing conversation has closed. This
	// is fired when a telephone call
	// is terminated, or a conversation is closed via the API.
	//   "HUMAN_INTERVENTION_NEEDED" - An existing conversation has received
	// notification from Dialogflow that
	// human intervention is required.
	//   "NEW_MESSAGE" - An existing conversation has received a new
	// message, either from API or
	// telephony. It is configured
	// in
	// ConversationProfile.new_message_event_notification_config
	//   "UNRECOVERABLE_ERROR" - Unrecoverable error during a telephone
	// call.
	//
	// In general non-recoverable errors only occur if something
	// was
	// misconfigured in the ConversationProfile corresponding to the call.
	// After
	// a non-recoverable error, Dialogflow may stop responding.
	//
	// We don't fire this event:
	// * in an API call because we can directly return the error, or,
	// * when we can recover from an error.
	Type string `json:"type,omitempty"`

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

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

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

// GoogleCloudDialogflowV2DetectIntentRequest:
// ======================================================================
// ======
// Requests and responses for custom methods.
// The request to detect user's intent.
type GoogleCloudDialogflowV2DetectIntentRequest struct {
	// InputAudio: The natural language speech audio to be processed. This
	// field
	// should be populated iff `query_input` is set to an input audio
	// config.
	// A single request can contain up to 1 minute of speech audio data.
	InputAudio string `json:"inputAudio,omitempty"`

	// OutputAudioConfig: Instructs the speech synthesizer how to generate
	// the output
	// audio. If this field is not set and agent-level speech synthesizer is
	// not
	// configured, no output audio is generated.
	OutputAudioConfig *GoogleCloudDialogflowV2OutputAudioConfig `json:"outputAudioConfig,omitempty"`

	// OutputAudioConfigMask: Mask for output_audio_config indicating which
	// settings in this
	// request-level config should override speech synthesizer settings
	// defined at
	// agent-level.
	//
	// If unspecified or empty, output_audio_config replaces the
	// agent-level
	// config in its entirety.
	OutputAudioConfigMask string `json:"outputAudioConfigMask,omitempty"`

	// QueryInput: Required. The input specification. It can be set to:
	//
	// 1.  an audio config
	//     which instructs the speech recognizer how to process the speech
	// audio,
	//
	// 2.  a conversational query in the form of text, or
	//
	// 3.  an event that specifies which intent to trigger.
	QueryInput *GoogleCloudDialogflowV2QueryInput `json:"queryInput,omitempty"`

	// QueryParams: The parameters of this query.
	QueryParams *GoogleCloudDialogflowV2QueryParameters `json:"queryParams,omitempty"`

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

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

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

// GoogleCloudDialogflowV2DetectIntentResponse: The message returned
// from the DetectIntent method.
type GoogleCloudDialogflowV2DetectIntentResponse struct {
	// OutputAudio: The audio data bytes encoded as specified in the
	// request.
	// Note: The output audio is generated based on the values of default
	// platform
	// text responses found in the `query_result.fulfillment_messages`
	// field. If
	// multiple default text responses exist, they will be concatenated
	// when
	// generating audio. If no default platform text responses exist,
	// the
	// generated audio content will be empty.
	OutputAudio string `json:"outputAudio,omitempty"`

	// OutputAudioConfig: The config used by the speech synthesizer to
	// generate the output audio.
	OutputAudioConfig *GoogleCloudDialogflowV2OutputAudioConfig `json:"outputAudioConfig,omitempty"`

	// QueryResult: The selected results of the conversational query or
	// event processing.
	// See `alternative_query_results` for additional potential results.
	QueryResult *GoogleCloudDialogflowV2QueryResult `json:"queryResult,omitempty"`

	// ResponseId: The unique identifier of the response. It can be used
	// to
	// locate a response in the training example set or for reporting
	// issues.
	ResponseId string `json:"responseId,omitempty"`

	// WebhookStatus: Specifies the status of the webhook request.
	WebhookStatus *GoogleRpcStatus `json:"webhookStatus,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2EntityType: Represents an entity type.
// Entity types serve as a tool for extracting parameter values from
// natural
// language queries.
type GoogleCloudDialogflowV2EntityType struct {
	// AutoExpansionMode: Optional. Indicates whether the entity type can be
	// automatically
	// expanded.
	//
	// Possible values:
	//   "AUTO_EXPANSION_MODE_UNSPECIFIED" - Auto expansion disabled for the
	// entity.
	//   "AUTO_EXPANSION_MODE_DEFAULT" - Allows an agent to recognize values
	// that have not been explicitly
	// listed in the entity.
	AutoExpansionMode string `json:"autoExpansionMode,omitempty"`

	// DisplayName: Required. The name of the entity type.
	DisplayName string `json:"displayName,omitempty"`

	// EnableFuzzyExtraction: Optional. Enables fuzzy entity extraction
	// during classification.
	EnableFuzzyExtraction bool `json:"enableFuzzyExtraction,omitempty"`

	// Entities: Optional. The collection of entity entries associated with
	// the entity type.
	Entities []*GoogleCloudDialogflowV2EntityTypeEntity `json:"entities,omitempty"`

	// Kind: Required. Indicates the kind of entity type.
	//
	// Possible values:
	//   "KIND_UNSPECIFIED" - Not specified. This value should be never
	// used.
	//   "KIND_MAP" - Map entity types allow mapping of a group of synonyms
	// to a reference
	// value.
	//   "KIND_LIST" - List entity types contain a set of entries that do
	// not map to reference
	// values. However, list entity types can contain references to other
	// entity
	// types (with or without aliases).
	//   "KIND_REGEXP" - Regexp entity types allow to specify regular
	// expressions in entries
	// values.
	Kind string `json:"kind,omitempty"`

	// Name: The unique identifier of the entity type.
	// Required for EntityTypes.UpdateEntityType
	// and
	// EntityTypes.BatchUpdateEntityTypes methods.
	// Format: `projects/<Project ID>/agent/entityTypes/<Entity Type ID>`.
	Name string `json:"name,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2EntityTypeBatch: This message is a wrapper
// around a collection of entity types.
type GoogleCloudDialogflowV2EntityTypeBatch struct {
	// EntityTypes: A collection of entity types.
	EntityTypes []*GoogleCloudDialogflowV2EntityType `json:"entityTypes,omitempty"`

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

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

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

// GoogleCloudDialogflowV2EntityTypeEntity: An **entity entry** for an
// associated entity type.
type GoogleCloudDialogflowV2EntityTypeEntity struct {
	// Synonyms: Required. A collection of value synonyms. For example, if
	// the entity type
	// is *vegetable*, and `value` is *scallions*, a synonym could be
	// *green
	// onions*.
	//
	// For `KIND_LIST` entity types:
	//
	// *   This collection must contain exactly one synonym equal to
	// `value`.
	Synonyms []string `json:"synonyms,omitempty"`

	// Value: Required. The primary value associated with this entity
	// entry.
	// For example, if the entity type is *vegetable*, the value could
	// be
	// *scallions*.
	//
	// For `KIND_MAP` entity types:
	//
	// *   A reference value to be used in place of synonyms.
	//
	// For `KIND_LIST` entity types:
	//
	// *   A string that can contain references to other entity types (with
	// or
	//     without aliases).
	Value string `json:"value,omitempty"`

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

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

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

// GoogleCloudDialogflowV2EventInput: Events allow for matching intents
// by event name instead of the natural
// language input. For instance, input `<event: { name:
// "welcome_event",
// parameters: { name: "Sam" } }>` can trigger a personalized welcome
// response.
// The parameter `name` may be used by the agent in the
// response:
// "Hello #welcome_event.name! What can I do for you today?".
type GoogleCloudDialogflowV2EventInput struct {
	// LanguageCode: Required. The language of this query. See
	// [Language
	// Support](https://cloud.google.com/dialogflow/docs/reference/
	// language)
	// for a list of the currently supported language codes. Note that
	// queries in
	// the same session do not necessarily need to specify the same
	// language.
	LanguageCode string `json:"languageCode,omitempty"`

	// Name: Required. The unique identifier of the event.
	Name string `json:"name,omitempty"`

	// Parameters: The collection of parameters associated with the event.
	Parameters googleapi.RawMessage `json:"parameters,omitempty"`

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

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

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

// GoogleCloudDialogflowV2ExportAgentRequest: The request message for
// Agents.ExportAgent.
type GoogleCloudDialogflowV2ExportAgentRequest struct {
	// AgentUri: Required. The [Google Cloud
	// Storage](https://cloud.google.com/storage/docs/)
	// URI to export the agent to.
	// The format of this URI must be `gs://<bucket-name>/<object-name>`.
	// If left unspecified, the serialized agent is returned inline.
	AgentUri string `json:"agentUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2ExportAgentResponse: The response message for
// Agents.ExportAgent.
type GoogleCloudDialogflowV2ExportAgentResponse struct {
	// AgentContent: Zip compressed raw byte content for agent.
	AgentContent string `json:"agentContent,omitempty"`

	// AgentUri: The URI to a file containing the exported agent. This field
	// is populated
	// only if `agent_uri` is specified in `ExportAgentRequest`.
	AgentUri string `json:"agentUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2Fulfillment: Represents a fulfillment.
type GoogleCloudDialogflowV2Fulfillment struct {
	// DisplayName: Optional. The human-readable name of the fulfillment,
	// unique within the agent.
	DisplayName string `json:"displayName,omitempty"`

	// Enabled: Optional. Whether fulfillment is enabled.
	Enabled bool `json:"enabled,omitempty"`

	// Features: Optional. The field defines whether the fulfillment is
	// enabled for certain features.
	Features []*GoogleCloudDialogflowV2FulfillmentFeature `json:"features,omitempty"`

	// GenericWebService: Configuration for a generic web service.
	GenericWebService *GoogleCloudDialogflowV2FulfillmentGenericWebService `json:"genericWebService,omitempty"`

	// Name: Required. The unique identifier of the fulfillment.
	// Format: `projects/<Project ID>/agent/fulfillment`.
	Name string `json:"name,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2FulfillmentFeature: Whether fulfillment is
// enabled for the specific feature.
type GoogleCloudDialogflowV2FulfillmentFeature struct {
	// Type: The type of the feature that enabled for fulfillment.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Feature type not specified.
	//   "SMALLTALK" - Fulfillment is enabled for SmallTalk.
	Type string `json:"type,omitempty"`

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

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

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

// GoogleCloudDialogflowV2FulfillmentGenericWebService: Represents
// configuration for a generic web service.
// Dialogflow supports two mechanisms for authentications:
// - Basic authentication with username and password.
// - Authentication with additional authentication headers.
// More information could be found
// at:
// https://cloud.google.com/dialogflow/docs/fulfillment-configure.
type GoogleCloudDialogflowV2FulfillmentGenericWebService struct {
	// IsCloudFunction: Optional. Indicates if generic web service is
	// created through Cloud Functions
	// integration. Defaults to false.
	IsCloudFunction bool `json:"isCloudFunction,omitempty"`

	// Password: Optional. The password for HTTP Basic authentication.
	Password string `json:"password,omitempty"`

	// RequestHeaders: Optional. The HTTP request headers to send together
	// with fulfillment requests.
	RequestHeaders map[string]string `json:"requestHeaders,omitempty"`

	// Uri: Required. The fulfillment URI for receiving POST requests.
	Uri string `json:"uri,omitempty"`

	// Username: Optional. The user name for HTTP Basic authentication.
	Username string `json:"username,omitempty"`

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

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

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

// GoogleCloudDialogflowV2ImportAgentRequest: The request message for
// Agents.ImportAgent.
type GoogleCloudDialogflowV2ImportAgentRequest struct {
	// AgentContent: Zip compressed raw byte content for agent.
	AgentContent string `json:"agentContent,omitempty"`

	// AgentUri: The URI to a Google Cloud Storage file containing the agent
	// to import.
	// Note: The URI must start with "gs://".
	AgentUri string `json:"agentUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2InputAudioConfig: Instructs the speech
// recognizer how to process the audio content.
type GoogleCloudDialogflowV2InputAudioConfig struct {
	// AudioEncoding: Required. Audio encoding of the audio content to
	// process.
	//
	// Possible values:
	//   "AUDIO_ENCODING_UNSPECIFIED" - Not specified.
	//   "AUDIO_ENCODING_LINEAR_16" - Uncompressed 16-bit signed
	// little-endian samples (Linear PCM).
	//   "AUDIO_ENCODING_FLAC" -
	// [`FLAC`](https://xiph.org/flac/documentation.html) (Free Lossless
	// Audio
	// Codec) is the recommended encoding because it is lossless
	// (therefore
	// recognition is not compromised) and requires only about half
	// the
	// bandwidth of `LINEAR16`. `FLAC` stream encoding supports 16-bit
	// and
	// 24-bit samples, however, not all fields in `STREAMINFO` are
	// supported.
	//   "AUDIO_ENCODING_MULAW" - 8-bit samples that compand 14-bit audio
	// samples using G.711 PCMU/mu-law.
	//   "AUDIO_ENCODING_AMR" - Adaptive Multi-Rate Narrowband codec.
	// `sample_rate_hertz` must be 8000.
	//   "AUDIO_ENCODING_AMR_WB" - Adaptive Multi-Rate Wideband codec.
	// `sample_rate_hertz` must be 16000.
	//   "AUDIO_ENCODING_OGG_OPUS" - Opus encoded audio frames in Ogg
	// container
	// ([OggOpus](https://wiki.xiph.org/OggOpus)).
	// `sample_rate_her
	// tz` must be 16000.
	//   "AUDIO_ENCODING_SPEEX_WITH_HEADER_BYTE" - Although the use of lossy
	// encodings is not recommended, if a very low
	// bitrate encoding is required, `OGG_OPUS` is highly preferred
	// over
	// Speex encoding. The [Speex](https://speex.org/) encoding supported
	// by
	// Dialogflow API has a header byte in each block, as in MIME
	// type
	// `audio/x-speex-with-header-byte`.
	// It is a variant of the RTP Speex encoding defined in
	// [RFC 5574](https://tools.ietf.org/html/rfc5574).
	// The stream is a sequence of blocks, one block per RTP packet. Each
	// block
	// starts with a byte containing the length of the block, in bytes,
	// followed
	// by one or more frames of Speex data, padded to an integral number
	// of
	// bytes (octets) as specified in RFC 5574. In other words, each RTP
	// header
	// is replaced with a single byte containing the block length. Only
	// Speex
	// wideband is supported. `sample_rate_hertz` must be 16000.
	AudioEncoding string `json:"audioEncoding,omitempty"`

	// EnableWordInfo: Optional. If `true`, Dialogflow returns
	// SpeechWordInfo in
	// StreamingRecognitionResult with information about the recognized
	// speech
	// words, e.g. start and end time offsets. If false or unspecified,
	// Speech
	// doesn't return any word-level information.
	EnableWordInfo bool `json:"enableWordInfo,omitempty"`

	// LanguageCode: Required. The language of the supplied audio.
	// Dialogflow does not do
	// translations. See
	// [Language
	// Support](https://cloud.google.com/dialogflow/docs/reference/
	// language)
	// for a list of the currently supported language codes. Note that
	// queries in
	// the same session do not necessarily need to specify the same
	// language.
	LanguageCode string `json:"languageCode,omitempty"`

	// Model: Optional. Which Speech model to select for the given request.
	// Select the
	// model best suited to your domain to get best results. If a model is
	// not
	// explicitly specified, then we auto-select a model based on the
	// parameters
	// in the InputAudioConfig.
	// If enhanced speech model is enabled for the agent and an
	// enhanced
	// version of the specified model for the language does not exist, then
	// the
	// speech is recognized using the standard version of the specified
	// model.
	// Refer to
	// [Cloud Speech
	// API
	// documentation](https://cloud.google.com/speech-to-text/docs/basics
	// #select-model)
	// for more details.
	Model string `json:"model,omitempty"`

	// ModelVariant: Optional. Which variant of the Speech model to use.
	//
	// Possible values:
	//   "SPEECH_MODEL_VARIANT_UNSPECIFIED" - No model variant specified. In
	// this case Dialogflow defaults to
	// USE_BEST_AVAILABLE.
	//   "USE_BEST_AVAILABLE" - Use the best available variant of the
	// Speech
	// model that the caller is eligible for.
	//
	// Please see the
	// [Dialogflow
	// docs](https://cloud.google.com/dialogflow/docs/data-loggin
	// g) for
	// how to make your project eligible for enhanced models.
	//   "USE_STANDARD" - Use standard model variant even if an enhanced
	// model is available.  See the
	// [Cloud
	// Speech
	// documentation](https://cloud.google.com/speech-to-text/docs/enh
	// anced-models)
	// for details about enhanced models.
	//   "USE_ENHANCED" - Use an enhanced model variant:
	//
	// * If an enhanced variant does not exist for the given
	//   model and request language, Dialogflow falls
	//   back to the standard variant.
	//
	//   The [Cloud Speech
	//
	// documentation](https://cloud.google.com/speech-to-text/docs/enhanced-m
	// odels)
	//   describes which models have enhanced variants.
	//
	// * If the API caller isn't eligible for enhanced models, Dialogflow
	// returns
	//   an error. Please see the [Dialogflow
	//   docs](https://cloud.google.com/dialogflow/docs/data-logging)
	//   for how to make your project eligible.
	ModelVariant string `json:"modelVariant,omitempty"`

	// PhraseHints: Optional. A list of strings containing words and phrases
	// that the speech
	// recognizer should recognize with higher likelihood.
	//
	// See [the Cloud
	// Speech
	// documentation](https://cloud.google.com/speech-to-text/docs/bas
	// ics#phrase-hints)
	// for more details.
	//
	// This field is deprecated. Please use [speech_contexts]() instead. If
	// you
	// specify both [phrase_hints]() and [speech_contexts](), Dialogflow
	// will
	// treat the [phrase_hints]() as a single additional [SpeechContext]().
	PhraseHints []string `json:"phraseHints,omitempty"`

	// SampleRateHertz: Required. Sample rate (in Hertz) of the audio
	// content sent in the query.
	// Refer to
	// [Cloud Speech
	// API
	// documentation](https://cloud.google.com/speech-to-text/docs/basics
	// ) for
	// more details.
	SampleRateHertz int64 `json:"sampleRateHertz,omitempty"`

	// SingleUtterance: Optional. If `false` (default), recognition does not
	// cease until the
	// client closes the stream.
	// If `true`, the recognizer will detect a single spoken utterance in
	// input
	// audio. Recognition ceases when it detects the audio's voice
	// has
	// stopped or paused. In this case, once a detected intent is received,
	// the
	// client should close the stream and start a new request with a new
	// stream as
	// needed.
	// Note: This setting is relevant only for streaming methods.
	// Note: When specified, InputAudioConfig.single_utterance takes
	// precedence
	// over StreamingDetectIntentRequest.single_utterance.
	SingleUtterance bool `json:"singleUtterance,omitempty"`

	// SpeechContexts: Optional. Context information to assist speech
	// recognition.
	//
	// See [the Cloud
	// Speech
	// documentation](https://cloud.google.com/speech-to-text/docs/bas
	// ics#phrase-hints)
	// for more details.
	SpeechContexts []*GoogleCloudDialogflowV2SpeechContext `json:"speechContexts,omitempty"`

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

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

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

// GoogleCloudDialogflowV2Intent: Represents an intent.
// Intents convert a number of user expressions or patterns into an
// action. An
// action is an extraction of a user command or sentence semantics.
type GoogleCloudDialogflowV2Intent struct {
	// Action: Optional. The name of the action associated with the
	// intent.
	// Note: The action name must not contain whitespaces.
	Action string `json:"action,omitempty"`

	// DefaultResponsePlatforms: Optional. The list of platforms for which
	// the first responses will be
	// copied from the messages in PLATFORM_UNSPECIFIED (i.e. default
	// platform).
	//
	// Possible values:
	//   "PLATFORM_UNSPECIFIED" - Not specified.
	//   "FACEBOOK" - Facebook.
	//   "SLACK" - Slack.
	//   "TELEGRAM" - Telegram.
	//   "KIK" - Kik.
	//   "SKYPE" - Skype.
	//   "LINE" - Line.
	//   "VIBER" - Viber.
	//   "ACTIONS_ON_GOOGLE" - Actions on Google.
	// When using Actions on Google, you can choose one of the
	// specific
	// Intent.Message types that mention support for Actions on Google,
	// or you can use the advanced Intent.Message.payload field.
	// The payload field provides access to AoG features not available in
	// the
	// specific message types.
	// If using the Intent.Message.payload field, it should have a
	// structure
	// similar to the JSON message shown here. For more information,
	// see
	// [Actions on Google
	// Webhook
	// Format](https://developers.google.com/actions/dialogflow/webho
	// ok)
	// <pre>{
	//   "expectUserResponse": true,
	//   "isSsml": false,
	//   "noInputPrompts": [],
	//   "richResponse": {
	//     "items": [
	//       {
	//         "simpleResponse": {
	//           "displayText": "hi",
	//           "textToSpeech": "hello"
	//         }
	//       }
	//     ],
	//     "suggestions": [
	//       {
	//         "title": "Say this"
	//       },
	//       {
	//         "title": "or this"
	//       }
	//     ]
	//   },
	//   "systemIntent": {
	//     "data": {
	//       "@type":
	// "type.googleapis.com/google.actions.v2.OptionValueSpec",
	//       "listSelect": {
	//         "items": [
	//           {
	//             "optionInfo": {
	//               "key": "key1",
	//               "synonyms": [
	//                 "key one"
	//               ]
	//             },
	//             "title": "must not be empty, but unique"
	//           },
	//           {
	//             "optionInfo": {
	//               "key": "key2",
	//               "synonyms": [
	//                 "key two"
	//               ]
	//             },
	//             "title": "must not be empty, but unique"
	//           }
	//         ]
	//       }
	//     },
	//     "intent": "actions.intent.OPTION"
	//   }
	// }</pre>
	//   "GOOGLE_HANGOUTS" - Google Hangouts.
	DefaultResponsePlatforms []string `json:"defaultResponsePlatforms,omitempty"`

	// DisplayName: Required. The name of this intent.
	DisplayName string `json:"displayName,omitempty"`

	// Events: Optional. The collection of event names that trigger the
	// intent.
	// If the collection of input contexts is not empty, all of the contexts
	// must
	// be present in the active user session for an event to trigger this
	// intent.
	Events []string `json:"events,omitempty"`

	// FollowupIntentInfo: Read-only. Information about all followup intents
	// that have this intent as
	// a direct or indirect parent. We populate this field only in the
	// output.
	FollowupIntentInfo []*GoogleCloudDialogflowV2IntentFollowupIntentInfo `json:"followupIntentInfo,omitempty"`

	// InputContextNames: Optional. The list of context names required for
	// this intent to be
	// triggered.
	// Format: `projects/<Project ID>/agent/sessions/-/contexts/<Context
	// ID>`.
	InputContextNames []string `json:"inputContextNames,omitempty"`

	// IsFallback: Optional. Indicates whether this is a fallback intent.
	IsFallback bool `json:"isFallback,omitempty"`

	// Messages: Optional. The collection of rich messages corresponding to
	// the
	// `Response` field in the Dialogflow console.
	Messages []*GoogleCloudDialogflowV2IntentMessage `json:"messages,omitempty"`

	// MlDisabled: Optional. Indicates whether Machine Learning is disabled
	// for the intent.
	// Note: If `ml_disabled` setting is set to true, then this intent is
	// not
	// taken into account during inference in `ML ONLY` match mode.
	// Also,
	// auto-markup in the UI is turned off.
	MlDisabled bool `json:"mlDisabled,omitempty"`

	// Name: The unique identifier of this intent.
	// Required for Intents.UpdateIntent and
	// Intents.BatchUpdateIntents
	// methods.
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	Name string `json:"name,omitempty"`

	// OutputContexts: Optional. The collection of contexts that are
	// activated when the intent
	// is matched. Context messages in this collection should not set
	// the
	// parameters field. Setting the `lifespan_count` to 0 will reset the
	// context
	// when the intent is matched.
	// Format: `projects/<Project ID>/agent/sessions/-/contexts/<Context
	// ID>`.
	OutputContexts []*GoogleCloudDialogflowV2Context `json:"outputContexts,omitempty"`

	// Parameters: Optional. The collection of parameters associated with
	// the intent.
	Parameters []*GoogleCloudDialogflowV2IntentParameter `json:"parameters,omitempty"`

	// ParentFollowupIntentName: Read-only after creation. The unique
	// identifier of the parent intent in the
	// chain of followup intents. You can set this field when creating an
	// intent,
	// for example with CreateIntent or
	// BatchUpdateIntents, in order to make this
	// intent a followup intent.
	//
	// It identifies the parent followup intent.
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	ParentFollowupIntentName string `json:"parentFollowupIntentName,omitempty"`

	// Priority: Optional. The priority of this intent. Higher numbers
	// represent higher
	// priorities.
	//
	// - If the supplied value is unspecified or 0, the service
	//   translates the value to 500,000, which corresponds to the
	//   `Normal` priority in the console.
	// - If the supplied value is negative, the intent is ignored
	//   in runtime detect intent requests.
	Priority int64 `json:"priority,omitempty"`

	// ResetContexts: Optional. Indicates whether to delete all contexts in
	// the current
	// session when this intent is matched.
	ResetContexts bool `json:"resetContexts,omitempty"`

	// RootFollowupIntentName: Read-only. The unique identifier of the root
	// intent in the chain of
	// followup intents. It identifies the correct followup intents chain
	// for
	// this intent. We populate this field only in the output.
	//
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	RootFollowupIntentName string `json:"rootFollowupIntentName,omitempty"`

	// TrainingPhrases: Optional. The collection of examples that the agent
	// is
	// trained on.
	TrainingPhrases []*GoogleCloudDialogflowV2IntentTrainingPhrase `json:"trainingPhrases,omitempty"`

	// WebhookState: Optional. Indicates whether webhooks are enabled for
	// the intent.
	//
	// Possible values:
	//   "WEBHOOK_STATE_UNSPECIFIED" - Webhook is disabled in the agent and
	// in the intent.
	//   "WEBHOOK_STATE_ENABLED" - Webhook is enabled in the agent and in
	// the intent.
	//   "WEBHOOK_STATE_ENABLED_FOR_SLOT_FILLING" - Webhook is enabled in
	// the agent and in the intent. Also, each slot
	// filling prompt is forwarded to the webhook.
	WebhookState string `json:"webhookState,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2IntentBatch: This message is a wrapper around
// a collection of intents.
type GoogleCloudDialogflowV2IntentBatch struct {
	// Intents: A collection of intents.
	Intents []*GoogleCloudDialogflowV2Intent `json:"intents,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentFollowupIntentInfo: Represents a single
// followup intent in the chain.
type GoogleCloudDialogflowV2IntentFollowupIntentInfo struct {
	// FollowupIntentName: The unique identifier of the followup
	// intent.
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	FollowupIntentName string `json:"followupIntentName,omitempty"`

	// ParentFollowupIntentName: The unique identifier of the followup
	// intent's parent.
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	ParentFollowupIntentName string `json:"parentFollowupIntentName,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessage: Corresponds to the `Response`
// field in the Dialogflow console.
type GoogleCloudDialogflowV2IntentMessage struct {
	// BasicCard: The basic card response for Actions on Google.
	BasicCard *GoogleCloudDialogflowV2IntentMessageBasicCard `json:"basicCard,omitempty"`

	// BrowseCarouselCard: Browse carousel card for Actions on Google.
	BrowseCarouselCard *GoogleCloudDialogflowV2IntentMessageBrowseCarouselCard `json:"browseCarouselCard,omitempty"`

	// Card: The card response.
	Card *GoogleCloudDialogflowV2IntentMessageCard `json:"card,omitempty"`

	// CarouselSelect: The carousel card response for Actions on Google.
	CarouselSelect *GoogleCloudDialogflowV2IntentMessageCarouselSelect `json:"carouselSelect,omitempty"`

	// Image: The image response.
	Image *GoogleCloudDialogflowV2IntentMessageImage `json:"image,omitempty"`

	// LinkOutSuggestion: The link out suggestion chip for Actions on
	// Google.
	LinkOutSuggestion *GoogleCloudDialogflowV2IntentMessageLinkOutSuggestion `json:"linkOutSuggestion,omitempty"`

	// ListSelect: The list card response for Actions on Google.
	ListSelect *GoogleCloudDialogflowV2IntentMessageListSelect `json:"listSelect,omitempty"`

	// MediaContent: The media content card for Actions on Google.
	MediaContent *GoogleCloudDialogflowV2IntentMessageMediaContent `json:"mediaContent,omitempty"`

	// Payload: Returns a response containing a custom, platform-specific
	// payload.
	// See the Intent.Message.Platform type for a description of
	// the
	// structure that may be required for your platform.
	Payload googleapi.RawMessage `json:"payload,omitempty"`

	// Platform: Optional. The platform that this message is intended for.
	//
	// Possible values:
	//   "PLATFORM_UNSPECIFIED" - Not specified.
	//   "FACEBOOK" - Facebook.
	//   "SLACK" - Slack.
	//   "TELEGRAM" - Telegram.
	//   "KIK" - Kik.
	//   "SKYPE" - Skype.
	//   "LINE" - Line.
	//   "VIBER" - Viber.
	//   "ACTIONS_ON_GOOGLE" - Actions on Google.
	// When using Actions on Google, you can choose one of the
	// specific
	// Intent.Message types that mention support for Actions on Google,
	// or you can use the advanced Intent.Message.payload field.
	// The payload field provides access to AoG features not available in
	// the
	// specific message types.
	// If using the Intent.Message.payload field, it should have a
	// structure
	// similar to the JSON message shown here. For more information,
	// see
	// [Actions on Google
	// Webhook
	// Format](https://developers.google.com/actions/dialogflow/webho
	// ok)
	// <pre>{
	//   "expectUserResponse": true,
	//   "isSsml": false,
	//   "noInputPrompts": [],
	//   "richResponse": {
	//     "items": [
	//       {
	//         "simpleResponse": {
	//           "displayText": "hi",
	//           "textToSpeech": "hello"
	//         }
	//       }
	//     ],
	//     "suggestions": [
	//       {
	//         "title": "Say this"
	//       },
	//       {
	//         "title": "or this"
	//       }
	//     ]
	//   },
	//   "systemIntent": {
	//     "data": {
	//       "@type":
	// "type.googleapis.com/google.actions.v2.OptionValueSpec",
	//       "listSelect": {
	//         "items": [
	//           {
	//             "optionInfo": {
	//               "key": "key1",
	//               "synonyms": [
	//                 "key one"
	//               ]
	//             },
	//             "title": "must not be empty, but unique"
	//           },
	//           {
	//             "optionInfo": {
	//               "key": "key2",
	//               "synonyms": [
	//                 "key two"
	//               ]
	//             },
	//             "title": "must not be empty, but unique"
	//           }
	//         ]
	//       }
	//     },
	//     "intent": "actions.intent.OPTION"
	//   }
	// }</pre>
	//   "GOOGLE_HANGOUTS" - Google Hangouts.
	Platform string `json:"platform,omitempty"`

	// QuickReplies: The quick replies response.
	QuickReplies *GoogleCloudDialogflowV2IntentMessageQuickReplies `json:"quickReplies,omitempty"`

	// SimpleResponses: The voice and text-only responses for Actions on
	// Google.
	SimpleResponses *GoogleCloudDialogflowV2IntentMessageSimpleResponses `json:"simpleResponses,omitempty"`

	// Suggestions: The suggestion chips for Actions on Google.
	Suggestions *GoogleCloudDialogflowV2IntentMessageSuggestions `json:"suggestions,omitempty"`

	// TableCard: Table card for Actions on Google.
	TableCard *GoogleCloudDialogflowV2IntentMessageTableCard `json:"tableCard,omitempty"`

	// Text: The text response.
	Text *GoogleCloudDialogflowV2IntentMessageText `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageBasicCard: The basic card
// message. Useful for displaying information.
type GoogleCloudDialogflowV2IntentMessageBasicCard struct {
	// Buttons: Optional. The collection of card buttons.
	Buttons []*GoogleCloudDialogflowV2IntentMessageBasicCardButton `json:"buttons,omitempty"`

	// FormattedText: Required, unless image is present. The body text of
	// the card.
	FormattedText string `json:"formattedText,omitempty"`

	// Image: Optional. The image for the card.
	Image *GoogleCloudDialogflowV2IntentMessageImage `json:"image,omitempty"`

	// Subtitle: Optional. The subtitle of the card.
	Subtitle string `json:"subtitle,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2IntentMessageBasicCardButton: The button
// object that appears at the bottom of a card.
type GoogleCloudDialogflowV2IntentMessageBasicCardButton struct {
	// OpenUriAction: Required. Action to take when a user taps on the
	// button.
	OpenUriAction *GoogleCloudDialogflowV2IntentMessageBasicCardButtonOpenUriAction `json:"openUriAction,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2IntentMessageBasicCardButtonOpenUriAction:
// Opens the given URI.
type GoogleCloudDialogflowV2IntentMessageBasicCardButtonOpenUriAction struct {
	// Uri: Required. The HTTP or HTTPS scheme URI.
	Uri string `json:"uri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageBrowseCarouselCard: Browse
// Carousel Card for Actions on
// Google.
// https://developers.google.com/actions/assistant/responses#brow
// sing_carousel
type GoogleCloudDialogflowV2IntentMessageBrowseCarouselCard struct {
	// ImageDisplayOptions: Optional. Settings for displaying the image.
	// Applies to every image in
	// items.
	//
	// Possible values:
	//   "IMAGE_DISPLAY_OPTIONS_UNSPECIFIED" - Fill the gaps between the
	// image and the image container with gray
	// bars.
	//   "GRAY" - Fill the gaps between the image and the image container
	// with gray
	// bars.
	//   "WHITE" - Fill the gaps between the image and the image container
	// with white
	// bars.
	//   "CROPPED" - Image is scaled such that the image width and height
	// match or exceed
	// the container dimensions. This may crop the top and bottom of
	// the
	// image if the scaled image height is greater than the
	// container
	// height, or crop the left and right of the image if the scaled
	// image
	// width is greater than the container width. This is similar to
	// "Zoom
	// Mode" on a widescreen TV when playing a 4:3 video.
	//   "BLURRED_BACKGROUND" - Pad the gaps between image and image frame
	// with a blurred copy of the
	// same image.
	ImageDisplayOptions string `json:"imageDisplayOptions,omitempty"`

	// Items: Required. List of items in the Browse Carousel Card. Minimum
	// of two
	// items, maximum of ten.
	Items []*GoogleCloudDialogflowV2IntentMessageBrowseCarouselCardBrowseCarouselCardItem `json:"items,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageBrowseCarouselCardBrowseCarouselCa
// rdItem: Browsing carousel tile
type GoogleCloudDialogflowV2IntentMessageBrowseCarouselCardBrowseCarouselCardItem struct {
	// Description: Optional. Description of the carousel item. Maximum of
	// four lines of
	// text.
	Description string `json:"description,omitempty"`

	// Footer: Optional. Text that appears at the bottom of the Browse
	// Carousel
	// Card. Maximum of one line of text.
	Footer string `json:"footer,omitempty"`

	// Image: Optional. Hero image for the carousel item.
	Image *GoogleCloudDialogflowV2IntentMessageImage `json:"image,omitempty"`

	// OpenUriAction: Required. Action to present to the user.
	OpenUriAction *GoogleCloudDialogflowV2IntentMessageBrowseCarouselCardBrowseCarouselCardItemOpenUrlAction `json:"openUriAction,omitempty"`

	// Title: Required. Title of the carousel item. Maximum of two lines of
	// text.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageBrowseCarouselCardBrowseCarouselCa
// rdItemOpenUrlAction: Actions on Google action to open a given url.
type GoogleCloudDialogflowV2IntentMessageBrowseCarouselCardBrowseCarouselCardItemOpenUrlAction struct {
	// Url: Required. URL
	Url string `json:"url,omitempty"`

	// UrlTypeHint: Optional. Specifies the type of viewer that is used when
	// opening
	// the URL. Defaults to opening via web browser.
	//
	// Possible values:
	//   "URL_TYPE_HINT_UNSPECIFIED" - Unspecified
	//   "AMP_ACTION" - Url would be an amp action
	//   "AMP_CONTENT" - URL that points directly to AMP content, or to a
	// canonical URL
	// which refers to AMP content via <link rel="amphtml">.
	UrlTypeHint string `json:"urlTypeHint,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageCard: The card response message.
type GoogleCloudDialogflowV2IntentMessageCard struct {
	// Buttons: Optional. The collection of card buttons.
	Buttons []*GoogleCloudDialogflowV2IntentMessageCardButton `json:"buttons,omitempty"`

	// ImageUri: Optional. The public URI to an image file for the card.
	ImageUri string `json:"imageUri,omitempty"`

	// Subtitle: Optional. The subtitle of the card.
	Subtitle string `json:"subtitle,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2IntentMessageCardButton: Contains information
// about a button.
type GoogleCloudDialogflowV2IntentMessageCardButton struct {
	// Postback: Optional. The text to send back to the Dialogflow API or a
	// URI to
	// open.
	Postback string `json:"postback,omitempty"`

	// Text: Optional. The text to show on the button.
	Text string `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageCarouselSelect: The card for
// presenting a carousel of options to select from.
type GoogleCloudDialogflowV2IntentMessageCarouselSelect struct {
	// Items: Required. Carousel items.
	Items []*GoogleCloudDialogflowV2IntentMessageCarouselSelectItem `json:"items,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageCarouselSelectItem: An item in
// the carousel.
type GoogleCloudDialogflowV2IntentMessageCarouselSelectItem struct {
	// Description: Optional. The body text of the card.
	Description string `json:"description,omitempty"`

	// Image: Optional. The image to display.
	Image *GoogleCloudDialogflowV2IntentMessageImage `json:"image,omitempty"`

	// Info: Required. Additional info about the option item.
	Info *GoogleCloudDialogflowV2IntentMessageSelectItemInfo `json:"info,omitempty"`

	// Title: Required. Title of the carousel item.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageColumnProperties: Column
// properties for TableCard.
type GoogleCloudDialogflowV2IntentMessageColumnProperties struct {
	// Header: Required. Column heading.
	Header string `json:"header,omitempty"`

	// HorizontalAlignment: Optional. Defines text alignment for all cells
	// in this column.
	//
	// Possible values:
	//   "HORIZONTAL_ALIGNMENT_UNSPECIFIED" - Text is aligned to the leading
	// edge of the column.
	//   "LEADING" - Text is aligned to the leading edge of the column.
	//   "CENTER" - Text is centered in the column.
	//   "TRAILING" - Text is aligned to the trailing edge of the column.
	HorizontalAlignment string `json:"horizontalAlignment,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageImage: The image response
// message.
type GoogleCloudDialogflowV2IntentMessageImage struct {
	// AccessibilityText: Optional. A text description of the image to be
	// used for accessibility,
	// e.g., screen readers.
	AccessibilityText string `json:"accessibilityText,omitempty"`

	// ImageUri: Optional. The public URI to an image file.
	ImageUri string `json:"imageUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageLinkOutSuggestion: The suggestion
// chip message that allows the user to jump out to the app
// or website associated with this agent.
type GoogleCloudDialogflowV2IntentMessageLinkOutSuggestion struct {
	// DestinationName: Required. The name of the app or site this chip is
	// linking to.
	DestinationName string `json:"destinationName,omitempty"`

	// Uri: Required. The URI of the app or site to open when the user taps
	// the
	// suggestion chip.
	Uri string `json:"uri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageListSelect: The card for
// presenting a list of options to select from.
type GoogleCloudDialogflowV2IntentMessageListSelect struct {
	// Items: Required. List items.
	Items []*GoogleCloudDialogflowV2IntentMessageListSelectItem `json:"items,omitempty"`

	// Subtitle: Optional. Subtitle of the list.
	Subtitle string `json:"subtitle,omitempty"`

	// Title: Optional. The overall title of the list.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageListSelectItem: An item in the
// list.
type GoogleCloudDialogflowV2IntentMessageListSelectItem struct {
	// Description: Optional. The main text describing the item.
	Description string `json:"description,omitempty"`

	// Image: Optional. The image to display.
	Image *GoogleCloudDialogflowV2IntentMessageImage `json:"image,omitempty"`

	// Info: Required. Additional information about this option.
	Info *GoogleCloudDialogflowV2IntentMessageSelectItemInfo `json:"info,omitempty"`

	// Title: Required. The title of the list item.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageMediaContent: The media content
// card for Actions on Google.
type GoogleCloudDialogflowV2IntentMessageMediaContent struct {
	// MediaObjects: Required. List of media objects.
	MediaObjects []*GoogleCloudDialogflowV2IntentMessageMediaContentResponseMediaObject `json:"mediaObjects,omitempty"`

	// MediaType: Optional. What type of media is the content (ie "audio").
	//
	// Possible values:
	//   "RESPONSE_MEDIA_TYPE_UNSPECIFIED" - Unspecified.
	//   "AUDIO" - Response media type is audio.
	MediaType string `json:"mediaType,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageMediaContentResponseMediaObject:
// Response media object for media content card.
type GoogleCloudDialogflowV2IntentMessageMediaContentResponseMediaObject struct {
	// ContentUrl: Required. Url where the media is stored.
	ContentUrl string `json:"contentUrl,omitempty"`

	// Description: Optional. Description of media card.
	Description string `json:"description,omitempty"`

	// Icon: Optional. Icon to display above media content.
	Icon *GoogleCloudDialogflowV2IntentMessageImage `json:"icon,omitempty"`

	// LargeImage: Optional. Image to display above media content.
	LargeImage *GoogleCloudDialogflowV2IntentMessageImage `json:"largeImage,omitempty"`

	// Name: Required. Name of media card.
	Name string `json:"name,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageQuickReplies: The quick replies
// response message.
type GoogleCloudDialogflowV2IntentMessageQuickReplies struct {
	// QuickReplies: Optional. The collection of quick replies.
	QuickReplies []string `json:"quickReplies,omitempty"`

	// Title: Optional. The title of the collection of quick replies.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageSelectItemInfo: Additional info
// about the select item for when it is triggered in a
// dialog.
type GoogleCloudDialogflowV2IntentMessageSelectItemInfo struct {
	// Key: Required. A unique key that will be sent back to the agent if
	// this
	// response is given.
	Key string `json:"key,omitempty"`

	// Synonyms: Optional. A list of synonyms that can also be used to
	// trigger this
	// item in dialog.
	Synonyms []string `json:"synonyms,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageSimpleResponse: The simple
// response message containing speech or text.
type GoogleCloudDialogflowV2IntentMessageSimpleResponse struct {
	// DisplayText: Optional. The text to display.
	DisplayText string `json:"displayText,omitempty"`

	// Ssml: One of text_to_speech or ssml must be provided. Structured
	// spoken
	// response to the user in the SSML format. Mutually exclusive
	// with
	// text_to_speech.
	Ssml string `json:"ssml,omitempty"`

	// TextToSpeech: One of text_to_speech or ssml must be provided. The
	// plain text of the
	// speech output. Mutually exclusive with ssml.
	TextToSpeech string `json:"textToSpeech,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageSimpleResponses: The collection
// of simple response candidates.
// This message in `QueryResult.fulfillment_messages`
// and
// `WebhookResponse.fulfillment_messages` should contain only
// one
// `SimpleResponse`.
type GoogleCloudDialogflowV2IntentMessageSimpleResponses struct {
	// SimpleResponses: Required. The list of simple responses.
	SimpleResponses []*GoogleCloudDialogflowV2IntentMessageSimpleResponse `json:"simpleResponses,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageSuggestion: The suggestion chip
// message that the user can tap to quickly post a reply
// to the conversation.
type GoogleCloudDialogflowV2IntentMessageSuggestion struct {
	// Title: Required. The text shown the in the suggestion chip.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageSuggestions: The collection of
// suggestions.
type GoogleCloudDialogflowV2IntentMessageSuggestions struct {
	// Suggestions: Required. The list of suggested replies.
	Suggestions []*GoogleCloudDialogflowV2IntentMessageSuggestion `json:"suggestions,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageTableCard: Table card for Actions
// on Google.
type GoogleCloudDialogflowV2IntentMessageTableCard struct {
	// Buttons: Optional. List of buttons for the card.
	Buttons []*GoogleCloudDialogflowV2IntentMessageBasicCardButton `json:"buttons,omitempty"`

	// ColumnProperties: Optional. Display properties for the columns in
	// this table.
	ColumnProperties []*GoogleCloudDialogflowV2IntentMessageColumnProperties `json:"columnProperties,omitempty"`

	// Image: Optional. Image which should be displayed on the card.
	Image *GoogleCloudDialogflowV2IntentMessageImage `json:"image,omitempty"`

	// Rows: Optional. Rows in this table of data.
	Rows []*GoogleCloudDialogflowV2IntentMessageTableCardRow `json:"rows,omitempty"`

	// Subtitle: Optional. Subtitle to the title.
	Subtitle string `json:"subtitle,omitempty"`

	// Title: Required. Title of the card.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageTableCardCell: Cell of
// TableCardRow.
type GoogleCloudDialogflowV2IntentMessageTableCardCell struct {
	// Text: Required. Text in this cell.
	Text string `json:"text,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 *GoogleCloudDialogflowV2IntentMessageTableCardCell) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2IntentMessageTableCardCell
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2IntentMessageTableCardRow: Row of TableCard.
type GoogleCloudDialogflowV2IntentMessageTableCardRow struct {
	// Cells: Optional. List of cells that make up this row.
	Cells []*GoogleCloudDialogflowV2IntentMessageTableCardCell `json:"cells,omitempty"`

	// DividerAfter: Optional. Whether to add a visual divider after this
	// row.
	DividerAfter bool `json:"dividerAfter,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentMessageText: The text response message.
type GoogleCloudDialogflowV2IntentMessageText struct {
	// Text: Optional. The collection of the agent's responses.
	Text []string `json:"text,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 *GoogleCloudDialogflowV2IntentMessageText) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2IntentMessageText
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2IntentParameter: Represents intent parameters.
type GoogleCloudDialogflowV2IntentParameter struct {
	// DefaultValue: Optional. The default value to use when the `value`
	// yields an empty
	// result.
	// Default values can be extracted from contexts by using the
	// following
	// syntax: `#context_name.parameter_name`.
	DefaultValue string `json:"defaultValue,omitempty"`

	// DisplayName: Required. The name of the parameter.
	DisplayName string `json:"displayName,omitempty"`

	// EntityTypeDisplayName: Optional. The name of the entity type,
	// prefixed with `@`, that
	// describes values of the parameter. If the parameter is
	// required, this must be provided.
	EntityTypeDisplayName string `json:"entityTypeDisplayName,omitempty"`

	// IsList: Optional. Indicates whether the parameter represents a list
	// of values.
	IsList bool `json:"isList,omitempty"`

	// Mandatory: Optional. Indicates whether the parameter is required.
	// That is,
	// whether the intent cannot be completed without collecting the
	// parameter
	// value.
	Mandatory bool `json:"mandatory,omitempty"`

	// Name: The unique identifier of this parameter.
	Name string `json:"name,omitempty"`

	// Prompts: Optional. The collection of prompts that the agent can
	// present to the
	// user in order to collect a value for the parameter.
	Prompts []string `json:"prompts,omitempty"`

	// Value: Optional. The definition of the parameter value. It can be:
	// - a constant string,
	// - a parameter value defined as `$parameter_name`,
	// - an original parameter value defined as
	// `$parameter_name.original`,
	// - a parameter value from some context defined as
	//   `#context_name.parameter_name`.
	Value string `json:"value,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentTrainingPhrase: Represents an example
// that the agent is trained on.
type GoogleCloudDialogflowV2IntentTrainingPhrase struct {
	// Name: Output only. The unique identifier of this training phrase.
	Name string `json:"name,omitempty"`

	// Parts: Required. The ordered list of training phrase parts.
	// The parts are concatenated in order to form the training
	// phrase.
	//
	// Note: The API does not automatically annotate training phrases like
	// the
	// Dialogflow Console does.
	//
	// Note: Do not forget to include whitespace at part boundaries,
	// so the training phrase is well formatted when the parts are
	// concatenated.
	//
	// If the training phrase does not need to be annotated with
	// parameters,
	// you just need a single part with only the Part.text field set.
	//
	// If you want to annotate the training phrase, you must create
	// multiple
	// parts, where the fields of each part are populated in one of two
	// ways:
	//
	// -   `Part.text` is set to a part of the phrase that has no
	// parameters.
	// -   `Part.text` is set to a part of the phrase that you want to
	// annotate,
	//     and the `entity_type`, `alias`, and `user_defined` fields are
	// all
	//     set.
	Parts []*GoogleCloudDialogflowV2IntentTrainingPhrasePart `json:"parts,omitempty"`

	// TimesAddedCount: Optional. Indicates how many times this example was
	// added to
	// the intent. Each time a developer adds an existing sample by editing
	// an
	// intent or training, this counter is increased.
	TimesAddedCount int64 `json:"timesAddedCount,omitempty"`

	// Type: Required. The type of the training phrase.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Not specified. This value should never be
	// used.
	//   "EXAMPLE" - Examples do not contain @-prefixed entity type names,
	// but example parts
	// can be annotated with entity types.
	//   "TEMPLATE" - Templates are not annotated with entity types, but
	// they can contain
	// @-prefixed entity type names as substrings.
	// Template mode has been deprecated. Example mode is the only
	// supported
	// way to create new training phrases. If you have existing
	// training
	// phrases that you've created in template mode, those will continue
	// to
	// work.
	Type string `json:"type,omitempty"`

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

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

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

// GoogleCloudDialogflowV2IntentTrainingPhrasePart: Represents a part of
// a training phrase.
type GoogleCloudDialogflowV2IntentTrainingPhrasePart struct {
	// Alias: Optional. The parameter name for the value extracted from
	// the
	// annotated part of the example.
	// This field is required for annotated parts of the training phrase.
	Alias string `json:"alias,omitempty"`

	// EntityType: Optional. The entity type name prefixed with `@`.
	// This field is required for annotated parts of the training phrase.
	EntityType string `json:"entityType,omitempty"`

	// Text: Required. The text for this part.
	Text string `json:"text,omitempty"`

	// UserDefined: Optional. Indicates whether the text was manually
	// annotated.
	// This field is set to true when the Dialogflow Console is used
	// to
	// manually annotate the part. When creating an annotated part with
	// the
	// API, you must set this to true.
	UserDefined bool `json:"userDefined,omitempty"`

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

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

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

// GoogleCloudDialogflowV2ListContextsResponse: The response message for
// Contexts.ListContexts.
type GoogleCloudDialogflowV2ListContextsResponse struct {
	// Contexts: The list of contexts. There will be a maximum number of
	// items
	// returned based on the page_size field in the request.
	Contexts []*GoogleCloudDialogflowV2Context `json:"contexts,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no
	// more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2ListEntityTypesResponse: The response message
// for EntityTypes.ListEntityTypes.
type GoogleCloudDialogflowV2ListEntityTypesResponse struct {
	// EntityTypes: The list of agent entity types. There will be a maximum
	// number of items
	// returned based on the page_size field in the request.
	EntityTypes []*GoogleCloudDialogflowV2EntityType `json:"entityTypes,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no
	// more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2ListIntentsResponse: The response message for
// Intents.ListIntents.
type GoogleCloudDialogflowV2ListIntentsResponse struct {
	// Intents: The list of agent intents. There will be a maximum number of
	// items
	// returned based on the page_size field in the request.
	Intents []*GoogleCloudDialogflowV2Intent `json:"intents,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no
	// more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2ListSessionEntityTypesResponse: The response
// message for SessionEntityTypes.ListSessionEntityTypes.
type GoogleCloudDialogflowV2ListSessionEntityTypesResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no
	// more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SessionEntityTypes: The list of session entity types. There will be a
	// maximum number of items
	// returned based on the page_size field in the request.
	SessionEntityTypes []*GoogleCloudDialogflowV2SessionEntityType `json:"sessionEntityTypes,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2Message: Represents a message posted into a
// conversation.
type GoogleCloudDialogflowV2Message struct {
	// Content: Required. The message content.
	Content string `json:"content,omitempty"`

	// CreateTime: Output only. The time when the message was created.
	CreateTime string `json:"createTime,omitempty"`

	// LanguageCode: Optional. The message language.
	// This should be a
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt)
	// language tag. Example: "en-US".
	LanguageCode string `json:"languageCode,omitempty"`

	// MessageAnnotation: Output only. The annotation for the message.
	MessageAnnotation *GoogleCloudDialogflowV2MessageAnnotation `json:"messageAnnotation,omitempty"`

	// Name: The unique identifier of the message.
	// Format: `projects/<Project
	// ID>/conversations/<Conversation
	// ID>/messages/<Message ID>`.
	Name string `json:"name,omitempty"`

	// Participant: Output only. The participant that sends this message.
	Participant string `json:"participant,omitempty"`

	// ParticipantRole: Output only. The role of the participant.
	//
	// Possible values:
	//   "ROLE_UNSPECIFIED" - Participant role not set.
	//   "HUMAN_AGENT" - Participant is a human agent.
	//   "AUTOMATED_AGENT" - Participant is an automated agent, such as a
	// Dialogflow agent.
	//   "END_USER" - Participant is an end user that has called or chatted
	// with
	// Dialogflow services.
	ParticipantRole string `json:"participantRole,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 *GoogleCloudDialogflowV2Message) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2Message
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2MessageAnnotation: Represents the result of
// annotation for the message.
type GoogleCloudDialogflowV2MessageAnnotation struct {
	// ContainEntities: Indicates whether the text message contains
	// entities.
	ContainEntities bool `json:"containEntities,omitempty"`

	// Parts: The collection of annotated message parts ordered by
	// their
	// position in the message. You can recover the annotated message
	// by
	// concatenating [AnnotatedMessagePart.text].
	Parts []*GoogleCloudDialogflowV2AnnotatedMessagePart `json:"parts,omitempty"`

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

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

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

// GoogleCloudDialogflowV2OriginalDetectIntentRequest: Represents the
// contents of the original request that was passed to
// the `[Streaming]DetectIntent` call.
type GoogleCloudDialogflowV2OriginalDetectIntentRequest struct {
	// Payload: Optional. This field is set to the value of the
	// `QueryParameters.payload`
	// field passed in the request. Some integrations that query a
	// Dialogflow
	// agent may provide additional information in the payload.
	//
	// In particular for the Telephony Gateway this field has the
	// form:
	// <pre>{
	//  "telephony": {
	//    "caller_id": "+18558363987"
	//  }
	// }</pre>
	// Note: The caller ID field (`caller_id`) will be redacted for
	// Standard
	// Edition agents and populated with the caller ID in
	// [E.164
	// format](https://en.wikipedia.org/wiki/E.164) for Enterprise Edition
	// agents.
	Payload googleapi.RawMessage `json:"payload,omitempty"`

	// Source: The source of this request, e.g., `google`, `facebook`,
	// `slack`. It is set
	// by Dialogflow-owned servers.
	Source string `json:"source,omitempty"`

	// Version: Optional. The version of the protocol used for this
	// request.
	// This field is AoG-specific.
	Version string `json:"version,omitempty"`

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

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

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

// GoogleCloudDialogflowV2OutputAudioConfig: Instructs the speech
// synthesizer on how to generate the output audio content.
// If this audio config is supplied in a request, it overrides all
// existing
// text-to-speech settings applied to the agent.
type GoogleCloudDialogflowV2OutputAudioConfig struct {
	// AudioEncoding: Required. Audio encoding of the synthesized audio
	// content.
	//
	// Possible values:
	//   "OUTPUT_AUDIO_ENCODING_UNSPECIFIED" - Not specified.
	//   "OUTPUT_AUDIO_ENCODING_LINEAR_16" - Uncompressed 16-bit signed
	// little-endian samples (Linear PCM).
	// Audio content returned as LINEAR16 also contains a WAV header.
	//   "OUTPUT_AUDIO_ENCODING_MP3" - MP3 audio at 32kbps.
	//   "OUTPUT_AUDIO_ENCODING_OGG_OPUS" - Opus encoded audio wrapped in an
	// ogg container. The result will be a
	// file which can be played natively on Android, and in browsers (at
	// least
	// Chrome and Firefox). The quality of the encoding is considerably
	// higher
	// than MP3 while using approximately the same bitrate.
	AudioEncoding string `json:"audioEncoding,omitempty"`

	// SampleRateHertz: The synthesis sample rate (in hertz) for this audio.
	// If not
	// provided, then the synthesizer will use the default sample rate based
	// on
	// the audio encoding. If this is different from the voice's natural
	// sample
	// rate, then the synthesizer will honor this request by converting to
	// the
	// desired sample rate (which might result in worse audio quality).
	SampleRateHertz int64 `json:"sampleRateHertz,omitempty"`

	// SynthesizeSpeechConfig: Configuration of how speech should be
	// synthesized.
	SynthesizeSpeechConfig *GoogleCloudDialogflowV2SynthesizeSpeechConfig `json:"synthesizeSpeechConfig,omitempty"`

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

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

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

// GoogleCloudDialogflowV2QueryInput: Represents the query input. It can
// contain either:
//
// 1.  An audio config which
//     instructs the speech recognizer how to process the speech
// audio.
//
// 2.  A conversational query in the form of text,.
//
// 3.  An event that specifies which intent to trigger.
type GoogleCloudDialogflowV2QueryInput struct {
	// AudioConfig: Instructs the speech recognizer how to process the
	// speech audio.
	AudioConfig *GoogleCloudDialogflowV2InputAudioConfig `json:"audioConfig,omitempty"`

	// Event: The event to be processed.
	Event *GoogleCloudDialogflowV2EventInput `json:"event,omitempty"`

	// Text: The natural language text to be processed.
	Text *GoogleCloudDialogflowV2TextInput `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2QueryParameters: Represents the parameters of
// the conversational query.
type GoogleCloudDialogflowV2QueryParameters struct {
	// Contexts: The collection of contexts to be activated before this
	// query is
	// executed.
	Contexts []*GoogleCloudDialogflowV2Context `json:"contexts,omitempty"`

	// GeoLocation: The geo location of this conversational query.
	GeoLocation *GoogleTypeLatLng `json:"geoLocation,omitempty"`

	// Payload: This field can be used to pass custom data into the
	// webhook
	// associated with the agent. Arbitrary JSON objects are supported.
	Payload googleapi.RawMessage `json:"payload,omitempty"`

	// ResetContexts: Specifies whether to delete all contexts in the
	// current session
	// before the new ones are activated.
	ResetContexts bool `json:"resetContexts,omitempty"`

	// SentimentAnalysisRequestConfig: Configures the type of sentiment
	// analysis to perform. If not
	// provided, sentiment analysis is not performed.
	SentimentAnalysisRequestConfig *GoogleCloudDialogflowV2SentimentAnalysisRequestConfig `json:"sentimentAnalysisRequestConfig,omitempty"`

	// SessionEntityTypes: Additional session entity types to replace or
	// extend developer
	// entity types with. The entity synonyms apply to all languages and
	// persist
	// for the session of this query.
	SessionEntityTypes []*GoogleCloudDialogflowV2SessionEntityType `json:"sessionEntityTypes,omitempty"`

	// TimeZone: The time zone of this conversational query from the
	// [time zone database](https://www.iana.org/time-zones),
	// e.g.,
	// America/New_York, Europe/Paris. If not provided, the time zone
	// specified in
	// agent settings is used.
	TimeZone string `json:"timeZone,omitempty"`

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

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

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

// GoogleCloudDialogflowV2QueryResult: Represents the result of
// conversational query or event processing.
type GoogleCloudDialogflowV2QueryResult struct {
	// Action: The action name from the matched intent.
	Action string `json:"action,omitempty"`

	// AllRequiredParamsPresent: This field is set to:
	//
	// - `false` if the matched intent has required parameters and not all
	// of
	//    the required parameter values have been collected.
	// - `true` if all required parameter values have been collected, or if
	// the
	//    matched intent doesn't contain any required parameters.
	AllRequiredParamsPresent bool `json:"allRequiredParamsPresent,omitempty"`

	// DiagnosticInfo: Free-form diagnostic information for the associated
	// detect intent request.
	// The fields of this data can change without notice, so you should not
	// write
	// code that depends on its structure.
	// The data may contain:
	//
	// - webhook call latency
	// - webhook errors
	DiagnosticInfo googleapi.RawMessage `json:"diagnosticInfo,omitempty"`

	// FulfillmentMessages: The collection of rich messages to present to
	// the user.
	FulfillmentMessages []*GoogleCloudDialogflowV2IntentMessage `json:"fulfillmentMessages,omitempty"`

	// FulfillmentText: The text to be pronounced to the user or shown on
	// the screen.
	// Note: This is a legacy field, `fulfillment_messages` should be
	// preferred.
	FulfillmentText string `json:"fulfillmentText,omitempty"`

	// Intent: The intent that matched the conversational query. Some,
	// not
	// all fields are filled in this message, including but not limited
	// to:
	// `name`, `display_name`, `end_interaction` and `is_fallback`.
	Intent *GoogleCloudDialogflowV2Intent `json:"intent,omitempty"`

	// IntentDetectionConfidence: The intent detection confidence. Values
	// range from 0.0
	// (completely uncertain) to 1.0 (completely certain).
	// This value is for informational purpose only and is only used to
	// help match the best intent within the classification threshold.
	// This value may change for the same end-user expression at any time
	// due to a
	// model retraining or change in implementation.
	// If there are `multiple knowledge_answers` messages, this value is set
	// to
	// the greatest `knowledgeAnswers.match_confidence` value in the list.
	IntentDetectionConfidence float64 `json:"intentDetectionConfidence,omitempty"`

	// LanguageCode: The language that was triggered during intent
	// detection.
	// See
	// [Language
	// Support](https://cloud.google.com/dialogflow/docs/reference/
	// language)
	// for a list of the currently supported language codes.
	LanguageCode string `json:"languageCode,omitempty"`

	// OutputContexts: The collection of output contexts. If
	// applicable,
	// `output_contexts.parameters` contains entries with name
	// `<parameter name>.original` containing the original parameter
	// values
	// before the query.
	OutputContexts []*GoogleCloudDialogflowV2Context `json:"outputContexts,omitempty"`

	// Parameters: The collection of extracted parameters.
	Parameters googleapi.RawMessage `json:"parameters,omitempty"`

	// QueryText: The original conversational query text:
	//
	// - If natural language text was provided as input, `query_text`
	// contains
	//   a copy of the input.
	// - If natural language speech audio was provided as input,
	// `query_text`
	//   contains the speech recognition result. If speech recognizer
	// produced
	//   multiple alternatives, a particular one is picked.
	// - If automatic spell correction is enabled, `query_text` will contain
	// the
	//   corrected user input.
	QueryText string `json:"queryText,omitempty"`

	// SentimentAnalysisResult: The sentiment analysis result, which depends
	// on the
	// `sentiment_analysis_request_config` specified in the request.
	SentimentAnalysisResult *GoogleCloudDialogflowV2SentimentAnalysisResult `json:"sentimentAnalysisResult,omitempty"`

	// SpeechRecognitionConfidence: The Speech recognition confidence
	// between 0.0 and 1.0. A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. The default of 0.0 is a sentinel value indicating that
	// confidence
	// was not set.
	//
	// This field is not guaranteed to be accurate or set. In particular
	// this
	// field isn't set for StreamingDetectIntent since the streaming
	// endpoint has
	// separate confidence estimates per portion of the audio
	// in
	// StreamingRecognitionResult.
	SpeechRecognitionConfidence float64 `json:"speechRecognitionConfidence,omitempty"`

	// WebhookPayload: If the query was fulfilled by a webhook call, this
	// field is set to the
	// value of the `payload` field returned in the webhook response.
	WebhookPayload googleapi.RawMessage `json:"webhookPayload,omitempty"`

	// WebhookSource: If the query was fulfilled by a webhook call, this
	// field is set to the
	// value of the `source` field returned in the webhook response.
	WebhookSource string `json:"webhookSource,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2RestoreAgentRequest: The request message for
// Agents.RestoreAgent.
type GoogleCloudDialogflowV2RestoreAgentRequest struct {
	// AgentContent: Zip compressed raw byte content for agent.
	AgentContent string `json:"agentContent,omitempty"`

	// AgentUri: The URI to a Google Cloud Storage file containing the agent
	// to restore.
	// Note: The URI must start with "gs://".
	AgentUri string `json:"agentUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2SearchAgentsResponse: The response message for
// Agents.SearchAgents.
type GoogleCloudDialogflowV2SearchAgentsResponse struct {
	// Agents: The list of agents. There will be a maximum number of items
	// returned based
	// on the page_size field in the request.
	Agents []*GoogleCloudDialogflowV2Agent `json:"agents,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no
	// more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2Sentiment: The sentiment, such as
// positive/negative feeling or association, for a unit
// of analysis, such as the query text.
type GoogleCloudDialogflowV2Sentiment 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 *GoogleCloudDialogflowV2Sentiment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2Sentiment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudDialogflowV2Sentiment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudDialogflowV2Sentiment
	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
}

// GoogleCloudDialogflowV2SentimentAnalysisRequestConfig: Configures the
// types of sentiment analysis to perform.
type GoogleCloudDialogflowV2SentimentAnalysisRequestConfig struct {
	// AnalyzeQueryTextSentiment: Instructs the service to perform sentiment
	// analysis on
	// `query_text`. If not provided, sentiment analysis is not performed
	// on
	// `query_text`.
	AnalyzeQueryTextSentiment bool `json:"analyzeQueryTextSentiment,omitempty"`

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

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

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

// GoogleCloudDialogflowV2SentimentAnalysisResult: The result of
// sentiment analysis as configured
// by
// `sentiment_analysis_request_config`.
type GoogleCloudDialogflowV2SentimentAnalysisResult struct {
	// QueryTextSentiment: The sentiment analysis result for `query_text`.
	QueryTextSentiment *GoogleCloudDialogflowV2Sentiment `json:"queryTextSentiment,omitempty"`

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

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

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

// GoogleCloudDialogflowV2SessionEntityType: Represents a session entity
// type.
//
// Extends or replaces a custom entity type at the user session level
// (we
// refer to the entity types defined at the agent level as "custom
// entity
// types").
//
// Note: session entity types apply to all queries, regardless of the
// language.
type GoogleCloudDialogflowV2SessionEntityType struct {
	// Entities: Required. The collection of entities associated with this
	// session entity
	// type.
	Entities []*GoogleCloudDialogflowV2EntityTypeEntity `json:"entities,omitempty"`

	// EntityOverrideMode: Required. Indicates whether the additional data
	// should override or
	// supplement the custom entity type definition.
	//
	// Possible values:
	//   "ENTITY_OVERRIDE_MODE_UNSPECIFIED" - Not specified. This value
	// should be never used.
	//   "ENTITY_OVERRIDE_MODE_OVERRIDE" - The collection of session
	// entities overrides the collection of entities
	// in the corresponding custom entity type.
	//   "ENTITY_OVERRIDE_MODE_SUPPLEMENT" - The collection of session
	// entities extends the collection of entities in
	// the corresponding custom entity type.
	//
	// Note: Even in this override mode calls to
	// `ListSessionEntityTypes`,
	// `GetSessionEntityType`, `CreateSessionEntityType`
	// and
	// `UpdateSessionEntityType` only return the additional entities added
	// in
	// this session entity type. If you want to get the supplemented
	// list,
	// please call EntityTypes.GetEntityType on the custom entity type
	// and merge.
	EntityOverrideMode string `json:"entityOverrideMode,omitempty"`

	// Name: Required. The unique identifier of this session entity type.
	// Format:
	// `projects/<Project ID>/agent/sessions/<Session
	// ID>/entityTypes/<Entity Type
	// Display Name>`, or `projects/<Project
	// ID>/agent/environments/<Environment
	// ID>/users/<User ID>/sessions/<Session ID>/entityTypes/<Entity Type
	// Display
	// Name>`.
	// If `Environment ID` is not specified, we assume default
	// 'draft'
	// environment. If `User ID` is not specified, we assume default '-'
	// user.
	//
	// `<Entity Type Display Name>` must be the display name of an existing
	// entity
	// type in the same agent that will be overridden or supplemented.
	Name string `json:"name,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 *GoogleCloudDialogflowV2SessionEntityType) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2SessionEntityType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2SpeechContext: Hints for the speech recognizer
// to help with recognition in a specific
// conversation state.
type GoogleCloudDialogflowV2SpeechContext struct {
	// Boost: Optional. Boost for this context compared to other contexts:
	// * If the boost is positive, Dialogflow will increase the probability
	// that
	//   the phrases in this context are recognized over similar sounding
	// phrases.
	// * If the boost is unspecified or non-positive, Dialogflow will not
	// apply
	//   any boost.
	//
	// Dialogflow recommends that you use boosts in the range (0, 20] and
	// that you
	// find a value that fits your use case with binary search.
	Boost float64 `json:"boost,omitempty"`

	// Phrases: Optional. A list of strings containing words and phrases
	// that the speech
	// recognizer should recognize with higher likelihood.
	//
	// This list can be used to:
	// * improve accuracy for words and phrases you expect the user to say,
	//   e.g. typical commands for your Dialogflow agent
	// * add additional words to the speech recognizer vocabulary
	// * ...
	//
	// See the [Cloud
	// Speech
	// documentation](https://cloud.google.com/speech-to-text/quotas) for
	// usage
	// limits.
	Phrases []string `json:"phrases,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2SynthesizeSpeechConfig: Configuration of how
// speech should be synthesized.
type GoogleCloudDialogflowV2SynthesizeSpeechConfig struct {
	// EffectsProfileId: Optional. An identifier which selects 'audio
	// effects' profiles that are
	// applied on (post synthesized) text to speech. Effects are applied on
	// top of
	// each other in the order they are given.
	EffectsProfileId []string `json:"effectsProfileId,omitempty"`

	// Pitch: Optional. Speaking pitch, in the range [-20.0, 20.0]. 20 means
	// increase 20
	// semitones from the original pitch. -20 means decrease 20 semitones
	// from the
	// original pitch.
	Pitch float64 `json:"pitch,omitempty"`

	// SpeakingRate: Optional. Speaking rate/speed, in the range [0.25,
	// 4.0]. 1.0 is the normal
	// native speed supported by the specific voice. 2.0 is twice as fast,
	// and
	// 0.5 is half as fast. If unset(0.0), defaults to the native 1.0 speed.
	// Any
	// other values < 0.25 or > 4.0 will return an error.
	SpeakingRate float64 `json:"speakingRate,omitempty"`

	// Voice: Optional. The desired voice of the synthesized audio.
	Voice *GoogleCloudDialogflowV2VoiceSelectionParams `json:"voice,omitempty"`

	// VolumeGainDb: Optional. Volume gain (in dB) of the normal native
	// volume supported by the
	// specific voice, in the range [-96.0, 16.0]. If unset, or set to a
	// value of
	// 0.0 (dB), will play at normal native signal amplitude. A value of
	// -6.0 (dB)
	// will play at approximately half the amplitude of the normal native
	// signal
	// amplitude. A value of +6.0 (dB) will play at approximately twice
	// the
	// amplitude of the normal native signal amplitude. We strongly
	// recommend not
	// to exceed +10 (dB) as there's usually no effective increase in
	// loudness for
	// any value greater than that.
	VolumeGainDb float64 `json:"volumeGainDb,omitempty"`

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

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

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

func (s *GoogleCloudDialogflowV2SynthesizeSpeechConfig) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudDialogflowV2SynthesizeSpeechConfig
	var s1 struct {
		Pitch        gensupport.JSONFloat64 `json:"pitch"`
		SpeakingRate gensupport.JSONFloat64 `json:"speakingRate"`
		VolumeGainDb gensupport.JSONFloat64 `json:"volumeGainDb"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Pitch = float64(s1.Pitch)
	s.SpeakingRate = float64(s1.SpeakingRate)
	s.VolumeGainDb = float64(s1.VolumeGainDb)
	return nil
}

// GoogleCloudDialogflowV2TextInput: Represents the natural language
// text to be processed.
type GoogleCloudDialogflowV2TextInput struct {
	// LanguageCode: Required. The language of this conversational query.
	// See
	// [Language
	// Support](https://cloud.google.com/dialogflow/docs/reference/
	// language)
	// for a list of the currently supported language codes. Note that
	// queries in
	// the same session do not necessarily need to specify the same
	// language.
	LanguageCode string `json:"languageCode,omitempty"`

	// Text: Required. The UTF-8 encoded natural language text to be
	// processed.
	// Text length must not exceed 256 characters.
	Text string `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2TrainAgentRequest: The request message for
// Agents.TrainAgent.
type GoogleCloudDialogflowV2TrainAgentRequest struct {
}

// GoogleCloudDialogflowV2ValidationError: Represents a single
// validation error.
type GoogleCloudDialogflowV2ValidationError struct {
	// Entries: The names of the entries that the error is associated
	// with.
	// Format:
	//
	// - "projects/<Project ID>/agent", if the error is associated with the
	// entire
	// agent.
	// - "projects/<Project ID>/agent/intents/<Intent ID>", if the error
	// is
	// associated with certain intents.
	// - "projects/<Project
	// ID>/agent/intents/<Intent Id>/trainingPhrases/<Training Phrase ID>",
	// if the
	// error is associated with certain intent training phrases.
	// - "projects/<Project ID>/agent/intents/<Intent
	// Id>/parameters/<Parameter
	// ID>", if the error is associated with certain intent parameters.
	// - "projects/<Project ID>/agent/entities/<Entity ID>", if the error
	// is
	// associated with certain entities.
	Entries []string `json:"entries,omitempty"`

	// ErrorMessage: The detailed error messsage.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// Severity: The severity of the error.
	//
	// Possible values:
	//   "SEVERITY_UNSPECIFIED" - Not specified. This value should never be
	// used.
	//   "INFO" - The agent doesn't follow Dialogflow best practicies.
	//   "WARNING" - The agent may not behave as expected.
	//   "ERROR" - The agent may experience partial failures.
	//   "CRITICAL" - The agent may completely fail.
	Severity string `json:"severity,omitempty"`

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

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

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

// GoogleCloudDialogflowV2ValidationResult: Represents the output of
// agent validation.
type GoogleCloudDialogflowV2ValidationResult struct {
	// ValidationErrors: Contains all validation errors.
	ValidationErrors []*GoogleCloudDialogflowV2ValidationError `json:"validationErrors,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2VoiceSelectionParams: Description of which
// voice to use for speech synthesis.
type GoogleCloudDialogflowV2VoiceSelectionParams struct {
	// Name: Optional. The name of the voice. If not set, the service will
	// choose a
	// voice based on the other parameters such as language_code
	// and
	// ssml_gender.
	Name string `json:"name,omitempty"`

	// SsmlGender: Optional. The preferred gender of the voice. If not set,
	// the service will
	// choose a voice based on the other parameters such as language_code
	// and
	// name. Note that this is only a preference, not requirement. If
	// a
	// voice of the appropriate gender is not available, the synthesizer
	// should
	// substitute a voice with a different gender rather than failing the
	// request.
	//
	// Possible values:
	//   "SSML_VOICE_GENDER_UNSPECIFIED" - An unspecified gender, which
	// means that the client doesn't care which
	// gender the selected voice will have.
	//   "SSML_VOICE_GENDER_MALE" - A male voice.
	//   "SSML_VOICE_GENDER_FEMALE" - A female voice.
	//   "SSML_VOICE_GENDER_NEUTRAL" - A gender-neutral voice.
	SsmlGender string `json:"ssmlGender,omitempty"`

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

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

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

// GoogleCloudDialogflowV2WebhookRequest: The request message for a
// webhook call.
type GoogleCloudDialogflowV2WebhookRequest struct {
	// OriginalDetectIntentRequest: Optional. The contents of the original
	// request that was passed to
	// `[Streaming]DetectIntent` call.
	OriginalDetectIntentRequest *GoogleCloudDialogflowV2OriginalDetectIntentRequest `json:"originalDetectIntentRequest,omitempty"`

	// QueryResult: The result of the conversational query or event
	// processing. Contains the
	// same value as `[Streaming]DetectIntentResponse.query_result`.
	QueryResult *GoogleCloudDialogflowV2QueryResult `json:"queryResult,omitempty"`

	// ResponseId: The unique identifier of the response. Contains the same
	// value as
	// `[Streaming]DetectIntentResponse.response_id`.
	ResponseId string `json:"responseId,omitempty"`

	// Session: The unique identifier of detectIntent request session.
	// Can be used to identify end-user inside webhook
	// implementation.
	// Format: `projects/<Project ID>/agent/sessions/<Session ID>`,
	// or
	// `projects/<Project ID>/agent/environments/<Environment
	// ID>/users/<User
	// ID>/sessions/<Session ID>`.
	Session string `json:"session,omitempty"`

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

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

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

// GoogleCloudDialogflowV2WebhookResponse: The response message for a
// webhook call.
//
// This response is validated by the Dialogflow server. If validation
// fails,
// an error will be returned in the QueryResult.diagnostic_info
// field.
// Setting JSON fields to an empty value with the wrong type is a common
// error.
// To avoid this error:
//
// - Use "" for empty strings
// - Use `{}` or `null` for empty objects
// - Use `[]` or `null` for empty arrays
//
// For more information, see the
// [Protocol Buffers
// Language
// Guide](https://developers.google.com/protocol-buffers/docs/pr
// oto3#json).
type GoogleCloudDialogflowV2WebhookResponse struct {
	// FollowupEventInput: Optional. Makes the platform immediately invoke
	// another `DetectIntent` call
	// internally with the specified event as input.
	// When this field is set, Dialogflow ignores the
	// `fulfillment_text`,
	// `fulfillment_messages`, and `payload` fields.
	FollowupEventInput *GoogleCloudDialogflowV2EventInput `json:"followupEventInput,omitempty"`

	// FulfillmentMessages: Optional. The collection of rich messages to
	// present to the user. This
	// value is passed directly to `QueryResult.fulfillment_messages`.
	FulfillmentMessages []*GoogleCloudDialogflowV2IntentMessage `json:"fulfillmentMessages,omitempty"`

	// FulfillmentText: Optional. The text to be shown on the screen. This
	// value is passed directly
	// to `QueryResult.fulfillment_text`.
	FulfillmentText string `json:"fulfillmentText,omitempty"`

	// OutputContexts: Optional. The collection of output contexts. This
	// value is passed directly
	// to `QueryResult.output_contexts`.
	OutputContexts []*GoogleCloudDialogflowV2Context `json:"outputContexts,omitempty"`

	// Payload: Optional. This value is passed directly to
	// `QueryResult.webhook_payload`.
	// See the related `fulfillment_messages[i].payload field`, which may be
	// used
	// as an alternative to this field.
	//
	// This field can be used for Actions on Google responses.
	// It should have a structure similar to the JSON message shown here.
	// For more
	// information, see
	// [Actions on Google
	// Webhook
	// Format](https://developers.google.com/actions/dialogflow/webho
	// ok)
	// <pre>{
	//   "google": {
	//     "expectUserResponse": true,
	//     "richResponse": {
	//       "items": [
	//         {
	//           "simpleResponse": {
	//             "textToSpeech": "this is a simple response"
	//           }
	//         }
	//       ]
	//     }
	//   }
	// }</pre>
	Payload googleapi.RawMessage `json:"payload,omitempty"`

	// SessionEntityTypes: Optional. Additional session entity types to
	// replace or extend developer
	// entity types with. The entity synonyms apply to all languages and
	// persist
	// for the session of this query. Setting the session entity types
	// inside
	// webhook overwrites the session entity types that have been set
	// through
	// `DetectIntentRequest.query_params.session_entity_types`.
	SessionEntityTypes []*GoogleCloudDialogflowV2SessionEntityType `json:"sessionEntityTypes,omitempty"`

	// Source: Optional. This value is passed directly to
	// `QueryResult.webhook_source`.
	Source string `json:"source,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1AnnotatedConversationDataset: Represents
// an annotated conversation dataset.
// ConversationDataset can have multiple AnnotatedConversationDataset,
// each of
// them represents one result from one annotation
// task.
// AnnotatedConversationDataset can only be generated from annotation
// task,
// which will be triggered by LabelConversation.
type GoogleCloudDialogflowV2beta1AnnotatedConversationDataset struct {
	// CompletedExampleCount: Output only. Number of examples that have
	// annotations in the annotated
	// conversation dataset.
	CompletedExampleCount int64 `json:"completedExampleCount,omitempty,string"`

	// CreateTime: Output only. Creation time of this annotated conversation
	// dataset.
	CreateTime string `json:"createTime,omitempty"`

	// Description: Optional. The description of the annotated conversation
	// dataset.
	// Maximum of 10000 bytes.
	Description string `json:"description,omitempty"`

	// DisplayName: Required. The display name of the annotated conversation
	// dataset.
	// It's specified when user starts an annotation task. Maximum of 64
	// bytes.
	DisplayName string `json:"displayName,omitempty"`

	// ExampleCount: Output only. Number of examples in the annotated
	// conversation dataset.
	ExampleCount int64 `json:"exampleCount,omitempty,string"`

	// Name: Output only. AnnotatedConversationDataset resource name.
	// Format:
	// `projects/<Project ID>/conversationDatasets/<Conversation
	// Dataset
	// ID>/annotatedConversationDatasets/<Annotated Conversation Dataset
	// ID>`
	Name string `json:"name,omitempty"`

	// QuestionTypeName: Output only. Question type name that identifies a
	// labeling task.
	// A question is a single task that a worker answers. A question type is
	// set
	// of related questions. Each question belongs to a particular question
	// type.
	// It can be used in CrowdCompute UI to filter and manage labeling
	// tasks.
	QuestionTypeName string `json:"questionTypeName,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1BatchUpdateEntityTypesResponse: The
// response message for EntityTypes.BatchUpdateEntityTypes.
type GoogleCloudDialogflowV2beta1BatchUpdateEntityTypesResponse struct {
	// EntityTypes: The collection of updated or created entity types.
	EntityTypes []*GoogleCloudDialogflowV2beta1EntityType `json:"entityTypes,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1BatchUpdateIntentsResponse: The response
// message for Intents.BatchUpdateIntents.
type GoogleCloudDialogflowV2beta1BatchUpdateIntentsResponse struct {
	// Intents: The collection of updated or created intents.
	Intents []*GoogleCloudDialogflowV2beta1Intent `json:"intents,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1Context: Represents a context.
type GoogleCloudDialogflowV2beta1Context struct {
	// LifespanCount: Optional. The number of conversational query requests
	// after which the
	// context expires. If set to `0` (the default) the context
	// expires
	// immediately. Contexts expire automatically after 20 minutes if
	// there
	// are no matching queries.
	LifespanCount int64 `json:"lifespanCount,omitempty"`

	// Name: Required. The unique identifier of the context.
	// Format:
	// `projects/<Project ID>/agent/sessions/<Session ID>/contexts/<Context
	// ID>`,
	// or `projects/<Project ID>/agent/environments/<Environment
	// ID>/users/<User
	// ID>/sessions/<Session ID>/contexts/<Context ID>`.
	//
	// The `Context ID` is always converted to lowercase, may only
	// contain
	// characters in a-zA-Z0-9_-% and may be at most 250 bytes long.
	//
	// If `Environment ID` is not specified, we assume default
	// 'draft'
	// environment. If `User ID` is not specified, we assume default '-'
	// user.
	//
	// The following context names are reserved for internal use by
	// Dialogflow.
	// You should not use these contexts or create contexts with these
	// names:
	//
	// * `__system_counters__`
	// * `*_id_dialog_context`
	// * `*_dialog_params_size`
	Name string `json:"name,omitempty"`

	// Parameters: Optional. The collection of parameters associated with
	// this context.
	// Refer to
	// [this
	// doc](https://cloud.google.com/dialogflow/docs/intents-actions-pa
	// rameters)
	// for syntax.
	Parameters googleapi.RawMessage `json:"parameters,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1EntityType: Represents an entity
// type.
// Entity types serve as a tool for extracting parameter values from
// natural
// language queries.
type GoogleCloudDialogflowV2beta1EntityType struct {
	// AutoExpansionMode: Optional. Indicates whether the entity type can be
	// automatically
	// expanded.
	//
	// Possible values:
	//   "AUTO_EXPANSION_MODE_UNSPECIFIED" - Auto expansion disabled for the
	// entity.
	//   "AUTO_EXPANSION_MODE_DEFAULT" - Allows an agent to recognize values
	// that have not been explicitly
	// listed in the entity.
	AutoExpansionMode string `json:"autoExpansionMode,omitempty"`

	// DisplayName: Required. The name of the entity type.
	DisplayName string `json:"displayName,omitempty"`

	// EnableFuzzyExtraction: Optional. Enables fuzzy entity extraction
	// during classification.
	EnableFuzzyExtraction bool `json:"enableFuzzyExtraction,omitempty"`

	// Entities: Optional. The collection of entity entries associated with
	// the entity type.
	Entities []*GoogleCloudDialogflowV2beta1EntityTypeEntity `json:"entities,omitempty"`

	// Kind: Required. Indicates the kind of entity type.
	//
	// Possible values:
	//   "KIND_UNSPECIFIED" - Not specified. This value should be never
	// used.
	//   "KIND_MAP" - Map entity types allow mapping of a group of synonyms
	// to a reference
	// value.
	//   "KIND_LIST" - List entity types contain a set of entries that do
	// not map to reference
	// values. However, list entity types can contain references to other
	// entity
	// types (with or without aliases).
	//   "KIND_REGEXP" - Regexp entity types allow to specify regular
	// expressions in entries
	// values.
	Kind string `json:"kind,omitempty"`

	// Name: The unique identifier of the entity type.
	// Required for EntityTypes.UpdateEntityType
	// and
	// EntityTypes.BatchUpdateEntityTypes methods.
	// Format: `projects/<Project ID>/agent/entityTypes/<Entity Type ID>`.
	Name string `json:"name,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1EntityTypeEntity: An **entity entry** for
// an associated entity type.
type GoogleCloudDialogflowV2beta1EntityTypeEntity struct {
	// Synonyms: Required. A collection of value synonyms. For example, if
	// the entity type
	// is *vegetable*, and `value` is *scallions*, a synonym could be
	// *green
	// onions*.
	//
	// For `KIND_LIST` entity types:
	//
	// *   This collection must contain exactly one synonym equal to
	// `value`.
	Synonyms []string `json:"synonyms,omitempty"`

	// Value: Required. The primary value associated with this entity
	// entry.
	// For example, if the entity type is *vegetable*, the value could
	// be
	// *scallions*.
	//
	// For `KIND_MAP` entity types:
	//
	// *   A reference value to be used in place of synonyms.
	//
	// For `KIND_LIST` entity types:
	//
	// *   A string that can contain references to other entity types (with
	// or
	//     without aliases).
	Value string `json:"value,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1EventInput: Events allow for matching
// intents by event name instead of the natural
// language input. For instance, input `<event: { name:
// "welcome_event",
// parameters: { name: "Sam" } }>` can trigger a personalized welcome
// response.
// The parameter `name` may be used by the agent in the
// response:
// "Hello #welcome_event.name! What can I do for you today?".
type GoogleCloudDialogflowV2beta1EventInput struct {
	// LanguageCode: Required. The language of this query. See
	// [Language
	// Support](https://cloud.google.com/dialogflow/docs/reference/
	// language)
	// for a list of the currently supported language codes. Note that
	// queries in
	// the same session do not necessarily need to specify the same
	// language.
	LanguageCode string `json:"languageCode,omitempty"`

	// Name: Required. The unique identifier of the event.
	Name string `json:"name,omitempty"`

	// Parameters: The collection of parameters associated with the event.
	Parameters googleapi.RawMessage `json:"parameters,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1ExportAgentResponse: The response message
// for Agents.ExportAgent.
type GoogleCloudDialogflowV2beta1ExportAgentResponse struct {
	// AgentContent: Zip compressed raw byte content for agent.
	AgentContent string `json:"agentContent,omitempty"`

	// AgentUri: The URI to a file containing the exported agent. This field
	// is populated
	// only if `agent_uri` is specified in `ExportAgentRequest`.
	AgentUri string `json:"agentUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1Intent: Represents an intent.
// Intents convert a number of user expressions or patterns into an
// action. An
// action is an extraction of a user command or sentence semantics.
type GoogleCloudDialogflowV2beta1Intent struct {
	// Action: Optional. The name of the action associated with the
	// intent.
	// Note: The action name must not contain whitespaces.
	Action string `json:"action,omitempty"`

	// DefaultResponsePlatforms: Optional. The list of platforms for which
	// the first responses will be
	// copied from the messages in PLATFORM_UNSPECIFIED (i.e. default
	// platform).
	//
	// Possible values:
	//   "PLATFORM_UNSPECIFIED" - Not specified.
	//   "FACEBOOK" - Facebook.
	//   "SLACK" - Slack.
	//   "TELEGRAM" - Telegram.
	//   "KIK" - Kik.
	//   "SKYPE" - Skype.
	//   "LINE" - Line.
	//   "VIBER" - Viber.
	//   "ACTIONS_ON_GOOGLE" - Actions on Google.
	// When using Actions on Google, you can choose one of the
	// specific
	// Intent.Message types that mention support for Actions on Google,
	// or you can use the advanced Intent.Message.payload field.
	// The payload field provides access to AoG features not available in
	// the
	// specific message types.
	// If using the Intent.Message.payload field, it should have a
	// structure
	// similar to the JSON message shown here. For more information,
	// see
	// [Actions on Google
	// Webhook
	// Format](https://developers.google.com/actions/dialogflow/webho
	// ok)
	// <pre>{
	//   "expectUserResponse": true,
	//   "isSsml": false,
	//   "noInputPrompts": [],
	//   "richResponse": {
	//     "items": [
	//       {
	//         "simpleResponse": {
	//           "displayText": "hi",
	//           "textToSpeech": "hello"
	//         }
	//       }
	//     ],
	//     "suggestions": [
	//       {
	//         "title": "Say this"
	//       },
	//       {
	//         "title": "or this"
	//       }
	//     ]
	//   },
	//   "systemIntent": {
	//     "data": {
	//       "@type":
	// "type.googleapis.com/google.actions.v2.OptionValueSpec",
	//       "listSelect": {
	//         "items": [
	//           {
	//             "optionInfo": {
	//               "key": "key1",
	//               "synonyms": [
	//                 "key one"
	//               ]
	//             },
	//             "title": "must not be empty, but unique"
	//           },
	//           {
	//             "optionInfo": {
	//               "key": "key2",
	//               "synonyms": [
	//                 "key two"
	//               ]
	//             },
	//             "title": "must not be empty, but unique"
	//           }
	//         ]
	//       }
	//     },
	//     "intent": "actions.intent.OPTION"
	//   }
	// }</pre>
	//   "TELEPHONY" - Telephony Gateway.
	//   "GOOGLE_HANGOUTS" - Google Hangouts.
	DefaultResponsePlatforms []string `json:"defaultResponsePlatforms,omitempty"`

	// DisplayName: Required. The name of this intent.
	DisplayName string `json:"displayName,omitempty"`

	// EndInteraction: Optional. Indicates that this intent ends an
	// interaction. Some integrations
	// (e.g., Actions on Google or Dialogflow phone gateway) use this
	// information
	// to close interaction with an end user. Default is false.
	EndInteraction bool `json:"endInteraction,omitempty"`

	// Events: Optional. The collection of event names that trigger the
	// intent.
	// If the collection of input contexts is not empty, all of the contexts
	// must
	// be present in the active user session for an event to trigger this
	// intent.
	Events []string `json:"events,omitempty"`

	// FollowupIntentInfo: Read-only. Information about all followup intents
	// that have this intent as
	// a direct or indirect parent. We populate this field only in the
	// output.
	FollowupIntentInfo []*GoogleCloudDialogflowV2beta1IntentFollowupIntentInfo `json:"followupIntentInfo,omitempty"`

	// InputContextNames: Optional. The list of context names required for
	// this intent to be
	// triggered.
	// Format: `projects/<Project ID>/agent/sessions/-/contexts/<Context
	// ID>`.
	InputContextNames []string `json:"inputContextNames,omitempty"`

	// IsFallback: Optional. Indicates whether this is a fallback intent.
	IsFallback bool `json:"isFallback,omitempty"`

	// Messages: Optional. The collection of rich messages corresponding to
	// the
	// `Response` field in the Dialogflow console.
	Messages []*GoogleCloudDialogflowV2beta1IntentMessage `json:"messages,omitempty"`

	// MlDisabled: Optional. Indicates whether Machine Learning is disabled
	// for the intent.
	// Note: If `ml_disabled` setting is set to true, then this intent is
	// not
	// taken into account during inference in `ML ONLY` match mode.
	// Also,
	// auto-markup in the UI is turned off.
	MlDisabled bool `json:"mlDisabled,omitempty"`

	// MlEnabled: Optional. Indicates whether Machine Learning is enabled
	// for the intent.
	// Note: If `ml_enabled` setting is set to false, then this intent is
	// not
	// taken into account during inference in `ML ONLY` match mode.
	// Also,
	// auto-markup in the UI is turned off.
	// DEPRECATED! Please use `ml_disabled` field instead.
	// NOTE: If both `ml_enabled` and `ml_disabled` are either not set or
	// false,
	// then the default value is determined as follows:
	// - Before April 15th, 2018 the default is:
	//   ml_enabled = false / ml_disabled = true.
	// - After April 15th, 2018 the default is:
	//   ml_enabled = true / ml_disabled = false.
	MlEnabled bool `json:"mlEnabled,omitempty"`

	// Name: The unique identifier of this intent.
	// Required for Intents.UpdateIntent and
	// Intents.BatchUpdateIntents
	// methods.
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	Name string `json:"name,omitempty"`

	// OutputContexts: Optional. The collection of contexts that are
	// activated when the intent
	// is matched. Context messages in this collection should not set
	// the
	// parameters field. Setting the `lifespan_count` to 0 will reset the
	// context
	// when the intent is matched.
	// Format: `projects/<Project ID>/agent/sessions/-/contexts/<Context
	// ID>`.
	OutputContexts []*GoogleCloudDialogflowV2beta1Context `json:"outputContexts,omitempty"`

	// Parameters: Optional. The collection of parameters associated with
	// the intent.
	Parameters []*GoogleCloudDialogflowV2beta1IntentParameter `json:"parameters,omitempty"`

	// ParentFollowupIntentName: Read-only after creation. The unique
	// identifier of the parent intent in the
	// chain of followup intents. You can set this field when creating an
	// intent,
	// for example with CreateIntent or
	// BatchUpdateIntents, in order to make this
	// intent a followup intent.
	//
	// It identifies the parent followup intent.
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	ParentFollowupIntentName string `json:"parentFollowupIntentName,omitempty"`

	// Priority: The priority of this intent. Higher numbers represent
	// higher
	// priorities.
	//
	// - If the supplied value is unspecified or 0, the service
	//   translates the value to 500,000, which corresponds to the
	//   `Normal` priority in the console.
	// - If the supplied value is negative, the intent is ignored
	//   in runtime detect intent requests.
	Priority int64 `json:"priority,omitempty"`

	// ResetContexts: Optional. Indicates whether to delete all contexts in
	// the current
	// session when this intent is matched.
	ResetContexts bool `json:"resetContexts,omitempty"`

	// RootFollowupIntentName: Read-only. The unique identifier of the root
	// intent in the chain of
	// followup intents. It identifies the correct followup intents chain
	// for
	// this intent. We populate this field only in the output.
	//
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	RootFollowupIntentName string `json:"rootFollowupIntentName,omitempty"`

	// TrainingPhrases: Optional. The collection of examples that the agent
	// is
	// trained on.
	TrainingPhrases []*GoogleCloudDialogflowV2beta1IntentTrainingPhrase `json:"trainingPhrases,omitempty"`

	// WebhookState: Optional. Indicates whether webhooks are enabled for
	// the intent.
	//
	// Possible values:
	//   "WEBHOOK_STATE_UNSPECIFIED" - Webhook is disabled in the agent and
	// in the intent.
	//   "WEBHOOK_STATE_ENABLED" - Webhook is enabled in the agent and in
	// the intent.
	//   "WEBHOOK_STATE_ENABLED_FOR_SLOT_FILLING" - Webhook is enabled in
	// the agent and in the intent. Also, each slot
	// filling prompt is forwarded to the webhook.
	WebhookState string `json:"webhookState,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentFollowupIntentInfo: Represents a
// single followup intent in the chain.
type GoogleCloudDialogflowV2beta1IntentFollowupIntentInfo struct {
	// FollowupIntentName: The unique identifier of the followup
	// intent.
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	FollowupIntentName string `json:"followupIntentName,omitempty"`

	// ParentFollowupIntentName: The unique identifier of the followup
	// intent's parent.
	// Format: `projects/<Project ID>/agent/intents/<Intent ID>`.
	ParentFollowupIntentName string `json:"parentFollowupIntentName,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessage: Corresponds to the
// `Response` field in the Dialogflow console.
type GoogleCloudDialogflowV2beta1IntentMessage struct {
	// BasicCard: Displays a basic card for Actions on Google.
	BasicCard *GoogleCloudDialogflowV2beta1IntentMessageBasicCard `json:"basicCard,omitempty"`

	// BrowseCarouselCard: Browse carousel card for Actions on Google.
	BrowseCarouselCard *GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCard `json:"browseCarouselCard,omitempty"`

	// Card: Displays a card.
	Card *GoogleCloudDialogflowV2beta1IntentMessageCard `json:"card,omitempty"`

	// CarouselSelect: Displays a carousel card for Actions on Google.
	CarouselSelect *GoogleCloudDialogflowV2beta1IntentMessageCarouselSelect `json:"carouselSelect,omitempty"`

	// Image: Displays an image.
	Image *GoogleCloudDialogflowV2beta1IntentMessageImage `json:"image,omitempty"`

	// LinkOutSuggestion: Displays a link out suggestion chip for Actions on
	// Google.
	LinkOutSuggestion *GoogleCloudDialogflowV2beta1IntentMessageLinkOutSuggestion `json:"linkOutSuggestion,omitempty"`

	// ListSelect: Displays a list card for Actions on Google.
	ListSelect *GoogleCloudDialogflowV2beta1IntentMessageListSelect `json:"listSelect,omitempty"`

	// MediaContent: The media content card for Actions on Google.
	MediaContent *GoogleCloudDialogflowV2beta1IntentMessageMediaContent `json:"mediaContent,omitempty"`

	// Payload: Returns a response containing a custom, platform-specific
	// payload.
	// See the Intent.Message.Platform type for a description of
	// the
	// structure that may be required for your platform.
	Payload googleapi.RawMessage `json:"payload,omitempty"`

	// Platform: Optional. The platform that this message is intended for.
	//
	// Possible values:
	//   "PLATFORM_UNSPECIFIED" - Not specified.
	//   "FACEBOOK" - Facebook.
	//   "SLACK" - Slack.
	//   "TELEGRAM" - Telegram.
	//   "KIK" - Kik.
	//   "SKYPE" - Skype.
	//   "LINE" - Line.
	//   "VIBER" - Viber.
	//   "ACTIONS_ON_GOOGLE" - Actions on Google.
	// When using Actions on Google, you can choose one of the
	// specific
	// Intent.Message types that mention support for Actions on Google,
	// or you can use the advanced Intent.Message.payload field.
	// The payload field provides access to AoG features not available in
	// the
	// specific message types.
	// If using the Intent.Message.payload field, it should have a
	// structure
	// similar to the JSON message shown here. For more information,
	// see
	// [Actions on Google
	// Webhook
	// Format](https://developers.google.com/actions/dialogflow/webho
	// ok)
	// <pre>{
	//   "expectUserResponse": true,
	//   "isSsml": false,
	//   "noInputPrompts": [],
	//   "richResponse": {
	//     "items": [
	//       {
	//         "simpleResponse": {
	//           "displayText": "hi",
	//           "textToSpeech": "hello"
	//         }
	//       }
	//     ],
	//     "suggestions": [
	//       {
	//         "title": "Say this"
	//       },
	//       {
	//         "title": "or this"
	//       }
	//     ]
	//   },
	//   "systemIntent": {
	//     "data": {
	//       "@type":
	// "type.googleapis.com/google.actions.v2.OptionValueSpec",
	//       "listSelect": {
	//         "items": [
	//           {
	//             "optionInfo": {
	//               "key": "key1",
	//               "synonyms": [
	//                 "key one"
	//               ]
	//             },
	//             "title": "must not be empty, but unique"
	//           },
	//           {
	//             "optionInfo": {
	//               "key": "key2",
	//               "synonyms": [
	//                 "key two"
	//               ]
	//             },
	//             "title": "must not be empty, but unique"
	//           }
	//         ]
	//       }
	//     },
	//     "intent": "actions.intent.OPTION"
	//   }
	// }</pre>
	//   "TELEPHONY" - Telephony Gateway.
	//   "GOOGLE_HANGOUTS" - Google Hangouts.
	Platform string `json:"platform,omitempty"`

	// QuickReplies: Displays quick replies.
	QuickReplies *GoogleCloudDialogflowV2beta1IntentMessageQuickReplies `json:"quickReplies,omitempty"`

	// RbmCarouselRichCard: Rich Business Messaging (RBM) carousel rich card
	// response.
	RbmCarouselRichCard *GoogleCloudDialogflowV2beta1IntentMessageRbmCarouselCard `json:"rbmCarouselRichCard,omitempty"`

	// RbmStandaloneRichCard: Standalone Rich Business Messaging (RBM) rich
	// card response.
	RbmStandaloneRichCard *GoogleCloudDialogflowV2beta1IntentMessageRbmStandaloneCard `json:"rbmStandaloneRichCard,omitempty"`

	// RbmText: Rich Business Messaging (RBM) text response.
	//
	// RBM allows businesses to send enriched and branded versions of SMS.
	// See
	// https://jibe.google.com/business-messaging.
	RbmText *GoogleCloudDialogflowV2beta1IntentMessageRbmText `json:"rbmText,omitempty"`

	// SimpleResponses: Returns a voice or text-only response for Actions on
	// Google.
	SimpleResponses *GoogleCloudDialogflowV2beta1IntentMessageSimpleResponses `json:"simpleResponses,omitempty"`

	// Suggestions: Displays suggestion chips for Actions on Google.
	Suggestions *GoogleCloudDialogflowV2beta1IntentMessageSuggestions `json:"suggestions,omitempty"`

	// TableCard: Table card for Actions on Google.
	TableCard *GoogleCloudDialogflowV2beta1IntentMessageTableCard `json:"tableCard,omitempty"`

	// TelephonyPlayAudio: Plays audio from a file in Telephony Gateway.
	TelephonyPlayAudio *GoogleCloudDialogflowV2beta1IntentMessageTelephonyPlayAudio `json:"telephonyPlayAudio,omitempty"`

	// TelephonySynthesizeSpeech: Synthesizes speech in Telephony Gateway.
	TelephonySynthesizeSpeech *GoogleCloudDialogflowV2beta1IntentMessageTelephonySynthesizeSpeech `json:"telephonySynthesizeSpeech,omitempty"`

	// TelephonyTransferCall: Transfers the call in Telephony Gateway.
	TelephonyTransferCall *GoogleCloudDialogflowV2beta1IntentMessageTelephonyTransferCall `json:"telephonyTransferCall,omitempty"`

	// Text: Returns a text response.
	Text *GoogleCloudDialogflowV2beta1IntentMessageText `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageBasicCard: The basic card
// message. Useful for displaying information.
type GoogleCloudDialogflowV2beta1IntentMessageBasicCard struct {
	// Buttons: Optional. The collection of card buttons.
	Buttons []*GoogleCloudDialogflowV2beta1IntentMessageBasicCardButton `json:"buttons,omitempty"`

	// FormattedText: Required, unless image is present. The body text of
	// the card.
	FormattedText string `json:"formattedText,omitempty"`

	// Image: Optional. The image for the card.
	Image *GoogleCloudDialogflowV2beta1IntentMessageImage `json:"image,omitempty"`

	// Subtitle: Optional. The subtitle of the card.
	Subtitle string `json:"subtitle,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageBasicCardButton: The button
// object that appears at the bottom of a card.
type GoogleCloudDialogflowV2beta1IntentMessageBasicCardButton struct {
	// OpenUriAction: Required. Action to take when a user taps on the
	// button.
	OpenUriAction *GoogleCloudDialogflowV2beta1IntentMessageBasicCardButtonOpenUriAction `json:"openUriAction,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageBasicCardButtonOpenUriAction:
//  Opens the given URI.
type GoogleCloudDialogflowV2beta1IntentMessageBasicCardButtonOpenUriAction struct {
	// Uri: Required. The HTTP or HTTPS scheme URI.
	Uri string `json:"uri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCard: Browse
// Carousel Card for Actions on
// Google.
// https://developers.google.com/actions/assistant/responses#brow
// sing_carousel
type GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCard struct {
	// ImageDisplayOptions: Optional. Settings for displaying the image.
	// Applies to every image in
	// items.
	//
	// Possible values:
	//   "IMAGE_DISPLAY_OPTIONS_UNSPECIFIED" - Fill the gaps between the
	// image and the image container with gray
	// bars.
	//   "GRAY" - Fill the gaps between the image and the image container
	// with gray
	// bars.
	//   "WHITE" - Fill the gaps between the image and the image container
	// with white
	// bars.
	//   "CROPPED" - Image is scaled such that the image width and height
	// match or exceed
	// the container dimensions. This may crop the top and bottom of
	// the
	// image if the scaled image height is greater than the
	// container
	// height, or crop the left and right of the image if the scaled
	// image
	// width is greater than the container width. This is similar to
	// "Zoom
	// Mode" on a widescreen TV when playing a 4:3 video.
	//   "BLURRED_BACKGROUND" - Pad the gaps between image and image frame
	// with a blurred copy of the
	// same image.
	ImageDisplayOptions string `json:"imageDisplayOptions,omitempty"`

	// Items: Required. List of items in the Browse Carousel Card. Minimum
	// of two
	// items, maximum of ten.
	Items []*GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCardBrowseCarouselCardItem `json:"items,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCardBrowseCarou
// selCardItem: Browsing carousel tile
type GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCardBrowseCarouselCardItem struct {
	// Description: Optional. Description of the carousel item. Maximum of
	// four lines of
	// text.
	Description string `json:"description,omitempty"`

	// Footer: Optional. Text that appears at the bottom of the Browse
	// Carousel
	// Card. Maximum of one line of text.
	Footer string `json:"footer,omitempty"`

	// Image: Optional. Hero image for the carousel item.
	Image *GoogleCloudDialogflowV2beta1IntentMessageImage `json:"image,omitempty"`

	// OpenUriAction: Required. Action to present to the user.
	OpenUriAction *GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCardBrowseCarouselCardItemOpenUrlAction `json:"openUriAction,omitempty"`

	// Title: Required. Title of the carousel item. Maximum of two lines of
	// text.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCardBrowseCarou
// selCardItemOpenUrlAction: Actions on Google action to open a given
// url.
type GoogleCloudDialogflowV2beta1IntentMessageBrowseCarouselCardBrowseCarouselCardItemOpenUrlAction struct {
	// Url: Required. URL
	Url string `json:"url,omitempty"`

	// UrlTypeHint: Optional. Specifies the type of viewer that is used when
	// opening
	// the URL. Defaults to opening via web browser.
	//
	// Possible values:
	//   "URL_TYPE_HINT_UNSPECIFIED" - Unspecified
	//   "AMP_ACTION" - Url would be an amp action
	//   "AMP_CONTENT" - URL that points directly to AMP content, or to a
	// canonical URL
	// which refers to AMP content via <link rel="amphtml">.
	UrlTypeHint string `json:"urlTypeHint,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageCard: The card response
// message.
type GoogleCloudDialogflowV2beta1IntentMessageCard struct {
	// Buttons: Optional. The collection of card buttons.
	Buttons []*GoogleCloudDialogflowV2beta1IntentMessageCardButton `json:"buttons,omitempty"`

	// ImageUri: Optional. The public URI to an image file for the card.
	ImageUri string `json:"imageUri,omitempty"`

	// Subtitle: Optional. The subtitle of the card.
	Subtitle string `json:"subtitle,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageCardButton: Optional.
// Contains information about a button.
type GoogleCloudDialogflowV2beta1IntentMessageCardButton struct {
	// Postback: Optional. The text to send back to the Dialogflow API or a
	// URI to
	// open.
	Postback string `json:"postback,omitempty"`

	// Text: Optional. The text to show on the button.
	Text string `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageCarouselSelect: The card for
// presenting a carousel of options to select from.
type GoogleCloudDialogflowV2beta1IntentMessageCarouselSelect struct {
	// Items: Required. Carousel items.
	Items []*GoogleCloudDialogflowV2beta1IntentMessageCarouselSelectItem `json:"items,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageCarouselSelectItem: An item
// in the carousel.
type GoogleCloudDialogflowV2beta1IntentMessageCarouselSelectItem struct {
	// Description: Optional. The body text of the card.
	Description string `json:"description,omitempty"`

	// Image: Optional. The image to display.
	Image *GoogleCloudDialogflowV2beta1IntentMessageImage `json:"image,omitempty"`

	// Info: Required. Additional info about the option item.
	Info *GoogleCloudDialogflowV2beta1IntentMessageSelectItemInfo `json:"info,omitempty"`

	// Title: Required. Title of the carousel item.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageColumnProperties: Column
// properties for TableCard.
type GoogleCloudDialogflowV2beta1IntentMessageColumnProperties struct {
	// Header: Required. Column heading.
	Header string `json:"header,omitempty"`

	// HorizontalAlignment: Optional. Defines text alignment for all cells
	// in this column.
	//
	// Possible values:
	//   "HORIZONTAL_ALIGNMENT_UNSPECIFIED" - Text is aligned to the leading
	// edge of the column.
	//   "LEADING" - Text is aligned to the leading edge of the column.
	//   "CENTER" - Text is centered in the column.
	//   "TRAILING" - Text is aligned to the trailing edge of the column.
	HorizontalAlignment string `json:"horizontalAlignment,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageImage: The image response
// message.
type GoogleCloudDialogflowV2beta1IntentMessageImage struct {
	// AccessibilityText: A text description of the image to be used for
	// accessibility,
	// e.g., screen readers. Required if image_uri is set for
	// CarouselSelect.
	AccessibilityText string `json:"accessibilityText,omitempty"`

	// ImageUri: Optional. The public URI to an image file.
	ImageUri string `json:"imageUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageLinkOutSuggestion: The
// suggestion chip message that allows the user to jump out to the
// app
// or website associated with this agent.
type GoogleCloudDialogflowV2beta1IntentMessageLinkOutSuggestion struct {
	// DestinationName: Required. The name of the app or site this chip is
	// linking to.
	DestinationName string `json:"destinationName,omitempty"`

	// Uri: Required. The URI of the app or site to open when the user taps
	// the
	// suggestion chip.
	Uri string `json:"uri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageListSelect: The card for
// presenting a list of options to select from.
type GoogleCloudDialogflowV2beta1IntentMessageListSelect struct {
	// Items: Required. List items.
	Items []*GoogleCloudDialogflowV2beta1IntentMessageListSelectItem `json:"items,omitempty"`

	// Subtitle: Optional. Subtitle of the list.
	Subtitle string `json:"subtitle,omitempty"`

	// Title: Optional. The overall title of the list.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageListSelectItem: An item in
// the list.
type GoogleCloudDialogflowV2beta1IntentMessageListSelectItem struct {
	// Description: Optional. The main text describing the item.
	Description string `json:"description,omitempty"`

	// Image: Optional. The image to display.
	Image *GoogleCloudDialogflowV2beta1IntentMessageImage `json:"image,omitempty"`

	// Info: Required. Additional information about this option.
	Info *GoogleCloudDialogflowV2beta1IntentMessageSelectItemInfo `json:"info,omitempty"`

	// Title: Required. The title of the list item.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageMediaContent: The media
// content card for Actions on Google.
type GoogleCloudDialogflowV2beta1IntentMessageMediaContent struct {
	// MediaObjects: Required. List of media objects.
	MediaObjects []*GoogleCloudDialogflowV2beta1IntentMessageMediaContentResponseMediaObject `json:"mediaObjects,omitempty"`

	// MediaType: Optional. What type of media is the content (ie "audio").
	//
	// Possible values:
	//   "RESPONSE_MEDIA_TYPE_UNSPECIFIED" - Unspecified.
	//   "AUDIO" - Response media type is audio.
	MediaType string `json:"mediaType,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageMediaContentResponseMediaObje
// ct: Response media object for media content card.
type GoogleCloudDialogflowV2beta1IntentMessageMediaContentResponseMediaObject struct {
	// ContentUrl: Required. Url where the media is stored.
	ContentUrl string `json:"contentUrl,omitempty"`

	// Description: Optional. Description of media card.
	Description string `json:"description,omitempty"`

	// Icon: Optional. Icon to display above media content.
	Icon *GoogleCloudDialogflowV2beta1IntentMessageImage `json:"icon,omitempty"`

	// LargeImage: Optional. Image to display above media content.
	LargeImage *GoogleCloudDialogflowV2beta1IntentMessageImage `json:"largeImage,omitempty"`

	// Name: Required. Name of media card.
	Name string `json:"name,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageQuickReplies: The quick
// replies response message.
type GoogleCloudDialogflowV2beta1IntentMessageQuickReplies struct {
	// QuickReplies: Optional. The collection of quick replies.
	QuickReplies []string `json:"quickReplies,omitempty"`

	// Title: Optional. The title of the collection of quick replies.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmCardContent: Rich
// Business Messaging (RBM) Card content
type GoogleCloudDialogflowV2beta1IntentMessageRbmCardContent struct {
	// Description: Optional. Description of the card (at most 2000
	// bytes).
	//
	// At least one of the title, description or media must be set.
	Description string `json:"description,omitempty"`

	// Media: Optional. However at least one of the title, description or
	// media must
	// be set. Media (image, GIF or a video) to include in the card.
	Media *GoogleCloudDialogflowV2beta1IntentMessageRbmCardContentRbmMedia `json:"media,omitempty"`

	// Suggestions: Optional. List of suggestions to include in the card.
	Suggestions []*GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestion `json:"suggestions,omitempty"`

	// Title: Optional. Title of the card (at most 200 bytes).
	//
	// At least one of the title, description or media must be set.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmCardContentRbmMedia: Rich
// Business Messaging (RBM) Media displayed in Cards
// The following media-types are currently supported:
//
// ## Image Types
//
//  image/jpeg
//  image/jpg'
//  image/gif
//  image/png
//
// ## Video Types
//
//  video/h263
//  video/m4v
//  video/mp4
//  video/mpeg
//  video/mpeg4
//  video/webm
type GoogleCloudDialogflowV2beta1IntentMessageRbmCardContentRbmMedia struct {
	// FileUri: Required. Publicly reachable URI of the file. The RBM
	// platform
	// determines the MIME type of the file from the content-type field
	// in
	// the HTTP headers when the platform fetches the file. The
	// content-type
	// field must be present and accurate in the HTTP response from the URL.
	FileUri string `json:"fileUri,omitempty"`

	// Height: Required for cards with vertical orientation. The height of
	// the media
	// within a rich card with a vertical layout.
	// (https://goo.gl/NeFCjz).
	// For a standalone card with horizontal layout, height is
	// not
	// customizable, and this field is ignored.
	//
	// Possible values:
	//   "HEIGHT_UNSPECIFIED" - Not specified.
	//   "SHORT" - 112 DP.
	//   "MEDIUM" - 168 DP.
	//   "TALL" - 264 DP. Not available for rich card carousels when the
	// card width
	// is set to small.
	Height string `json:"height,omitempty"`

	// ThumbnailUri: Optional. Publicly reachable URI of the thumbnail.If
	// you don't
	// provide a thumbnail URI, the RBM platform displays a
	// blank
	// placeholder thumbnail until the user's device downloads the
	// file.
	// Depending on the user's setting, the file may not
	// download
	// automatically and may require the user to tap a download button.
	ThumbnailUri string `json:"thumbnailUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmCarouselCard: Carousel
// Rich Business Messaging (RBM) rich card.
//
// Rich cards allow you to respond to users with more vivid content,
// e.g.
// with media and suggestions.
//
// For more details about RBM rich cards, please
// see:
// https://developers.google.com/rcs-business-messaging/rbm/guides/b
// uild/send-messages#rich-cards.
// If you want to show a single card with more control over the
// layout,
// please use RbmStandaloneCard instead.
type GoogleCloudDialogflowV2beta1IntentMessageRbmCarouselCard struct {
	// CardContents: Required. The cards in the carousel. A carousel must
	// have at least
	// 2 cards and at most 10.
	CardContents []*GoogleCloudDialogflowV2beta1IntentMessageRbmCardContent `json:"cardContents,omitempty"`

	// CardWidth: Required. The width of the cards in the carousel.
	//
	// Possible values:
	//   "CARD_WIDTH_UNSPECIFIED" - Not specified.
	//   "SMALL" - 120 DP. Note that tall media cannot be used.
	//   "MEDIUM" - 232 DP.
	CardWidth string `json:"cardWidth,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmStandaloneCard:
// Standalone Rich Business Messaging (RBM) rich card.
//
// Rich cards allow you to respond to users with more vivid content,
// e.g.
// with media and suggestions.
//
// For more details about RBM rich cards, please
// see:
// https://developers.google.com/rcs-business-messaging/rbm/guides/b
// uild/send-messages#rich-cards.
// You can group multiple rich cards into one using RbmCarouselCard
// but
// carousel cards will give you less control over the card layout.
type GoogleCloudDialogflowV2beta1IntentMessageRbmStandaloneCard struct {
	// CardContent: Required. Card content.
	CardContent *GoogleCloudDialogflowV2beta1IntentMessageRbmCardContent `json:"cardContent,omitempty"`

	// CardOrientation: Required. Orientation of the card.
	//
	// Possible values:
	//   "CARD_ORIENTATION_UNSPECIFIED" - Not specified.
	//   "HORIZONTAL" - Horizontal layout.
	//   "VERTICAL" - Vertical layout.
	CardOrientation string `json:"cardOrientation,omitempty"`

	// ThumbnailImageAlignment: Required if orientation is horizontal.
	// Image preview alignment for standalone cards with horizontal layout.
	//
	// Possible values:
	//   "THUMBNAIL_IMAGE_ALIGNMENT_UNSPECIFIED" - Not specified.
	//   "LEFT" - Thumbnail preview is left-aligned.
	//   "RIGHT" - Thumbnail preview is right-aligned.
	ThumbnailImageAlignment string `json:"thumbnailImageAlignment,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedAction: Rich
// Business Messaging (RBM) suggested client-side action that the
// user
// can choose from the card.
type GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedAction struct {
	// Dial: Suggested client side action: Dial a phone number
	Dial *GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggestedActionDial `json:"dial,omitempty"`

	// OpenUrl: Suggested client side action: Open a URI on device
	OpenUrl *GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggestedActionOpenUri `json:"openUrl,omitempty"`

	// PostbackData: Opaque payload that the Dialogflow receives in a user
	// event
	// when the user taps the suggested action. This data will be
	// also
	// forwarded to webhook to allow performing custom business logic.
	PostbackData string `json:"postbackData,omitempty"`

	// ShareLocation: Suggested client side action: Share user location
	ShareLocation *GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggestedActionShareLocation `json:"shareLocation,omitempty"`

	// Text: Text to display alongside the action.
	Text string `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggeste
// dActionDial: Opens the user's default dialer app with the specified
// phone number
// but does not dial automatically (https://goo.gl/ergbB2).
type GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggestedActionDial struct {
	// PhoneNumber: Required. The phone number to fill in the default dialer
	// app.
	// This field should be in
	// [E.164](https://en.wikipedia.org/wiki/E.164)
	// format. An example of a correctly formatted phone
	// number:
	// +15556767888.
	PhoneNumber string `json:"phoneNumber,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggeste
// dActionOpenUri: Opens the user's default web browser app to the
// specified uri
// (https://goo.gl/6GLJD2). If the user has an app installed that
// is
// registered as the default handler for the URL, then this app will
// be
// opened instead, and its icon will be used in the suggested action UI.
type GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggestedActionOpenUri struct {
	// Uri: Required. The uri to open on the user device
	Uri string `json:"uri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggeste
// dActionShareLocation: Opens the device's location chooser so the user
// can pick a location
// to send back to the agent (https://goo.gl/GXotJW).
type GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedActionRbmSuggestedActionShareLocation struct {
}

// GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedReply: Rich
// Business Messaging (RBM) suggested reply that the user can
// click
// instead of typing in their own response.
type GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedReply struct {
	// PostbackData: Opaque payload that the Dialogflow receives in a user
	// event
	// when the user taps the suggested reply. This data will be
	// also
	// forwarded to webhook to allow performing custom business logic.
	PostbackData string `json:"postbackData,omitempty"`

	// Text: Suggested reply text.
	Text string `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestion: Rich Business
// Messaging (RBM) suggestion. Suggestions allow user to
// easily select/click a predefined response or perform an action
// (like
// opening a web uri).
type GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestion struct {
	// Action: Predefined client side actions that user can choose
	Action *GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedAction `json:"action,omitempty"`

	// Reply: Predefined replies for user to select instead of typing
	Reply *GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestedReply `json:"reply,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageRbmText: Rich Business
// Messaging (RBM) text response with suggestions.
type GoogleCloudDialogflowV2beta1IntentMessageRbmText struct {
	// RbmSuggestion: Optional. One or more suggestions to show to the user.
	RbmSuggestion []*GoogleCloudDialogflowV2beta1IntentMessageRbmSuggestion `json:"rbmSuggestion,omitempty"`

	// Text: Required. Text sent and displayed to the user.
	Text string `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageSelectItemInfo: Additional
// info about the select item for when it is triggered in a
// dialog.
type GoogleCloudDialogflowV2beta1IntentMessageSelectItemInfo struct {
	// Key: Required. A unique key that will be sent back to the agent if
	// this
	// response is given.
	Key string `json:"key,omitempty"`

	// Synonyms: Optional. A list of synonyms that can also be used to
	// trigger this
	// item in dialog.
	Synonyms []string `json:"synonyms,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageSimpleResponse: The simple
// response message containing speech or text.
type GoogleCloudDialogflowV2beta1IntentMessageSimpleResponse struct {
	// DisplayText: Optional. The text to display.
	DisplayText string `json:"displayText,omitempty"`

	// Ssml: One of text_to_speech or ssml must be provided. Structured
	// spoken
	// response to the user in the SSML format. Mutually exclusive
	// with
	// text_to_speech.
	Ssml string `json:"ssml,omitempty"`

	// TextToSpeech: One of text_to_speech or ssml must be provided. The
	// plain text of the
	// speech output. Mutually exclusive with ssml.
	TextToSpeech string `json:"textToSpeech,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageSimpleResponses: The
// collection of simple response candidates.
// This message in `QueryResult.fulfillment_messages`
// and
// `WebhookResponse.fulfillment_messages` should contain only
// one
// `SimpleResponse`.
type GoogleCloudDialogflowV2beta1IntentMessageSimpleResponses struct {
	// SimpleResponses: Required. The list of simple responses.
	SimpleResponses []*GoogleCloudDialogflowV2beta1IntentMessageSimpleResponse `json:"simpleResponses,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageSuggestion: The suggestion
// chip message that the user can tap to quickly post a reply
// to the conversation.
type GoogleCloudDialogflowV2beta1IntentMessageSuggestion struct {
	// Title: Required. The text shown the in the suggestion chip.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageSuggestions: The collection
// of suggestions.
type GoogleCloudDialogflowV2beta1IntentMessageSuggestions struct {
	// Suggestions: Required. The list of suggested replies.
	Suggestions []*GoogleCloudDialogflowV2beta1IntentMessageSuggestion `json:"suggestions,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageTableCard: Table card for
// Actions on Google.
type GoogleCloudDialogflowV2beta1IntentMessageTableCard struct {
	// Buttons: Optional. List of buttons for the card.
	Buttons []*GoogleCloudDialogflowV2beta1IntentMessageBasicCardButton `json:"buttons,omitempty"`

	// ColumnProperties: Optional. Display properties for the columns in
	// this table.
	ColumnProperties []*GoogleCloudDialogflowV2beta1IntentMessageColumnProperties `json:"columnProperties,omitempty"`

	// Image: Optional. Image which should be displayed on the card.
	Image *GoogleCloudDialogflowV2beta1IntentMessageImage `json:"image,omitempty"`

	// Rows: Optional. Rows in this table of data.
	Rows []*GoogleCloudDialogflowV2beta1IntentMessageTableCardRow `json:"rows,omitempty"`

	// Subtitle: Optional. Subtitle to the title.
	Subtitle string `json:"subtitle,omitempty"`

	// Title: Required. Title of the card.
	Title string `json:"title,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageTableCardCell: Cell of
// TableCardRow.
type GoogleCloudDialogflowV2beta1IntentMessageTableCardCell struct {
	// Text: Required. Text in this cell.
	Text string `json:"text,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 *GoogleCloudDialogflowV2beta1IntentMessageTableCardCell) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2beta1IntentMessageTableCardCell
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2beta1IntentMessageTableCardRow: Row of
// TableCard.
type GoogleCloudDialogflowV2beta1IntentMessageTableCardRow struct {
	// Cells: Optional. List of cells that make up this row.
	Cells []*GoogleCloudDialogflowV2beta1IntentMessageTableCardCell `json:"cells,omitempty"`

	// DividerAfter: Optional. Whether to add a visual divider after this
	// row.
	DividerAfter bool `json:"dividerAfter,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageTelephonyPlayAudio: Plays
// audio from a file in Telephony Gateway.
type GoogleCloudDialogflowV2beta1IntentMessageTelephonyPlayAudio struct {
	// AudioUri: Required. URI to a Google Cloud Storage object containing
	// the audio to
	// play, e.g., "gs://bucket/object". The object must contain a
	// single
	// channel (mono) of linear PCM audio (2 bytes / sample) at 8kHz.
	//
	// This object must be readable by the
	// `service-<Project
	// Number>@gcp-sa-dialogflow.iam.gserviceaccount.com` service
	// account
	// where <Project Number> is the number of the Telephony Gateway
	// project
	// (usually the same as the Dialogflow agent project). If the Google
	// Cloud
	// Storage bucket is in the Telephony Gateway project, this permission
	// is
	// added by default when enabling the Dialogflow V2 API.
	//
	// For audio from other sources, consider using
	// the
	// `TelephonySynthesizeSpeech` message with SSML.
	AudioUri string `json:"audioUri,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageTelephonySynthesizeSpeech:
// Synthesizes speech and plays back the synthesized audio to the caller
// in
// Telephony Gateway.
//
// Telephony Gateway takes the synthesizer settings
// from
// `DetectIntentResponse.output_audio_config` which can either be set
// at request-level or can come from the agent-level synthesizer config.
type GoogleCloudDialogflowV2beta1IntentMessageTelephonySynthesizeSpeech struct {
	// Ssml: The SSML to be synthesized. For more information,
	// see
	// [SSML](https://developers.google.com/actions/reference/ssml).
	Ssml string `json:"ssml,omitempty"`

	// Text: The raw text to be synthesized.
	Text string `json:"text,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageTelephonyTransferCall:
// Transfers the call in Telephony Gateway.
type GoogleCloudDialogflowV2beta1IntentMessageTelephonyTransferCall struct {
	// PhoneNumber: Required. The phone number to transfer the call to
	// in [E.164 format](https://en.wikipedia.org/wiki/E.164).
	//
	// We currently only allow transferring to US numbers (+1xxxyyyzzzz).
	PhoneNumber string `json:"phoneNumber,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentMessageText: The text response
// message.
type GoogleCloudDialogflowV2beta1IntentMessageText struct {
	// Text: Optional. The collection of the agent's responses.
	Text []string `json:"text,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 *GoogleCloudDialogflowV2beta1IntentMessageText) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2beta1IntentMessageText
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2beta1IntentParameter: Represents intent
// parameters.
type GoogleCloudDialogflowV2beta1IntentParameter struct {
	// DefaultValue: Optional. The default value to use when the `value`
	// yields an empty
	// result.
	// Default values can be extracted from contexts by using the
	// following
	// syntax: `#context_name.parameter_name`.
	DefaultValue string `json:"defaultValue,omitempty"`

	// DisplayName: Required. The name of the parameter.
	DisplayName string `json:"displayName,omitempty"`

	// EntityTypeDisplayName: Optional. The name of the entity type,
	// prefixed with `@`, that
	// describes values of the parameter. If the parameter is
	// required, this must be provided.
	EntityTypeDisplayName string `json:"entityTypeDisplayName,omitempty"`

	// IsList: Optional. Indicates whether the parameter represents a list
	// of values.
	IsList bool `json:"isList,omitempty"`

	// Mandatory: Optional. Indicates whether the parameter is required.
	// That is,
	// whether the intent cannot be completed without collecting the
	// parameter
	// value.
	Mandatory bool `json:"mandatory,omitempty"`

	// Name: The unique identifier of this parameter.
	Name string `json:"name,omitempty"`

	// Prompts: Optional. The collection of prompts that the agent can
	// present to the
	// user in order to collect a value for the parameter.
	Prompts []string `json:"prompts,omitempty"`

	// Value: Optional. The definition of the parameter value. It can be:
	// - a constant string,
	// - a parameter value defined as `$parameter_name`,
	// - an original parameter value defined as
	// `$parameter_name.original`,
	// - a parameter value from some context defined as
	//   `#context_name.parameter_name`.
	Value string `json:"value,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentTrainingPhrase: Represents an
// example that the agent is trained on.
type GoogleCloudDialogflowV2beta1IntentTrainingPhrase struct {
	// Name: Output only. The unique identifier of this training phrase.
	Name string `json:"name,omitempty"`

	// Parts: Required. The ordered list of training phrase parts.
	// The parts are concatenated in order to form the training
	// phrase.
	//
	// Note: The API does not automatically annotate training phrases like
	// the
	// Dialogflow Console does.
	//
	// Note: Do not forget to include whitespace at part boundaries,
	// so the training phrase is well formatted when the parts are
	// concatenated.
	//
	// If the training phrase does not need to be annotated with
	// parameters,
	// you just need a single part with only the Part.text field set.
	//
	// If you want to annotate the training phrase, you must create
	// multiple
	// parts, where the fields of each part are populated in one of two
	// ways:
	//
	// -   `Part.text` is set to a part of the phrase that has no
	// parameters.
	// -   `Part.text` is set to a part of the phrase that you want to
	// annotate,
	//     and the `entity_type`, `alias`, and `user_defined` fields are
	// all
	//     set.
	Parts []*GoogleCloudDialogflowV2beta1IntentTrainingPhrasePart `json:"parts,omitempty"`

	// TimesAddedCount: Optional. Indicates how many times this example was
	// added to
	// the intent. Each time a developer adds an existing sample by editing
	// an
	// intent or training, this counter is increased.
	TimesAddedCount int64 `json:"timesAddedCount,omitempty"`

	// Type: Required. The type of the training phrase.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Not specified. This value should never be
	// used.
	//   "EXAMPLE" - Examples do not contain @-prefixed entity type names,
	// but example parts
	// can be annotated with entity types.
	//   "TEMPLATE" - Templates are not annotated with entity types, but
	// they can contain
	// @-prefixed entity type names as substrings.
	// Template mode has been deprecated. Example mode is the only
	// supported
	// way to create new training phrases. If you have existing
	// training
	// phrases that you've created in template mode, those will continue
	// to
	// work.
	Type string `json:"type,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1IntentTrainingPhrasePart: Represents a
// part of a training phrase.
type GoogleCloudDialogflowV2beta1IntentTrainingPhrasePart struct {
	// Alias: Optional. The parameter name for the value extracted from
	// the
	// annotated part of the example.
	// This field is required for annotated parts of the training phrase.
	Alias string `json:"alias,omitempty"`

	// EntityType: Optional. The entity type name prefixed with `@`.
	// This field is required for annotated parts of the training phrase.
	EntityType string `json:"entityType,omitempty"`

	// Text: Required. The text for this part.
	Text string `json:"text,omitempty"`

	// UserDefined: Optional. Indicates whether the text was manually
	// annotated.
	// This field is set to true when the Dialogflow Console is used
	// to
	// manually annotate the part. When creating an annotated part with
	// the
	// API, you must set this to true.
	UserDefined bool `json:"userDefined,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1KnowledgeAnswers: Represents the result
// of querying a Knowledge base.
type GoogleCloudDialogflowV2beta1KnowledgeAnswers struct {
	// Answers: A list of answers from Knowledge Connector.
	Answers []*GoogleCloudDialogflowV2beta1KnowledgeAnswersAnswer `json:"answers,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1KnowledgeAnswersAnswer: An answer from
// Knowledge Connector.
type GoogleCloudDialogflowV2beta1KnowledgeAnswersAnswer struct {
	// Answer: The piece of text from the `source` knowledge base document
	// that answers
	// this conversational query.
	Answer string `json:"answer,omitempty"`

	// FaqQuestion: The corresponding FAQ question if the answer was
	// extracted from a FAQ
	// Document, empty otherwise.
	FaqQuestion string `json:"faqQuestion,omitempty"`

	// MatchConfidence: The system's confidence score that this Knowledge
	// answer is a good match
	// for this conversational query.
	// The range is from 0.0 (completely uncertain) to 1.0 (completely
	// certain).
	// Note: The confidence score is likely to vary somewhat (possibly even
	// for
	// identical requests), as the underlying model is under
	// constant
	// improvement. It may be deprecated in the future. We recommend
	// using
	// `match_confidence_level` which should be generally more stable.
	MatchConfidence float64 `json:"matchConfidence,omitempty"`

	// MatchConfidenceLevel: The system's confidence level that this
	// knowledge answer is a good match
	// for this conversational query.
	// NOTE: The confidence level for a given `<query, answer>` pair may
	// change
	// without notice, as it depends on models that are constantly
	// being
	// improved. However, it will change less frequently than the
	// confidence
	// score below, and should be preferred for referencing the quality of
	// an
	// answer.
	//
	// Possible values:
	//   "MATCH_CONFIDENCE_LEVEL_UNSPECIFIED" - Not specified.
	//   "LOW" - Indicates that the confidence is low.
	//   "MEDIUM" - Indicates our confidence is medium.
	//   "HIGH" - Indicates our confidence is high.
	MatchConfidenceLevel string `json:"matchConfidenceLevel,omitempty"`

	// Source: Indicates which Knowledge Document this answer was extracted
	// from.
	// Format: `projects/<Project ID>/knowledgeBases/<Knowledge
	// Base
	// ID>/documents/<Document ID>`.
	Source string `json:"source,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2beta1KnowledgeOperationMetadata: Metadata in
// google::longrunning::Operation for Knowledge operations.
type GoogleCloudDialogflowV2beta1KnowledgeOperationMetadata struct {
	// State: Required. The current state of this operation.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - State unspecified.
	//   "PENDING" - The operation has been created.
	//   "RUNNING" - The operation is currently running.
	//   "DONE" - The operation is done, either cancelled or completed.
	State string `json:"state,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1LabelConversationResponse: The response
// for
// ConversationDatasets.LabelConversation.
type GoogleCloudDialogflowV2beta1LabelConversationResponse struct {
	// AnnotatedConversationDataset: New annotated conversation dataset
	// created by the labeling task.
	AnnotatedConversationDataset *GoogleCloudDialogflowV2beta1AnnotatedConversationDataset `json:"annotatedConversationDataset,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1OriginalDetectIntentRequest: Represents
// the contents of the original request that was passed to
// the `[Streaming]DetectIntent` call.
type GoogleCloudDialogflowV2beta1OriginalDetectIntentRequest struct {
	// Payload: Optional. This field is set to the value of the
	// `QueryParameters.payload`
	// field passed in the request. Some integrations that query a
	// Dialogflow
	// agent may provide additional information in the payload.
	//
	// In particular for the Telephony Gateway this field has the
	// form:
	// <pre>{
	//  "telephony": {
	//    "caller_id": "+18558363987"
	//  }
	// }</pre>
	// Note: The caller ID field (`caller_id`) will be redacted for
	// Standard
	// Edition agents and populated with the caller ID in
	// [E.164
	// format](https://en.wikipedia.org/wiki/E.164) for Enterprise Edition
	// agents.
	Payload googleapi.RawMessage `json:"payload,omitempty"`

	// Source: The source of this request, e.g., `google`, `facebook`,
	// `slack`. It is set
	// by Dialogflow-owned servers.
	Source string `json:"source,omitempty"`

	// Version: Optional. The version of the protocol used for this
	// request.
	// This field is AoG-specific.
	Version string `json:"version,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1QueryResult: Represents the result of
// conversational query or event processing.
type GoogleCloudDialogflowV2beta1QueryResult struct {
	// Action: The action name from the matched intent.
	Action string `json:"action,omitempty"`

	// AllRequiredParamsPresent: This field is set to:
	//
	// - `false` if the matched intent has required parameters and not all
	// of
	//    the required parameter values have been collected.
	// - `true` if all required parameter values have been collected, or if
	// the
	//    matched intent doesn't contain any required parameters.
	AllRequiredParamsPresent bool `json:"allRequiredParamsPresent,omitempty"`

	// DiagnosticInfo: Free-form diagnostic information for the associated
	// detect intent request.
	// The fields of this data can change without notice, so you should not
	// write
	// code that depends on its structure.
	// The data may contain:
	//
	// - webhook call latency
	// - webhook errors
	DiagnosticInfo googleapi.RawMessage `json:"diagnosticInfo,omitempty"`

	// FulfillmentMessages: The collection of rich messages to present to
	// the user.
	FulfillmentMessages []*GoogleCloudDialogflowV2beta1IntentMessage `json:"fulfillmentMessages,omitempty"`

	// FulfillmentText: The text to be pronounced to the user or shown on
	// the screen.
	// Note: This is a legacy field, `fulfillment_messages` should be
	// preferred.
	FulfillmentText string `json:"fulfillmentText,omitempty"`

	// Intent: The intent that matched the conversational query. Some,
	// not
	// all fields are filled in this message, including but not limited
	// to:
	// `name`, `display_name`, `end_interaction` and `is_fallback`.
	Intent *GoogleCloudDialogflowV2beta1Intent `json:"intent,omitempty"`

	// IntentDetectionConfidence: The intent detection confidence. Values
	// range from 0.0
	// (completely uncertain) to 1.0 (completely certain).
	// This value is for informational purpose only and is only used to
	// help match the best intent within the classification threshold.
	// This value may change for the same end-user expression at any time
	// due to a
	// model retraining or change in implementation.
	// If there are `multiple knowledge_answers` messages, this value is set
	// to
	// the greatest `knowledgeAnswers.match_confidence` value in the list.
	IntentDetectionConfidence float64 `json:"intentDetectionConfidence,omitempty"`

	// KnowledgeAnswers: The result from Knowledge Connector (if any),
	// ordered by decreasing
	// `KnowledgeAnswers.match_confidence`.
	KnowledgeAnswers *GoogleCloudDialogflowV2beta1KnowledgeAnswers `json:"knowledgeAnswers,omitempty"`

	// LanguageCode: The language that was triggered during intent
	// detection.
	// See
	// [Language
	// Support](https://cloud.google.com/dialogflow/docs/reference/
	// language)
	// for a list of the currently supported language codes.
	LanguageCode string `json:"languageCode,omitempty"`

	// OutputContexts: The collection of output contexts. If
	// applicable,
	// `output_contexts.parameters` contains entries with name
	// `<parameter name>.original` containing the original parameter
	// values
	// before the query.
	OutputContexts []*GoogleCloudDialogflowV2beta1Context `json:"outputContexts,omitempty"`

	// Parameters: The collection of extracted parameters.
	Parameters googleapi.RawMessage `json:"parameters,omitempty"`

	// QueryText: The original conversational query text:
	//
	// - If natural language text was provided as input, `query_text`
	// contains
	//   a copy of the input.
	// - If natural language speech audio was provided as input,
	// `query_text`
	//   contains the speech recognition result. If speech recognizer
	// produced
	//   multiple alternatives, a particular one is picked.
	// - If automatic spell correction is enabled, `query_text` will contain
	// the
	//   corrected user input.
	QueryText string `json:"queryText,omitempty"`

	// SentimentAnalysisResult: The sentiment analysis result, which depends
	// on the
	// `sentiment_analysis_request_config` specified in the request.
	SentimentAnalysisResult *GoogleCloudDialogflowV2beta1SentimentAnalysisResult `json:"sentimentAnalysisResult,omitempty"`

	// SpeechRecognitionConfidence: The Speech recognition confidence
	// between 0.0 and 1.0. A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. The default of 0.0 is a sentinel value indicating that
	// confidence
	// was not set.
	//
	// This field is not guaranteed to be accurate or set. In particular
	// this
	// field isn't set for StreamingDetectIntent since the streaming
	// endpoint has
	// separate confidence estimates per portion of the audio
	// in
	// StreamingRecognitionResult.
	SpeechRecognitionConfidence float64 `json:"speechRecognitionConfidence,omitempty"`

	// WebhookPayload: If the query was fulfilled by a webhook call, this
	// field is set to the
	// value of the `payload` field returned in the webhook response.
	WebhookPayload googleapi.RawMessage `json:"webhookPayload,omitempty"`

	// WebhookSource: If the query was fulfilled by a webhook call, this
	// field is set to the
	// value of the `source` field returned in the webhook response.
	WebhookSource string `json:"webhookSource,omitempty"`

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

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

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

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

// GoogleCloudDialogflowV2beta1Sentiment: The sentiment, such as
// positive/negative feeling or association, for a unit
// of analysis, such as the query text.
type GoogleCloudDialogflowV2beta1Sentiment 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 *GoogleCloudDialogflowV2beta1Sentiment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2beta1Sentiment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudDialogflowV2beta1Sentiment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudDialogflowV2beta1Sentiment
	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
}

// GoogleCloudDialogflowV2beta1SentimentAnalysisResult: The result of
// sentiment analysis as configured
// by
// `sentiment_analysis_request_config`.
type GoogleCloudDialogflowV2beta1SentimentAnalysisResult struct {
	// QueryTextSentiment: The sentiment analysis result for `query_text`.
	QueryTextSentiment *GoogleCloudDialogflowV2beta1Sentiment `json:"queryTextSentiment,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1SessionEntityType: Represents a session
// entity type.
//
// Extends or replaces a custom entity type at the user session level
// (we
// refer to the entity types defined at the agent level as "custom
// entity
// types").
//
// Note: session entity types apply to all queries, regardless of the
// language.
type GoogleCloudDialogflowV2beta1SessionEntityType struct {
	// Entities: Required. The collection of entities associated with this
	// session entity
	// type.
	Entities []*GoogleCloudDialogflowV2beta1EntityTypeEntity `json:"entities,omitempty"`

	// EntityOverrideMode: Required. Indicates whether the additional data
	// should override or
	// supplement the custom entity type definition.
	//
	// Possible values:
	//   "ENTITY_OVERRIDE_MODE_UNSPECIFIED" - Not specified. This value
	// should be never used.
	//   "ENTITY_OVERRIDE_MODE_OVERRIDE" - The collection of session
	// entities overrides the collection of entities
	// in the corresponding custom entity type.
	//   "ENTITY_OVERRIDE_MODE_SUPPLEMENT" - The collection of session
	// entities extends the collection of entities in
	// the corresponding custom entity type.
	//
	// Note: Even in this override mode calls to
	// `ListSessionEntityTypes`,
	// `GetSessionEntityType`, `CreateSessionEntityType`
	// and
	// `UpdateSessionEntityType` only return the additional entities added
	// in
	// this session entity type. If you want to get the supplemented
	// list,
	// please call EntityTypes.GetEntityType on the custom entity type
	// and merge.
	EntityOverrideMode string `json:"entityOverrideMode,omitempty"`

	// Name: Required. The unique identifier of this session entity type.
	// Format:
	// `projects/<Project ID>/agent/sessions/<Session
	// ID>/entityTypes/<Entity Type
	// Display Name>`, or
	// `projects/<Project ID>/agent/environments/<Environment
	// ID>/users/<User
	// ID>/sessions/<Session ID>/entityTypes/<Entity Type Display Name>`.
	// If `Environment ID` is not specified, we assume default
	// 'draft'
	// environment. If `User ID` is not specified, we assume default '-'
	// user.
	//
	// `<Entity Type Display Name>` must be the display name of an existing
	// entity
	// type in the same agent that will be overridden or supplemented.
	Name string `json:"name,omitempty"`

	// 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 *GoogleCloudDialogflowV2beta1SessionEntityType) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudDialogflowV2beta1SessionEntityType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudDialogflowV2beta1WebhookRequest: The request message for a
// webhook call.
type GoogleCloudDialogflowV2beta1WebhookRequest struct {
	// AlternativeQueryResults: Alternative query results from
	// KnowledgeService.
	AlternativeQueryResults []*GoogleCloudDialogflowV2beta1QueryResult `json:"alternativeQueryResults,omitempty"`

	// OriginalDetectIntentRequest: Optional. The contents of the original
	// request that was passed to
	// `[Streaming]DetectIntent` call.
	OriginalDetectIntentRequest *GoogleCloudDialogflowV2beta1OriginalDetectIntentRequest `json:"originalDetectIntentRequest,omitempty"`

	// QueryResult: The result of the conversational query or event
	// processing. Contains the
	// same value as `[Streaming]DetectIntentResponse.query_result`.
	QueryResult *GoogleCloudDialogflowV2beta1QueryResult `json:"queryResult,omitempty"`

	// ResponseId: The unique identifier of the response. Contains the same
	// value as
	// `[Streaming]DetectIntentResponse.response_id`.
	ResponseId string `json:"responseId,omitempty"`

	// Session: The unique identifier of detectIntent request session.
	// Can be used to identify end-user inside webhook
	// implementation.
	// Format: `projects/<Project ID>/agent/sessions/<Session ID>`,
	// or
	// `projects/<Project ID>/agent/environments/<Environment
	// ID>/users/<User
	// ID>/sessions/<Session ID>`.
	Session string `json:"session,omitempty"`

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

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

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

// GoogleCloudDialogflowV2beta1WebhookResponse: The response message for
// a webhook call.
//
// This response is validated by the Dialogflow server. If validation
// fails,
// an error will be returned in the QueryResult.diagnostic_info
// field.
// Setting JSON fields to an empty value with the wrong type is a common
// error.
// To avoid this error:
//
// - Use "" for empty strings
// - Use `{}` or `null` for empty objects
// - Use `[]` or `null` for empty arrays
//
// For more information, see the
// [Protocol Buffers
// Language
// Guide](https://developers.google.com/protocol-buffers/docs/pr
// oto3#json).
type GoogleCloudDialogflowV2beta1WebhookResponse struct {
	// EndInteraction: Optional. Indicates that this intent ends an
	// interaction. Some integrations
	// (e.g., Actions on Google or Dialogflow phone gateway) use this
	// information
	// to close interaction with an end user. Default is false.
	EndInteraction bool `json:"endInteraction,omitempty"`

	// FollowupEventInput: Optional. Makes the platform immediately invoke
	// another `DetectIntent` call
	// internally with the specified event as input.
	// When this field is set, Dialogflow ignores the
	// `fulfillment_text`,
	// `fulfillment_messages`, and `payload` fields.
	FollowupEventInput *GoogleCloudDialogflowV2beta1EventInput `json:"followupEventInput,omitempty"`

	// FulfillmentMessages: Optional. The collection of rich messages to
	// present to the user. This
	// value is passed directly to `QueryResult.fulfillment_messages`.
	FulfillmentMessages []*GoogleCloudDialogflowV2beta1IntentMessage `json:"fulfillmentMessages,omitempty"`

	// FulfillmentText: Optional. The text to be shown on the screen. This
	// value is passed directly
	// to `QueryResult.fulfillment_text`.
	FulfillmentText string `json:"fulfillmentText,omitempty"`

	// OutputContexts: Optional. The collection of output contexts. This
	// value is passed directly
	// to `QueryResult.output_contexts`.
	OutputContexts []*GoogleCloudDialogflowV2beta1Context `json:"outputContexts,omitempty"`

	// Payload: Optional. This value is passed directly to
	// `QueryResult.webhook_payload`.
	// See the related `fulfillment_messages[i].payload field`, which may be
	// used
	// as an alternative to this field.
	//
	// This field can be used for Actions on Google responses.
	// It should have a structure similar to the JSON message shown here.
	// For more
	// information, see
	// [Actions on Google
	// Webhook
	// Format](https://developers.google.com/actions/dialogflow/webho
	// ok)
	// <pre>{
	//   "google": {
	//     "expectUserResponse": true,
	//     "richResponse": {
	//       "items": [
	//         {
	//           "simpleResponse": {
	//             "textToSpeech": "this is a simple response"
	//           }
	//         }
	//       ]
	//     }
	//   }
	// }</pre>
	Payload googleapi.RawMessage `json:"payload,omitempty"`

	// SessionEntityTypes: Optional. Additional session entity types to
	// replace or extend developer
	// entity types with. The entity synonyms apply to all languages and
	// persist
	// for the session of this query. Setting the session entity types
	// inside
	// webhook overwrites the session entity types that have been set
	// through
	// `DetectIntentRequest.query_params.session_entity_types`.
	SessionEntityTypes []*GoogleCloudDialogflowV2beta1SessionEntityType `json:"sessionEntityTypes,omitempty"`

	// Source: Optional. This value is passed directly to
	// `QueryResult.webhook_source`.
	Source string `json:"source,omitempty"`

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

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

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

// GoogleLongrunningListOperationsResponse: The response message for
// Operations.ListOperations.
type GoogleLongrunningListOperationsResponse struct {
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Operations: A list of operations that matches the specified filter in
	// the request.
	Operations []*GoogleLongrunningOperation `json:"operations,omitempty"`

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

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

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

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

// GoogleLongrunningOperation: This resource represents a long-running
// operation that is the result of a
// network API call.
type GoogleLongrunningOperation struct {
	// Done: If the value is `false`, it means the operation is still in
	// progress.
	// If `true`, the operation is completed, and either `error` or
	// `response` is
	// available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// Metadata: Service-specific metadata associated with the operation.
	// It typically
	// contains progress information and common metadata such as create
	// time.
	// Some services might not provide such metadata.  Any method that
	// returns a
	// long-running operation should document the metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that
	// originally returns it. If you use the default HTTP mapping,
	// the
	// `name` should be a resource name ending with
	// `operations/{unique_id}`.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success.
	// If the original
	// method returns no data on success, such as `Delete`, the response
	// is
	// `google.protobuf.Empty`.  If the original method is
	// standard
	// `Get`/`Create`/`Update`, the response should be the resource.  For
	// other
	// methods, the response should have the type `XxxResponse`, where
	// `Xxx`
	// is the original method name.  For example, if the original method
	// name
	// is `TakeSnapshot()`, the inferred response type
	// is
	// `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

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

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

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

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

// GoogleProtobufEmpty: A generic empty message that you can re-use to
// avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the
// request
// or the response type of an API method. For instance:
//
//     service Foo {
//       rpc Bar(google.protobuf.Empty) returns
// (google.protobuf.Empty);
//     }
//
// The JSON representation for `Empty` is empty JSON object `{}`.
type GoogleProtobufEmpty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// GoogleRpcStatus: 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). Each `Status` message
// contains
// three pieces of data: error code, error message, and error
// details.
//
// You can find out more about this error model and how to work with it
// in the
// [API Design Guide](https://cloud.google.com/apis/design/errors).
type GoogleRpcStatus 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 *GoogleRpcStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleRpcStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleTypeLatLng: An object representing a latitude/longitude pair.
// This is expressed as a pair
// of doubles representing degrees latitude and degrees longitude.
// Unless
// specified otherwise, this must conform to the
// <a
// href="http://www.unoosa.org/pdf/icg/2012/template/WGS_84.pdf">WGS84
// st
// andard</a>. Values must be within normalized ranges.
type GoogleTypeLatLng struct {
	// Latitude: The latitude in degrees. It must be in the range [-90.0,
	// +90.0].
	Latitude float64 `json:"latitude,omitempty"`

	// Longitude: The longitude in degrees. It must be in the range [-180.0,
	// +180.0].
	Longitude float64 `json:"longitude,omitempty"`

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

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

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

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

// method id "dialogflow.projects.deleteAgent":

type ProjectsDeleteAgentCall struct {
	s          *Service
	parent     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DeleteAgent: Deletes the specified agent.
func (r *ProjectsService) DeleteAgent(parent string) *ProjectsDeleteAgentCall {
	c := &ProjectsDeleteAgentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *ProjectsDeleteAgentCall) Fields(s ...googleapi.Field) *ProjectsDeleteAgentCall {
	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 *ProjectsDeleteAgentCall) Context(ctx context.Context) *ProjectsDeleteAgentCall {
	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 *ProjectsDeleteAgentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDeleteAgentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/agent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.deleteAgent" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsDeleteAgentCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes the specified agent.",
	//   "flatPath": "v2/projects/{projectsId}/agent",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.deleteAgent",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project that the agent to delete is associated with.\nFormat: `projects/\u003cProject ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.getAgent":

type ProjectsGetAgentCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetAgent: Retrieves the specified agent.
func (r *ProjectsService) GetAgent(parent string) *ProjectsGetAgentCall {
	c := &ProjectsGetAgentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *ProjectsGetAgentCall) Fields(s ...googleapi.Field) *ProjectsGetAgentCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsGetAgentCall) IfNoneMatch(entityTag string) *ProjectsGetAgentCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsGetAgentCall) Context(ctx context.Context) *ProjectsGetAgentCall {
	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 *ProjectsGetAgentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetAgentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/agent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.getAgent" call.
// Exactly one of *GoogleCloudDialogflowV2Agent or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Agent.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 *ProjectsGetAgentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Agent, 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 := &GoogleCloudDialogflowV2Agent{
		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": "Retrieves the specified agent.",
	//   "flatPath": "v2/projects/{projectsId}/agent",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.getAgent",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project that the agent to fetch is associated with.\nFormat: `projects/\u003cProject ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Agent"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.setAgent":

type ProjectsSetAgentCall struct {
	s                            *Service
	parent                       string
	googleclouddialogflowv2agent *GoogleCloudDialogflowV2Agent
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// SetAgent: Creates/updates the specified agent.
func (r *ProjectsService) SetAgent(parent string, googleclouddialogflowv2agent *GoogleCloudDialogflowV2Agent) *ProjectsSetAgentCall {
	c := &ProjectsSetAgentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2agent = googleclouddialogflowv2agent
	return c
}

// UpdateMask sets the optional parameter "updateMask": The mask to
// control which fields get updated.
func (c *ProjectsSetAgentCall) UpdateMask(updateMask string) *ProjectsSetAgentCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsSetAgentCall) Fields(s ...googleapi.Field) *ProjectsSetAgentCall {
	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 *ProjectsSetAgentCall) Context(ctx context.Context) *ProjectsSetAgentCall {
	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 *ProjectsSetAgentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsSetAgentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2agent)
	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, "v2/{+parent}/agent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.setAgent" call.
// Exactly one of *GoogleCloudDialogflowV2Agent or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Agent.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 *ProjectsSetAgentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Agent, 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 := &GoogleCloudDialogflowV2Agent{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates/updates the specified agent.",
	//   "flatPath": "v2/projects/{projectsId}/agent",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.setAgent",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project of this agent.\nFormat: `projects/\u003cProject ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Optional. The mask to control which fields get updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2Agent"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Agent"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.export":

type ProjectsAgentExportCall struct {
	s                                         *Service
	parent                                    string
	googleclouddialogflowv2exportagentrequest *GoogleCloudDialogflowV2ExportAgentRequest
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// Export: Exports the specified agent to a ZIP file.
//
// Operation <response: ExportAgentResponse>
func (r *ProjectsAgentService) Export(parent string, googleclouddialogflowv2exportagentrequest *GoogleCloudDialogflowV2ExportAgentRequest) *ProjectsAgentExportCall {
	c := &ProjectsAgentExportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2exportagentrequest = googleclouddialogflowv2exportagentrequest
	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 *ProjectsAgentExportCall) Fields(s ...googleapi.Field) *ProjectsAgentExportCall {
	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 *ProjectsAgentExportCall) Context(ctx context.Context) *ProjectsAgentExportCall {
	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 *ProjectsAgentExportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentExportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2exportagentrequest)
	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, "v2/{+parent}/agent:export")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.export" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentExportCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Exports the specified agent to a ZIP file.\n\nOperation \u003cresponse: ExportAgentResponse\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent:export",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.export",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project that the agent to export is associated with.\nFormat: `projects/\u003cProject ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent:export",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2ExportAgentRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.getFulfillment":

type ProjectsAgentGetFulfillmentCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetFulfillment: Retrieves the fulfillment.
func (r *ProjectsAgentService) GetFulfillment(name string) *ProjectsAgentGetFulfillmentCall {
	c := &ProjectsAgentGetFulfillmentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentGetFulfillmentCall) Fields(s ...googleapi.Field) *ProjectsAgentGetFulfillmentCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentGetFulfillmentCall) IfNoneMatch(entityTag string) *ProjectsAgentGetFulfillmentCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentGetFulfillmentCall) Context(ctx context.Context) *ProjectsAgentGetFulfillmentCall {
	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 *ProjectsAgentGetFulfillmentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentGetFulfillmentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.getFulfillment" call.
// Exactly one of *GoogleCloudDialogflowV2Fulfillment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Fulfillment.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 *ProjectsAgentGetFulfillmentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Fulfillment, 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 := &GoogleCloudDialogflowV2Fulfillment{
		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": "Retrieves the fulfillment.",
	//   "flatPath": "v2/projects/{projectsId}/agent/fulfillment",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.getFulfillment",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the fulfillment.\nFormat: `projects/\u003cProject ID\u003e/agent/fulfillment`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/fulfillment$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Fulfillment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.getValidationResult":

type ProjectsAgentGetValidationResultCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetValidationResult: Gets agent validation result. Agent validation
// is performed during
// training time and is updated automatically when training is
// completed.
func (r *ProjectsAgentService) GetValidationResult(parent string) *ProjectsAgentGetValidationResultCall {
	c := &ProjectsAgentGetValidationResultCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// for which you want a validation result. If not
// specified, the agent's default language is used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/reference/la
// nguage)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentGetValidationResultCall) LanguageCode(languageCode string) *ProjectsAgentGetValidationResultCall {
	c.urlParams_.Set("languageCode", languageCode)
	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 *ProjectsAgentGetValidationResultCall) Fields(s ...googleapi.Field) *ProjectsAgentGetValidationResultCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentGetValidationResultCall) IfNoneMatch(entityTag string) *ProjectsAgentGetValidationResultCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentGetValidationResultCall) Context(ctx context.Context) *ProjectsAgentGetValidationResultCall {
	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 *ProjectsAgentGetValidationResultCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentGetValidationResultCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/agent/validationResult")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.getValidationResult" call.
// Exactly one of *GoogleCloudDialogflowV2ValidationResult or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudDialogflowV2ValidationResult.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 *ProjectsAgentGetValidationResultCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2ValidationResult, 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 := &GoogleCloudDialogflowV2ValidationResult{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets agent validation result. Agent validation is performed during\ntraining time and is updated automatically when training is completed.",
	//   "flatPath": "v2/projects/{projectsId}/agent/validationResult",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.getValidationResult",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "Optional. The language for which you want a validation result. If not\nspecified, the agent's default language is used. [Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The project that the agent is associated with.\nFormat: `projects/\u003cProject ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent/validationResult",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2ValidationResult"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.import":

type ProjectsAgentImportCall struct {
	s                                         *Service
	parent                                    string
	googleclouddialogflowv2importagentrequest *GoogleCloudDialogflowV2ImportAgentRequest
	urlParams_                                gensupport.URLParams
	ctx_                                      context.Context
	header_                                   http.Header
}

// Import: Imports the specified agent from a ZIP file.
//
// Uploads new intents and entity types without deleting the existing
// ones.
// Intents and entity types with the same name are replaced with the
// new
// versions from ImportAgentRequest.
//
// Operation <response: google.protobuf.Empty>
func (r *ProjectsAgentService) Import(parent string, googleclouddialogflowv2importagentrequest *GoogleCloudDialogflowV2ImportAgentRequest) *ProjectsAgentImportCall {
	c := &ProjectsAgentImportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2importagentrequest = googleclouddialogflowv2importagentrequest
	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 *ProjectsAgentImportCall) Fields(s ...googleapi.Field) *ProjectsAgentImportCall {
	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 *ProjectsAgentImportCall) Context(ctx context.Context) *ProjectsAgentImportCall {
	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 *ProjectsAgentImportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentImportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2importagentrequest)
	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, "v2/{+parent}/agent:import")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.import" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentImportCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Imports the specified agent from a ZIP file.\n\nUploads new intents and entity types without deleting the existing ones.\nIntents and entity types with the same name are replaced with the new\nversions from ImportAgentRequest.\n\nOperation \u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent:import",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.import",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project that the agent to import is associated with.\nFormat: `projects/\u003cProject ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent:import",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2ImportAgentRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.restore":

type ProjectsAgentRestoreCall struct {
	s                                          *Service
	parent                                     string
	googleclouddialogflowv2restoreagentrequest *GoogleCloudDialogflowV2RestoreAgentRequest
	urlParams_                                 gensupport.URLParams
	ctx_                                       context.Context
	header_                                    http.Header
}

// Restore: Restores the specified agent from a ZIP file.
//
// Replaces the current agent version with a new one. All the intents
// and
// entity types in the older version are deleted.
//
// Operation <response: google.protobuf.Empty>
func (r *ProjectsAgentService) Restore(parent string, googleclouddialogflowv2restoreagentrequest *GoogleCloudDialogflowV2RestoreAgentRequest) *ProjectsAgentRestoreCall {
	c := &ProjectsAgentRestoreCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2restoreagentrequest = googleclouddialogflowv2restoreagentrequest
	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 *ProjectsAgentRestoreCall) Fields(s ...googleapi.Field) *ProjectsAgentRestoreCall {
	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 *ProjectsAgentRestoreCall) Context(ctx context.Context) *ProjectsAgentRestoreCall {
	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 *ProjectsAgentRestoreCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentRestoreCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2restoreagentrequest)
	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, "v2/{+parent}/agent:restore")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.restore" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentRestoreCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Restores the specified agent from a ZIP file.\n\nReplaces the current agent version with a new one. All the intents and\nentity types in the older version are deleted.\n\nOperation \u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent:restore",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.restore",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project that the agent to restore is associated with.\nFormat: `projects/\u003cProject ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent:restore",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2RestoreAgentRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.search":

type ProjectsAgentSearchCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Search: Returns the list of agents.
//
// Since there is at most one conversational agent per project, this
// method is
// useful primarily for listing all agents across projects the caller
// has
// access to. One can achieve that with a wildcard project collection id
// "-".
// Refer to
// [List
// Sub-Collections](https://cloud.google.com/apis/design/design_pat
// terns#list_sub-collections).
func (r *ProjectsAgentService) Search(parent string) *ProjectsAgentSearchCall {
	c := &ProjectsAgentSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of items to return in a single page. By
// default 100 and at most 1000.
func (c *ProjectsAgentSearchCall) PageSize(pageSize int64) *ProjectsAgentSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous list request.
func (c *ProjectsAgentSearchCall) PageToken(pageToken string) *ProjectsAgentSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsAgentSearchCall) Fields(s ...googleapi.Field) *ProjectsAgentSearchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentSearchCall) IfNoneMatch(entityTag string) *ProjectsAgentSearchCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentSearchCall) Context(ctx context.Context) *ProjectsAgentSearchCall {
	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 *ProjectsAgentSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/agent:search")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.search" call.
// Exactly one of *GoogleCloudDialogflowV2SearchAgentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2SearchAgentsResponse.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 *ProjectsAgentSearchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2SearchAgentsResponse, 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 := &GoogleCloudDialogflowV2SearchAgentsResponse{
		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": "Returns the list of agents.\n\nSince there is at most one conversational agent per project, this method is\nuseful primarily for listing all agents across projects the caller has\naccess to. One can achieve that with a wildcard project collection id \"-\".\nRefer to [List\nSub-Collections](https://cloud.google.com/apis/design/design_patterns#list_sub-collections).",
	//   "flatPath": "v2/projects/{projectsId}/agent:search",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.search",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of items to return in a single page. By\ndefault 100 and at most 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The next_page_token value returned from a previous list request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The project to list agents from.\nFormat: `projects/\u003cProject ID or '-'\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent:search",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2SearchAgentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsAgentSearchCall) Pages(ctx context.Context, f func(*GoogleCloudDialogflowV2SearchAgentsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dialogflow.projects.agent.train":

type ProjectsAgentTrainCall struct {
	s                                        *Service
	parent                                   string
	googleclouddialogflowv2trainagentrequest *GoogleCloudDialogflowV2TrainAgentRequest
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// Train: Trains the specified agent.
//
// Operation <response: google.protobuf.Empty>
func (r *ProjectsAgentService) Train(parent string, googleclouddialogflowv2trainagentrequest *GoogleCloudDialogflowV2TrainAgentRequest) *ProjectsAgentTrainCall {
	c := &ProjectsAgentTrainCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2trainagentrequest = googleclouddialogflowv2trainagentrequest
	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 *ProjectsAgentTrainCall) Fields(s ...googleapi.Field) *ProjectsAgentTrainCall {
	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 *ProjectsAgentTrainCall) Context(ctx context.Context) *ProjectsAgentTrainCall {
	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 *ProjectsAgentTrainCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentTrainCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2trainagentrequest)
	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, "v2/{+parent}/agent:train")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.train" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentTrainCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Trains the specified agent.\n\nOperation \u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent:train",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.train",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project that the agent to train is associated with.\nFormat: `projects/\u003cProject ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/agent:train",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2TrainAgentRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.updateFulfillment":

type ProjectsAgentUpdateFulfillmentCall struct {
	s                                  *Service
	nameid                             string
	googleclouddialogflowv2fulfillment *GoogleCloudDialogflowV2Fulfillment
	urlParams_                         gensupport.URLParams
	ctx_                               context.Context
	header_                            http.Header
}

// UpdateFulfillment: Updates the fulfillment.
func (r *ProjectsAgentService) UpdateFulfillment(nameid string, googleclouddialogflowv2fulfillment *GoogleCloudDialogflowV2Fulfillment) *ProjectsAgentUpdateFulfillmentCall {
	c := &ProjectsAgentUpdateFulfillmentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.googleclouddialogflowv2fulfillment = googleclouddialogflowv2fulfillment
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. The
// mask to control which fields get updated. If the mask is not
// present, all fields will be updated.
func (c *ProjectsAgentUpdateFulfillmentCall) UpdateMask(updateMask string) *ProjectsAgentUpdateFulfillmentCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsAgentUpdateFulfillmentCall) Fields(s ...googleapi.Field) *ProjectsAgentUpdateFulfillmentCall {
	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 *ProjectsAgentUpdateFulfillmentCall) Context(ctx context.Context) *ProjectsAgentUpdateFulfillmentCall {
	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 *ProjectsAgentUpdateFulfillmentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentUpdateFulfillmentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2fulfillment)
	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, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.nameid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.updateFulfillment" call.
// Exactly one of *GoogleCloudDialogflowV2Fulfillment or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Fulfillment.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 *ProjectsAgentUpdateFulfillmentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Fulfillment, 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 := &GoogleCloudDialogflowV2Fulfillment{
		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": "Updates the fulfillment.",
	//   "flatPath": "v2/projects/{projectsId}/agent/fulfillment",
	//   "httpMethod": "PATCH",
	//   "id": "dialogflow.projects.agent.updateFulfillment",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The unique identifier of the fulfillment.\nFormat: `projects/\u003cProject ID\u003e/agent/fulfillment`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/fulfillment$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Required. The mask to control which fields get updated. If the mask is not\npresent, all fields will be updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2Fulfillment"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Fulfillment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.batchDelete":

type ProjectsAgentEntityTypesBatchDeleteCall struct {
	s                                                    *Service
	parent                                               string
	googleclouddialogflowv2batchdeleteentitytypesrequest *GoogleCloudDialogflowV2BatchDeleteEntityTypesRequest
	urlParams_                                           gensupport.URLParams
	ctx_                                                 context.Context
	header_                                              http.Header
}

// BatchDelete: Deletes entity types in the specified agent.
//
// Operation <response: google.protobuf.Empty>
func (r *ProjectsAgentEntityTypesService) BatchDelete(parent string, googleclouddialogflowv2batchdeleteentitytypesrequest *GoogleCloudDialogflowV2BatchDeleteEntityTypesRequest) *ProjectsAgentEntityTypesBatchDeleteCall {
	c := &ProjectsAgentEntityTypesBatchDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2batchdeleteentitytypesrequest = googleclouddialogflowv2batchdeleteentitytypesrequest
	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 *ProjectsAgentEntityTypesBatchDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesBatchDeleteCall {
	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 *ProjectsAgentEntityTypesBatchDeleteCall) Context(ctx context.Context) *ProjectsAgentEntityTypesBatchDeleteCall {
	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 *ProjectsAgentEntityTypesBatchDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesBatchDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2batchdeleteentitytypesrequest)
	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, "v2/{+parent}/entityTypes:batchDelete")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.batchDelete" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentEntityTypesBatchDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Deletes entity types in the specified agent.\n\nOperation \u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes:batchDelete",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.entityTypes.batchDelete",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the agent to delete all entities types for. Format:\n`projects/\u003cProject ID\u003e/agent`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entityTypes:batchDelete",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2BatchDeleteEntityTypesRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.batchUpdate":

type ProjectsAgentEntityTypesBatchUpdateCall struct {
	s                                                    *Service
	parent                                               string
	googleclouddialogflowv2batchupdateentitytypesrequest *GoogleCloudDialogflowV2BatchUpdateEntityTypesRequest
	urlParams_                                           gensupport.URLParams
	ctx_                                                 context.Context
	header_                                              http.Header
}

// BatchUpdate: Updates/Creates multiple entity types in the specified
// agent.
//
// Operation <response: BatchUpdateEntityTypesResponse>
func (r *ProjectsAgentEntityTypesService) BatchUpdate(parent string, googleclouddialogflowv2batchupdateentitytypesrequest *GoogleCloudDialogflowV2BatchUpdateEntityTypesRequest) *ProjectsAgentEntityTypesBatchUpdateCall {
	c := &ProjectsAgentEntityTypesBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2batchupdateentitytypesrequest = googleclouddialogflowv2batchupdateentitytypesrequest
	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 *ProjectsAgentEntityTypesBatchUpdateCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesBatchUpdateCall {
	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 *ProjectsAgentEntityTypesBatchUpdateCall) Context(ctx context.Context) *ProjectsAgentEntityTypesBatchUpdateCall {
	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 *ProjectsAgentEntityTypesBatchUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2batchupdateentitytypesrequest)
	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, "v2/{+parent}/entityTypes:batchUpdate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.batchUpdate" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentEntityTypesBatchUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Updates/Creates multiple entity types in the specified agent.\n\nOperation \u003cresponse: BatchUpdateEntityTypesResponse\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.entityTypes.batchUpdate",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the agent to update or create entity types in.\nFormat: `projects/\u003cProject ID\u003e/agent`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entityTypes:batchUpdate",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2BatchUpdateEntityTypesRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.create":

type ProjectsAgentEntityTypesCreateCall struct {
	s                                 *Service
	parent                            string
	googleclouddialogflowv2entitytype *GoogleCloudDialogflowV2EntityType
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// Create: Creates an entity type in the specified agent.
func (r *ProjectsAgentEntityTypesService) Create(parent string, googleclouddialogflowv2entitytype *GoogleCloudDialogflowV2EntityType) *ProjectsAgentEntityTypesCreateCall {
	c := &ProjectsAgentEntityTypesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2entitytype = googleclouddialogflowv2entitytype
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// of entity synonyms defined in `entity_type`. If not
// specified, the agent's default language is
// used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/refere
// nce/language)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentEntityTypesCreateCall) LanguageCode(languageCode string) *ProjectsAgentEntityTypesCreateCall {
	c.urlParams_.Set("languageCode", languageCode)
	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 *ProjectsAgentEntityTypesCreateCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesCreateCall {
	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 *ProjectsAgentEntityTypesCreateCall) Context(ctx context.Context) *ProjectsAgentEntityTypesCreateCall {
	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 *ProjectsAgentEntityTypesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2entitytype)
	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, "v2/{+parent}/entityTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.create" call.
// Exactly one of *GoogleCloudDialogflowV2EntityType or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2EntityType.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 *ProjectsAgentEntityTypesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2EntityType, 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 := &GoogleCloudDialogflowV2EntityType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an entity type in the specified agent.",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.entityTypes.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "Optional. The language of entity synonyms defined in `entity_type`. If not\nspecified, the agent's default language is used.\n[Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The agent to create a entity type for.\nFormat: `projects/\u003cProject ID\u003e/agent`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entityTypes",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2EntityType"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2EntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.delete":

type ProjectsAgentEntityTypesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified entity type.
func (r *ProjectsAgentEntityTypesService) Delete(name string) *ProjectsAgentEntityTypesDeleteCall {
	c := &ProjectsAgentEntityTypesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentEntityTypesDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesDeleteCall {
	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 *ProjectsAgentEntityTypesDeleteCall) Context(ctx context.Context) *ProjectsAgentEntityTypesDeleteCall {
	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 *ProjectsAgentEntityTypesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsAgentEntityTypesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes the specified entity type.",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes/{entityTypesId}",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.agent.entityTypes.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the entity type to delete.\nFormat: `projects/\u003cProject ID\u003e/agent/entityTypes/\u003cEntityType ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.get":

type ProjectsAgentEntityTypesGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified entity type.
func (r *ProjectsAgentEntityTypesService) Get(name string) *ProjectsAgentEntityTypesGetCall {
	c := &ProjectsAgentEntityTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// to retrieve entity synonyms for. If not specified,
// the agent's default language is
// used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/refere
// nce/language)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentEntityTypesGetCall) LanguageCode(languageCode string) *ProjectsAgentEntityTypesGetCall {
	c.urlParams_.Set("languageCode", languageCode)
	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 *ProjectsAgentEntityTypesGetCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentEntityTypesGetCall) IfNoneMatch(entityTag string) *ProjectsAgentEntityTypesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentEntityTypesGetCall) Context(ctx context.Context) *ProjectsAgentEntityTypesGetCall {
	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 *ProjectsAgentEntityTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.get" call.
// Exactly one of *GoogleCloudDialogflowV2EntityType or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2EntityType.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 *ProjectsAgentEntityTypesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2EntityType, 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 := &GoogleCloudDialogflowV2EntityType{
		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": "Retrieves the specified entity type.",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes/{entityTypesId}",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.entityTypes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "Optional. The language to retrieve entity synonyms for. If not specified,\nthe agent's default language is used.\n[Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The name of the entity type.\nFormat: `projects/\u003cProject ID\u003e/agent/entityTypes/\u003cEntityType ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2EntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.list":

type ProjectsAgentEntityTypesListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Returns the list of all entity types in the specified agent.
func (r *ProjectsAgentEntityTypesService) List(parent string) *ProjectsAgentEntityTypesListCall {
	c := &ProjectsAgentEntityTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// to list entity synonyms for. If not specified,
// the agent's default language is
// used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/refere
// nce/language)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentEntityTypesListCall) LanguageCode(languageCode string) *ProjectsAgentEntityTypesListCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of items to return in a single page. By
// default 100 and at most 1000.
func (c *ProjectsAgentEntityTypesListCall) PageSize(pageSize int64) *ProjectsAgentEntityTypesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous list request.
func (c *ProjectsAgentEntityTypesListCall) PageToken(pageToken string) *ProjectsAgentEntityTypesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsAgentEntityTypesListCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentEntityTypesListCall) IfNoneMatch(entityTag string) *ProjectsAgentEntityTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentEntityTypesListCall) Context(ctx context.Context) *ProjectsAgentEntityTypesListCall {
	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 *ProjectsAgentEntityTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/entityTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.list" call.
// Exactly one of *GoogleCloudDialogflowV2ListEntityTypesResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2ListEntityTypesResponse.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 *ProjectsAgentEntityTypesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2ListEntityTypesResponse, 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 := &GoogleCloudDialogflowV2ListEntityTypesResponse{
		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": "Returns the list of all entity types in the specified agent.",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.entityTypes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "Optional. The language to list entity synonyms for. If not specified,\nthe agent's default language is used.\n[Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The maximum number of items to return in a single page. By\ndefault 100 and at most 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The next_page_token value returned from a previous list request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The agent to list all entity types from.\nFormat: `projects/\u003cProject ID\u003e/agent`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entityTypes",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2ListEntityTypesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsAgentEntityTypesListCall) Pages(ctx context.Context, f func(*GoogleCloudDialogflowV2ListEntityTypesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dialogflow.projects.agent.entityTypes.patch":

type ProjectsAgentEntityTypesPatchCall struct {
	s                                 *Service
	nameid                            string
	googleclouddialogflowv2entitytype *GoogleCloudDialogflowV2EntityType
	urlParams_                        gensupport.URLParams
	ctx_                              context.Context
	header_                           http.Header
}

// Patch: Updates the specified entity type.
func (r *ProjectsAgentEntityTypesService) Patch(nameid string, googleclouddialogflowv2entitytype *GoogleCloudDialogflowV2EntityType) *ProjectsAgentEntityTypesPatchCall {
	c := &ProjectsAgentEntityTypesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.googleclouddialogflowv2entitytype = googleclouddialogflowv2entitytype
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// of entity synonyms defined in `entity_type`. If not
// specified, the agent's default language is
// used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/refere
// nce/language)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentEntityTypesPatchCall) LanguageCode(languageCode string) *ProjectsAgentEntityTypesPatchCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// UpdateMask sets the optional parameter "updateMask": The mask to
// control which fields get updated.
func (c *ProjectsAgentEntityTypesPatchCall) UpdateMask(updateMask string) *ProjectsAgentEntityTypesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsAgentEntityTypesPatchCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesPatchCall {
	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 *ProjectsAgentEntityTypesPatchCall) Context(ctx context.Context) *ProjectsAgentEntityTypesPatchCall {
	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 *ProjectsAgentEntityTypesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2entitytype)
	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, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.nameid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.patch" call.
// Exactly one of *GoogleCloudDialogflowV2EntityType or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2EntityType.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 *ProjectsAgentEntityTypesPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2EntityType, 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 := &GoogleCloudDialogflowV2EntityType{
		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": "Updates the specified entity type.",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes/{entityTypesId}",
	//   "httpMethod": "PATCH",
	//   "id": "dialogflow.projects.agent.entityTypes.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "languageCode": {
	//       "description": "Optional. The language of entity synonyms defined in `entity_type`. If not\nspecified, the agent's default language is used.\n[Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The unique identifier of the entity type.\nRequired for EntityTypes.UpdateEntityType and\nEntityTypes.BatchUpdateEntityTypes methods.\nFormat: `projects/\u003cProject ID\u003e/agent/entityTypes/\u003cEntity Type ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Optional. The mask to control which fields get updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2EntityType"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2EntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.entities.batchCreate":

type ProjectsAgentEntityTypesEntitiesBatchCreateCall struct {
	s                                                 *Service
	parent                                            string
	googleclouddialogflowv2batchcreateentitiesrequest *GoogleCloudDialogflowV2BatchCreateEntitiesRequest
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// BatchCreate: Creates multiple new entities in the specified entity
// type.
//
// Operation <response: google.protobuf.Empty>
func (r *ProjectsAgentEntityTypesEntitiesService) BatchCreate(parent string, googleclouddialogflowv2batchcreateentitiesrequest *GoogleCloudDialogflowV2BatchCreateEntitiesRequest) *ProjectsAgentEntityTypesEntitiesBatchCreateCall {
	c := &ProjectsAgentEntityTypesEntitiesBatchCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2batchcreateentitiesrequest = googleclouddialogflowv2batchcreateentitiesrequest
	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 *ProjectsAgentEntityTypesEntitiesBatchCreateCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesEntitiesBatchCreateCall {
	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 *ProjectsAgentEntityTypesEntitiesBatchCreateCall) Context(ctx context.Context) *ProjectsAgentEntityTypesEntitiesBatchCreateCall {
	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 *ProjectsAgentEntityTypesEntitiesBatchCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesEntitiesBatchCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2batchcreateentitiesrequest)
	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, "v2/{+parent}/entities:batchCreate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.entities.batchCreate" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentEntityTypesEntitiesBatchCreateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates multiple new entities in the specified entity type.\n\nOperation \u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes/{entityTypesId}/entities:batchCreate",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.entityTypes.entities.batchCreate",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the entity type to create entities in. Format:\n`projects/\u003cProject ID\u003e/agent/entityTypes/\u003cEntity Type ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entities:batchCreate",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2BatchCreateEntitiesRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.entities.batchDelete":

type ProjectsAgentEntityTypesEntitiesBatchDeleteCall struct {
	s                                                 *Service
	parent                                            string
	googleclouddialogflowv2batchdeleteentitiesrequest *GoogleCloudDialogflowV2BatchDeleteEntitiesRequest
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// BatchDelete: Deletes entities in the specified entity
// type.
//
//
// Operation <response: google.protobuf.Empty>
func (r *ProjectsAgentEntityTypesEntitiesService) BatchDelete(parent string, googleclouddialogflowv2batchdeleteentitiesrequest *GoogleCloudDialogflowV2BatchDeleteEntitiesRequest) *ProjectsAgentEntityTypesEntitiesBatchDeleteCall {
	c := &ProjectsAgentEntityTypesEntitiesBatchDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2batchdeleteentitiesrequest = googleclouddialogflowv2batchdeleteentitiesrequest
	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 *ProjectsAgentEntityTypesEntitiesBatchDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesEntitiesBatchDeleteCall {
	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 *ProjectsAgentEntityTypesEntitiesBatchDeleteCall) Context(ctx context.Context) *ProjectsAgentEntityTypesEntitiesBatchDeleteCall {
	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 *ProjectsAgentEntityTypesEntitiesBatchDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesEntitiesBatchDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2batchdeleteentitiesrequest)
	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, "v2/{+parent}/entities:batchDelete")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.entities.batchDelete" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentEntityTypesEntitiesBatchDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Deletes entities in the specified entity type.\n\n\nOperation \u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes/{entityTypesId}/entities:batchDelete",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.entityTypes.entities.batchDelete",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the entity type to delete entries for. Format:\n`projects/\u003cProject ID\u003e/agent/entityTypes/\u003cEntity Type ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entities:batchDelete",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2BatchDeleteEntitiesRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.entityTypes.entities.batchUpdate":

type ProjectsAgentEntityTypesEntitiesBatchUpdateCall struct {
	s                                                 *Service
	parent                                            string
	googleclouddialogflowv2batchupdateentitiesrequest *GoogleCloudDialogflowV2BatchUpdateEntitiesRequest
	urlParams_                                        gensupport.URLParams
	ctx_                                              context.Context
	header_                                           http.Header
}

// BatchUpdate: Updates or creates multiple entities in the specified
// entity type. This
// method does not affect entities in the entity type that aren't
// explicitly
// specified in the request.
//
//
// Operation <response: google.protobuf.Empty>
func (r *ProjectsAgentEntityTypesEntitiesService) BatchUpdate(parent string, googleclouddialogflowv2batchupdateentitiesrequest *GoogleCloudDialogflowV2BatchUpdateEntitiesRequest) *ProjectsAgentEntityTypesEntitiesBatchUpdateCall {
	c := &ProjectsAgentEntityTypesEntitiesBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2batchupdateentitiesrequest = googleclouddialogflowv2batchupdateentitiesrequest
	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 *ProjectsAgentEntityTypesEntitiesBatchUpdateCall) Fields(s ...googleapi.Field) *ProjectsAgentEntityTypesEntitiesBatchUpdateCall {
	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 *ProjectsAgentEntityTypesEntitiesBatchUpdateCall) Context(ctx context.Context) *ProjectsAgentEntityTypesEntitiesBatchUpdateCall {
	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 *ProjectsAgentEntityTypesEntitiesBatchUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEntityTypesEntitiesBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2batchupdateentitiesrequest)
	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, "v2/{+parent}/entities:batchUpdate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.entityTypes.entities.batchUpdate" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentEntityTypesEntitiesBatchUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Updates or creates multiple entities in the specified entity type. This\nmethod does not affect entities in the entity type that aren't explicitly\nspecified in the request.\n\n\nOperation \u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent/entityTypes/{entityTypesId}/entities:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.entityTypes.entities.batchUpdate",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the entity type to update or create entities in.\nFormat: `projects/\u003cProject ID\u003e/agent/entityTypes/\u003cEntity Type ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entities:batchUpdate",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2BatchUpdateEntitiesRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.deleteContexts":

type ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall struct {
	s          *Service
	parent     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DeleteContexts: Deletes all active contexts in the specified session.
func (r *ProjectsAgentEnvironmentsUsersSessionsService) DeleteContexts(parent string) *ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/contexts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.deleteContexts" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsAgentEnvironmentsUsersSessionsDeleteContextsCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes all active contexts in the specified session.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/contexts",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.deleteContexts",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the session to delete all contexts from. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or `projects/\u003cProject\nID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser ID\u003e/sessions/\u003cSession\nID\u003e`.\nIf `Environment ID` is not specified we assume default 'draft' environment.\nIf `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/contexts",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.detectIntent":

type ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall struct {
	s                                          *Service
	sessionid                                  string
	googleclouddialogflowv2detectintentrequest *GoogleCloudDialogflowV2DetectIntentRequest
	urlParams_                                 gensupport.URLParams
	ctx_                                       context.Context
	header_                                    http.Header
}

// DetectIntent: Processes a natural language query and returns
// structured, actionable data
// as a result. This method is not idempotent, because it may cause
// contexts
// and session entity types to be updated, which in turn might
// affect
// results of future queries.
func (r *ProjectsAgentEnvironmentsUsersSessionsService) DetectIntent(sessionid string, googleclouddialogflowv2detectintentrequest *GoogleCloudDialogflowV2DetectIntentRequest) *ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.sessionid = sessionid
	c.googleclouddialogflowv2detectintentrequest = googleclouddialogflowv2detectintentrequest
	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 *ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2detectintentrequest)
	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, "v2/{+session}:detectIntent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"session": c.sessionid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.detectIntent" call.
// Exactly one of *GoogleCloudDialogflowV2DetectIntentResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2DetectIntentResponse.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 *ProjectsAgentEnvironmentsUsersSessionsDetectIntentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2DetectIntentResponse, 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 := &GoogleCloudDialogflowV2DetectIntentResponse{
		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": "Processes a natural language query and returns structured, actionable data\nas a result. This method is not idempotent, because it may cause contexts\nand session entity types to be updated, which in turn might affect\nresults of future queries.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}:detectIntent",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.detectIntent",
	//   "parameterOrder": [
	//     "session"
	//   ],
	//   "parameters": {
	//     "session": {
	//       "description": "Required. The name of the session this query is sent to. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e`, or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e`. If `Environment ID` is not specified, we assume\ndefault 'draft' environment. If `User ID` is not specified, we are using\n\"-\". It's up to the API caller to choose an appropriate `Session ID` and\n`User Id`. They can be a random number or some type of user and session\nidentifiers (preferably hashed). The length of the `Session ID` and\n`User ID` must not exceed 36 characters.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+session}:detectIntent",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2DetectIntentRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2DetectIntentResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.contexts.create":

type ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall struct {
	s                              *Service
	parent                         string
	googleclouddialogflowv2context *GoogleCloudDialogflowV2Context
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Create: Creates a context.
//
// If the specified context already exists, overrides the context.
func (r *ProjectsAgentEnvironmentsUsersSessionsContextsService) Create(parent string, googleclouddialogflowv2context *GoogleCloudDialogflowV2Context) *ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2context = googleclouddialogflowv2context
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2context)
	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, "v2/{+parent}/contexts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.contexts.create" call.
// Exactly one of *GoogleCloudDialogflowV2Context or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Context.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 *ProjectsAgentEnvironmentsUsersSessionsContextsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Context, 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 := &GoogleCloudDialogflowV2Context{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a context.\n\nIf the specified context already exists, overrides the context.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/contexts",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.contexts.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The session to create a context for.\nFormat: `projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/contexts",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.contexts.delete":

type ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified context.
func (r *ProjectsAgentEnvironmentsUsersSessionsContextsService) Delete(name string) *ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.contexts.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsAgentEnvironmentsUsersSessionsContextsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes the specified context.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/contexts/{contextsId}",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.contexts.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the context to delete. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`\nor `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+/contexts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.contexts.get":

type ProjectsAgentEnvironmentsUsersSessionsContextsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified context.
func (r *ProjectsAgentEnvironmentsUsersSessionsContextsService) Get(name string) *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsContextsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall) IfNoneMatch(entityTag string) *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.contexts.get" call.
// Exactly one of *GoogleCloudDialogflowV2Context or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Context.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 *ProjectsAgentEnvironmentsUsersSessionsContextsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Context, 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 := &GoogleCloudDialogflowV2Context{
		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": "Retrieves the specified context.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/contexts/{contextsId}",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.contexts.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the context. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`\nor `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+/contexts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.contexts.list":

type ProjectsAgentEnvironmentsUsersSessionsContextsListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Returns the list of all contexts in the specified session.
func (r *ProjectsAgentEnvironmentsUsersSessionsContextsService) List(parent string) *ProjectsAgentEnvironmentsUsersSessionsContextsListCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsContextsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of items to return in a single page. By
// default 100 and at most 1000.
func (c *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) PageSize(pageSize int64) *ProjectsAgentEnvironmentsUsersSessionsContextsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous list request.
func (c *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) PageToken(pageToken string) *ProjectsAgentEnvironmentsUsersSessionsContextsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsContextsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) IfNoneMatch(entityTag string) *ProjectsAgentEnvironmentsUsersSessionsContextsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsContextsListCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/contexts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.contexts.list" call.
// Exactly one of *GoogleCloudDialogflowV2ListContextsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2ListContextsResponse.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 *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2ListContextsResponse, 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 := &GoogleCloudDialogflowV2ListContextsResponse{
		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": "Returns the list of all contexts in the specified session.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/contexts",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.contexts.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of items to return in a single page. By\ndefault 100 and at most 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The next_page_token value returned from a previous list request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The session to list all contexts from.\nFormat: `projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/contexts",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2ListContextsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsAgentEnvironmentsUsersSessionsContextsListCall) Pages(ctx context.Context, f func(*GoogleCloudDialogflowV2ListContextsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dialogflow.projects.agent.environments.users.sessions.contexts.patch":

type ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall struct {
	s                              *Service
	nameid                         string
	googleclouddialogflowv2context *GoogleCloudDialogflowV2Context
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Patch: Updates the specified context.
func (r *ProjectsAgentEnvironmentsUsersSessionsContextsService) Patch(nameid string, googleclouddialogflowv2context *GoogleCloudDialogflowV2Context) *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.googleclouddialogflowv2context = googleclouddialogflowv2context
	return c
}

// UpdateMask sets the optional parameter "updateMask": The mask to
// control which fields get updated.
func (c *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall) UpdateMask(updateMask string) *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2context)
	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, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.nameid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.contexts.patch" call.
// Exactly one of *GoogleCloudDialogflowV2Context or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Context.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 *ProjectsAgentEnvironmentsUsersSessionsContextsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Context, 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 := &GoogleCloudDialogflowV2Context{
		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": "Updates the specified context.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/contexts/{contextsId}",
	//   "httpMethod": "PATCH",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.contexts.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The unique identifier of the context. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`,\nor `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`.\n\nThe `Context ID` is always converted to lowercase, may only contain\ncharacters in a-zA-Z0-9_-% and may be at most 250 bytes long.\n\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.\n\nThe following context names are reserved for internal use by Dialogflow.\nYou should not use these contexts or create contexts with these names:\n\n* `__system_counters__`\n* `*_id_dialog_context`\n* `*_dialog_params_size`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+/contexts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Optional. The mask to control which fields get updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.entityTypes.create":

type ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall struct {
	s                                        *Service
	parent                                   string
	googleclouddialogflowv2sessionentitytype *GoogleCloudDialogflowV2SessionEntityType
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// Create: Creates a session entity type.
//
// If the specified session entity type already exists, overrides the
// session
// entity type.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentEnvironmentsUsersSessionsEntityTypesService) Create(parent string, googleclouddialogflowv2sessionentitytype *GoogleCloudDialogflowV2SessionEntityType) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2sessionentitytype = googleclouddialogflowv2sessionentitytype
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2sessionentitytype)
	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, "v2/{+parent}/entityTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.entityTypes.create" call.
// Exactly one of *GoogleCloudDialogflowV2SessionEntityType or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2SessionEntityType.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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2SessionEntityType, 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 := &GoogleCloudDialogflowV2SessionEntityType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a session entity type.\n\nIf the specified session entity type already exists, overrides the session\nentity type.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/entityTypes",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.entityTypes.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The session to create a session entity type for.\nFormat: `projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser ID\u003e/\nsessions/\u003cSession ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entityTypes",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.entityTypes.delete":

type ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified session entity type.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentEnvironmentsUsersSessionsEntityTypesService) Delete(name string) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.entityTypes.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes the specified session entity type.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/entityTypes/{entityTypesId}",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.entityTypes.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the entity type to delete. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type\nDisplay Name\u003e` or `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment\nID\u003e/users/\u003cUser ID\u003e/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type Display\nName\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.entityTypes.get":

type ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified session entity type.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentEnvironmentsUsersSessionsEntityTypesService) Get(name string) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall) IfNoneMatch(entityTag string) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.entityTypes.get" call.
// Exactly one of *GoogleCloudDialogflowV2SessionEntityType or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2SessionEntityType.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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2SessionEntityType, 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 := &GoogleCloudDialogflowV2SessionEntityType{
		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": "Retrieves the specified session entity type.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/entityTypes/{entityTypesId}",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.entityTypes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the session entity type. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type\nDisplay Name\u003e` or `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment\nID\u003e/users/\u003cUser ID\u003e/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type Display\nName\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.environments.users.sessions.entityTypes.list":

type ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Returns the list of all session entity types in the specified
// session.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentEnvironmentsUsersSessionsEntityTypesService) List(parent string) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of items to return in a single page. By
// default 100 and at most 1000.
func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) PageSize(pageSize int64) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous list request.
func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) PageToken(pageToken string) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) IfNoneMatch(entityTag string) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/entityTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.entityTypes.list" call.
// Exactly one of *GoogleCloudDialogflowV2ListSessionEntityTypesResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudDialogflowV2ListSessionEntityTypesResponse.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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2ListSessionEntityTypesResponse, 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 := &GoogleCloudDialogflowV2ListSessionEntityTypesResponse{
		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": "Returns the list of all session entity types in the specified session.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/entityTypes",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.entityTypes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of items to return in a single page. By\ndefault 100 and at most 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The next_page_token value returned from a previous list request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The session to list all session entity types from.\nFormat: `projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser ID\u003e/\nsessions/\u003cSession ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entityTypes",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2ListSessionEntityTypesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesListCall) Pages(ctx context.Context, f func(*GoogleCloudDialogflowV2ListSessionEntityTypesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dialogflow.projects.agent.environments.users.sessions.entityTypes.patch":

type ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall struct {
	s                                        *Service
	nameid                                   string
	googleclouddialogflowv2sessionentitytype *GoogleCloudDialogflowV2SessionEntityType
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// Patch: Updates the specified session entity type.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentEnvironmentsUsersSessionsEntityTypesService) Patch(nameid string, googleclouddialogflowv2sessionentitytype *GoogleCloudDialogflowV2SessionEntityType) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall {
	c := &ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.googleclouddialogflowv2sessionentitytype = googleclouddialogflowv2sessionentitytype
	return c
}

// UpdateMask sets the optional parameter "updateMask": The mask to
// control which fields get updated.
func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall) UpdateMask(updateMask string) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall) Fields(s ...googleapi.Field) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall) Context(ctx context.Context) *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall {
	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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2sessionentitytype)
	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, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.nameid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.environments.users.sessions.entityTypes.patch" call.
// Exactly one of *GoogleCloudDialogflowV2SessionEntityType or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2SessionEntityType.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 *ProjectsAgentEnvironmentsUsersSessionsEntityTypesPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2SessionEntityType, 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 := &GoogleCloudDialogflowV2SessionEntityType{
		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": "Updates the specified session entity type.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/environments/{environmentsId}/users/{usersId}/sessions/{sessionsId}/entityTypes/{entityTypesId}",
	//   "httpMethod": "PATCH",
	//   "id": "dialogflow.projects.agent.environments.users.sessions.entityTypes.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The unique identifier of this session entity type. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type\nDisplay Name\u003e`, or `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment\nID\u003e/users/\u003cUser ID\u003e/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type Display\nName\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.\n\n`\u003cEntity Type Display Name\u003e` must be the display name of an existing entity\ntype in the same agent that will be overridden or supplemented.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/environments/[^/]+/users/[^/]+/sessions/[^/]+/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Optional. The mask to control which fields get updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.intents.batchDelete":

type ProjectsAgentIntentsBatchDeleteCall struct {
	s                                                *Service
	parent                                           string
	googleclouddialogflowv2batchdeleteintentsrequest *GoogleCloudDialogflowV2BatchDeleteIntentsRequest
	urlParams_                                       gensupport.URLParams
	ctx_                                             context.Context
	header_                                          http.Header
}

// BatchDelete: Deletes intents in the specified agent.
//
// Operation <response: google.protobuf.Empty>
func (r *ProjectsAgentIntentsService) BatchDelete(parent string, googleclouddialogflowv2batchdeleteintentsrequest *GoogleCloudDialogflowV2BatchDeleteIntentsRequest) *ProjectsAgentIntentsBatchDeleteCall {
	c := &ProjectsAgentIntentsBatchDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2batchdeleteintentsrequest = googleclouddialogflowv2batchdeleteintentsrequest
	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 *ProjectsAgentIntentsBatchDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentIntentsBatchDeleteCall {
	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 *ProjectsAgentIntentsBatchDeleteCall) Context(ctx context.Context) *ProjectsAgentIntentsBatchDeleteCall {
	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 *ProjectsAgentIntentsBatchDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentIntentsBatchDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2batchdeleteintentsrequest)
	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, "v2/{+parent}/intents:batchDelete")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.intents.batchDelete" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentIntentsBatchDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Deletes intents in the specified agent.\n\nOperation \u003cresponse: google.protobuf.Empty\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent/intents:batchDelete",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.intents.batchDelete",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the agent to delete all entities types for. Format:\n`projects/\u003cProject ID\u003e/agent`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/intents:batchDelete",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2BatchDeleteIntentsRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.intents.batchUpdate":

type ProjectsAgentIntentsBatchUpdateCall struct {
	s                                                *Service
	parent                                           string
	googleclouddialogflowv2batchupdateintentsrequest *GoogleCloudDialogflowV2BatchUpdateIntentsRequest
	urlParams_                                       gensupport.URLParams
	ctx_                                             context.Context
	header_                                          http.Header
}

// BatchUpdate: Updates/Creates multiple intents in the specified
// agent.
//
// Operation <response: BatchUpdateIntentsResponse>
func (r *ProjectsAgentIntentsService) BatchUpdate(parent string, googleclouddialogflowv2batchupdateintentsrequest *GoogleCloudDialogflowV2BatchUpdateIntentsRequest) *ProjectsAgentIntentsBatchUpdateCall {
	c := &ProjectsAgentIntentsBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2batchupdateintentsrequest = googleclouddialogflowv2batchupdateintentsrequest
	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 *ProjectsAgentIntentsBatchUpdateCall) Fields(s ...googleapi.Field) *ProjectsAgentIntentsBatchUpdateCall {
	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 *ProjectsAgentIntentsBatchUpdateCall) Context(ctx context.Context) *ProjectsAgentIntentsBatchUpdateCall {
	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 *ProjectsAgentIntentsBatchUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentIntentsBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2batchupdateintentsrequest)
	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, "v2/{+parent}/intents:batchUpdate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.intents.batchUpdate" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsAgentIntentsBatchUpdateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		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": "Updates/Creates multiple intents in the specified agent.\n\nOperation \u003cresponse: BatchUpdateIntentsResponse\u003e",
	//   "flatPath": "v2/projects/{projectsId}/agent/intents:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.intents.batchUpdate",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the agent to update or create intents in.\nFormat: `projects/\u003cProject ID\u003e/agent`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/intents:batchUpdate",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2BatchUpdateIntentsRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.intents.create":

type ProjectsAgentIntentsCreateCall struct {
	s                             *Service
	parent                        string
	googleclouddialogflowv2intent *GoogleCloudDialogflowV2Intent
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Create: Creates an intent in the specified agent.
func (r *ProjectsAgentIntentsService) Create(parent string, googleclouddialogflowv2intent *GoogleCloudDialogflowV2Intent) *ProjectsAgentIntentsCreateCall {
	c := &ProjectsAgentIntentsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2intent = googleclouddialogflowv2intent
	return c
}

// IntentView sets the optional parameter "intentView": The resource
// view to apply to the returned intent.
//
// Possible values:
//   "INTENT_VIEW_UNSPECIFIED"
//   "INTENT_VIEW_FULL"
func (c *ProjectsAgentIntentsCreateCall) IntentView(intentView string) *ProjectsAgentIntentsCreateCall {
	c.urlParams_.Set("intentView", intentView)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// of training phrases, parameters and rich messages
// defined in `intent`. If not specified, the agent's default language
// is
// used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/reference/la
// nguage)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentIntentsCreateCall) LanguageCode(languageCode string) *ProjectsAgentIntentsCreateCall {
	c.urlParams_.Set("languageCode", languageCode)
	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 *ProjectsAgentIntentsCreateCall) Fields(s ...googleapi.Field) *ProjectsAgentIntentsCreateCall {
	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 *ProjectsAgentIntentsCreateCall) Context(ctx context.Context) *ProjectsAgentIntentsCreateCall {
	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 *ProjectsAgentIntentsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentIntentsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2intent)
	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, "v2/{+parent}/intents")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.intents.create" call.
// Exactly one of *GoogleCloudDialogflowV2Intent or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Intent.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 *ProjectsAgentIntentsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Intent, 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 := &GoogleCloudDialogflowV2Intent{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates an intent in the specified agent.",
	//   "flatPath": "v2/projects/{projectsId}/agent/intents",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.intents.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "intentView": {
	//       "description": "Optional. The resource view to apply to the returned intent.",
	//       "enum": [
	//         "INTENT_VIEW_UNSPECIFIED",
	//         "INTENT_VIEW_FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCode": {
	//       "description": "Optional. The language of training phrases, parameters and rich messages\ndefined in `intent`. If not specified, the agent's default language is\nused. [Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The agent to create a intent for.\nFormat: `projects/\u003cProject ID\u003e/agent`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/intents",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2Intent"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Intent"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.intents.delete":

type ProjectsAgentIntentsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified intent and its direct or indirect
// followup intents.
func (r *ProjectsAgentIntentsService) Delete(name string) *ProjectsAgentIntentsDeleteCall {
	c := &ProjectsAgentIntentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentIntentsDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentIntentsDeleteCall {
	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 *ProjectsAgentIntentsDeleteCall) Context(ctx context.Context) *ProjectsAgentIntentsDeleteCall {
	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 *ProjectsAgentIntentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentIntentsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.intents.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsAgentIntentsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes the specified intent and its direct or indirect followup intents.",
	//   "flatPath": "v2/projects/{projectsId}/agent/intents/{intentsId}",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.agent.intents.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the intent to delete. If this intent has direct or\nindirect followup intents, we also delete them.\nFormat: `projects/\u003cProject ID\u003e/agent/intents/\u003cIntent ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/intents/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.intents.get":

type ProjectsAgentIntentsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified intent.
func (r *ProjectsAgentIntentsService) Get(name string) *ProjectsAgentIntentsGetCall {
	c := &ProjectsAgentIntentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// IntentView sets the optional parameter "intentView": The resource
// view to apply to the returned intent.
//
// Possible values:
//   "INTENT_VIEW_UNSPECIFIED"
//   "INTENT_VIEW_FULL"
func (c *ProjectsAgentIntentsGetCall) IntentView(intentView string) *ProjectsAgentIntentsGetCall {
	c.urlParams_.Set("intentView", intentView)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// to retrieve training phrases, parameters and rich
// messages for. If not specified, the agent's default language is
// used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/refere
// nce/language)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentIntentsGetCall) LanguageCode(languageCode string) *ProjectsAgentIntentsGetCall {
	c.urlParams_.Set("languageCode", languageCode)
	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 *ProjectsAgentIntentsGetCall) Fields(s ...googleapi.Field) *ProjectsAgentIntentsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentIntentsGetCall) IfNoneMatch(entityTag string) *ProjectsAgentIntentsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentIntentsGetCall) Context(ctx context.Context) *ProjectsAgentIntentsGetCall {
	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 *ProjectsAgentIntentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentIntentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.intents.get" call.
// Exactly one of *GoogleCloudDialogflowV2Intent or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Intent.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 *ProjectsAgentIntentsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Intent, 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 := &GoogleCloudDialogflowV2Intent{
		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": "Retrieves the specified intent.",
	//   "flatPath": "v2/projects/{projectsId}/agent/intents/{intentsId}",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.intents.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "intentView": {
	//       "description": "Optional. The resource view to apply to the returned intent.",
	//       "enum": [
	//         "INTENT_VIEW_UNSPECIFIED",
	//         "INTENT_VIEW_FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCode": {
	//       "description": "Optional. The language to retrieve training phrases, parameters and rich\nmessages for. If not specified, the agent's default language is used.\n[Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Required. The name of the intent.\nFormat: `projects/\u003cProject ID\u003e/agent/intents/\u003cIntent ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/intents/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Intent"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.intents.list":

type ProjectsAgentIntentsListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Returns the list of all intents in the specified agent.
func (r *ProjectsAgentIntentsService) List(parent string) *ProjectsAgentIntentsListCall {
	c := &ProjectsAgentIntentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// IntentView sets the optional parameter "intentView": The resource
// view to apply to the returned intent.
//
// Possible values:
//   "INTENT_VIEW_UNSPECIFIED"
//   "INTENT_VIEW_FULL"
func (c *ProjectsAgentIntentsListCall) IntentView(intentView string) *ProjectsAgentIntentsListCall {
	c.urlParams_.Set("intentView", intentView)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// to list training phrases, parameters and rich
// messages for. If not specified, the agent's default language is
// used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/refere
// nce/language)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentIntentsListCall) LanguageCode(languageCode string) *ProjectsAgentIntentsListCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of items to return in a single page. By
// default 100 and at most 1000.
func (c *ProjectsAgentIntentsListCall) PageSize(pageSize int64) *ProjectsAgentIntentsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous list request.
func (c *ProjectsAgentIntentsListCall) PageToken(pageToken string) *ProjectsAgentIntentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsAgentIntentsListCall) Fields(s ...googleapi.Field) *ProjectsAgentIntentsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentIntentsListCall) IfNoneMatch(entityTag string) *ProjectsAgentIntentsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentIntentsListCall) Context(ctx context.Context) *ProjectsAgentIntentsListCall {
	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 *ProjectsAgentIntentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentIntentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/intents")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.intents.list" call.
// Exactly one of *GoogleCloudDialogflowV2ListIntentsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2ListIntentsResponse.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 *ProjectsAgentIntentsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2ListIntentsResponse, 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 := &GoogleCloudDialogflowV2ListIntentsResponse{
		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": "Returns the list of all intents in the specified agent.",
	//   "flatPath": "v2/projects/{projectsId}/agent/intents",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.intents.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "intentView": {
	//       "description": "Optional. The resource view to apply to the returned intent.",
	//       "enum": [
	//         "INTENT_VIEW_UNSPECIFIED",
	//         "INTENT_VIEW_FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCode": {
	//       "description": "Optional. The language to list training phrases, parameters and rich\nmessages for. If not specified, the agent's default language is used.\n[Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The maximum number of items to return in a single page. By\ndefault 100 and at most 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The next_page_token value returned from a previous list request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The agent to list all intents from.\nFormat: `projects/\u003cProject ID\u003e/agent`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/intents",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2ListIntentsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsAgentIntentsListCall) Pages(ctx context.Context, f func(*GoogleCloudDialogflowV2ListIntentsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dialogflow.projects.agent.intents.patch":

type ProjectsAgentIntentsPatchCall struct {
	s                             *Service
	nameid                        string
	googleclouddialogflowv2intent *GoogleCloudDialogflowV2Intent
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Patch: Updates the specified intent.
func (r *ProjectsAgentIntentsService) Patch(nameid string, googleclouddialogflowv2intent *GoogleCloudDialogflowV2Intent) *ProjectsAgentIntentsPatchCall {
	c := &ProjectsAgentIntentsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.googleclouddialogflowv2intent = googleclouddialogflowv2intent
	return c
}

// IntentView sets the optional parameter "intentView": The resource
// view to apply to the returned intent.
//
// Possible values:
//   "INTENT_VIEW_UNSPECIFIED"
//   "INTENT_VIEW_FULL"
func (c *ProjectsAgentIntentsPatchCall) IntentView(intentView string) *ProjectsAgentIntentsPatchCall {
	c.urlParams_.Set("intentView", intentView)
	return c
}

// LanguageCode sets the optional parameter "languageCode": The language
// of training phrases, parameters and rich messages
// defined in `intent`. If not specified, the agent's default language
// is
// used.
// [Many
// languages](https://cloud.google.com/dialogflow/docs/reference/la
// nguage)
// are supported. Note: languages must be enabled in the agent before
// they can
// be used.
func (c *ProjectsAgentIntentsPatchCall) LanguageCode(languageCode string) *ProjectsAgentIntentsPatchCall {
	c.urlParams_.Set("languageCode", languageCode)
	return c
}

// UpdateMask sets the optional parameter "updateMask": The mask to
// control which fields get updated.
func (c *ProjectsAgentIntentsPatchCall) UpdateMask(updateMask string) *ProjectsAgentIntentsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsAgentIntentsPatchCall) Fields(s ...googleapi.Field) *ProjectsAgentIntentsPatchCall {
	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 *ProjectsAgentIntentsPatchCall) Context(ctx context.Context) *ProjectsAgentIntentsPatchCall {
	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 *ProjectsAgentIntentsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentIntentsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2intent)
	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, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.nameid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.intents.patch" call.
// Exactly one of *GoogleCloudDialogflowV2Intent or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Intent.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 *ProjectsAgentIntentsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Intent, 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 := &GoogleCloudDialogflowV2Intent{
		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": "Updates the specified intent.",
	//   "flatPath": "v2/projects/{projectsId}/agent/intents/{intentsId}",
	//   "httpMethod": "PATCH",
	//   "id": "dialogflow.projects.agent.intents.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "intentView": {
	//       "description": "Optional. The resource view to apply to the returned intent.",
	//       "enum": [
	//         "INTENT_VIEW_UNSPECIFIED",
	//         "INTENT_VIEW_FULL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "languageCode": {
	//       "description": "Optional. The language of training phrases, parameters and rich messages\ndefined in `intent`. If not specified, the agent's default language is\nused. [Many\nlanguages](https://cloud.google.com/dialogflow/docs/reference/language)\nare supported. Note: languages must be enabled in the agent before they can\nbe used.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The unique identifier of this intent.\nRequired for Intents.UpdateIntent and Intents.BatchUpdateIntents\nmethods.\nFormat: `projects/\u003cProject ID\u003e/agent/intents/\u003cIntent ID\u003e`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/intents/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Optional. The mask to control which fields get updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2Intent"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Intent"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.deleteContexts":

type ProjectsAgentSessionsDeleteContextsCall struct {
	s          *Service
	parent     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// DeleteContexts: Deletes all active contexts in the specified session.
func (r *ProjectsAgentSessionsService) DeleteContexts(parent string) *ProjectsAgentSessionsDeleteContextsCall {
	c := &ProjectsAgentSessionsDeleteContextsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	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 *ProjectsAgentSessionsDeleteContextsCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsDeleteContextsCall {
	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 *ProjectsAgentSessionsDeleteContextsCall) Context(ctx context.Context) *ProjectsAgentSessionsDeleteContextsCall {
	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 *ProjectsAgentSessionsDeleteContextsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsDeleteContextsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/contexts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.deleteContexts" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsAgentSessionsDeleteContextsCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes all active contexts in the specified session.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/contexts",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.agent.sessions.deleteContexts",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the session to delete all contexts from. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or `projects/\u003cProject\nID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser ID\u003e/sessions/\u003cSession\nID\u003e`.\nIf `Environment ID` is not specified we assume default 'draft' environment.\nIf `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/contexts",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.detectIntent":

type ProjectsAgentSessionsDetectIntentCall struct {
	s                                          *Service
	sessionid                                  string
	googleclouddialogflowv2detectintentrequest *GoogleCloudDialogflowV2DetectIntentRequest
	urlParams_                                 gensupport.URLParams
	ctx_                                       context.Context
	header_                                    http.Header
}

// DetectIntent: Processes a natural language query and returns
// structured, actionable data
// as a result. This method is not idempotent, because it may cause
// contexts
// and session entity types to be updated, which in turn might
// affect
// results of future queries.
func (r *ProjectsAgentSessionsService) DetectIntent(sessionid string, googleclouddialogflowv2detectintentrequest *GoogleCloudDialogflowV2DetectIntentRequest) *ProjectsAgentSessionsDetectIntentCall {
	c := &ProjectsAgentSessionsDetectIntentCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.sessionid = sessionid
	c.googleclouddialogflowv2detectintentrequest = googleclouddialogflowv2detectintentrequest
	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 *ProjectsAgentSessionsDetectIntentCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsDetectIntentCall {
	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 *ProjectsAgentSessionsDetectIntentCall) Context(ctx context.Context) *ProjectsAgentSessionsDetectIntentCall {
	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 *ProjectsAgentSessionsDetectIntentCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsDetectIntentCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2detectintentrequest)
	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, "v2/{+session}:detectIntent")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"session": c.sessionid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.detectIntent" call.
// Exactly one of *GoogleCloudDialogflowV2DetectIntentResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2DetectIntentResponse.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 *ProjectsAgentSessionsDetectIntentCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2DetectIntentResponse, 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 := &GoogleCloudDialogflowV2DetectIntentResponse{
		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": "Processes a natural language query and returns structured, actionable data\nas a result. This method is not idempotent, because it may cause contexts\nand session entity types to be updated, which in turn might affect\nresults of future queries.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}:detectIntent",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.sessions.detectIntent",
	//   "parameterOrder": [
	//     "session"
	//   ],
	//   "parameters": {
	//     "session": {
	//       "description": "Required. The name of the session this query is sent to. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e`, or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e`. If `Environment ID` is not specified, we assume\ndefault 'draft' environment. If `User ID` is not specified, we are using\n\"-\". It's up to the API caller to choose an appropriate `Session ID` and\n`User Id`. They can be a random number or some type of user and session\nidentifiers (preferably hashed). The length of the `Session ID` and\n`User ID` must not exceed 36 characters.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+session}:detectIntent",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2DetectIntentRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2DetectIntentResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.contexts.create":

type ProjectsAgentSessionsContextsCreateCall struct {
	s                              *Service
	parent                         string
	googleclouddialogflowv2context *GoogleCloudDialogflowV2Context
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Create: Creates a context.
//
// If the specified context already exists, overrides the context.
func (r *ProjectsAgentSessionsContextsService) Create(parent string, googleclouddialogflowv2context *GoogleCloudDialogflowV2Context) *ProjectsAgentSessionsContextsCreateCall {
	c := &ProjectsAgentSessionsContextsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2context = googleclouddialogflowv2context
	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 *ProjectsAgentSessionsContextsCreateCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsContextsCreateCall {
	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 *ProjectsAgentSessionsContextsCreateCall) Context(ctx context.Context) *ProjectsAgentSessionsContextsCreateCall {
	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 *ProjectsAgentSessionsContextsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsContextsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2context)
	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, "v2/{+parent}/contexts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.contexts.create" call.
// Exactly one of *GoogleCloudDialogflowV2Context or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Context.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 *ProjectsAgentSessionsContextsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Context, 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 := &GoogleCloudDialogflowV2Context{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a context.\n\nIf the specified context already exists, overrides the context.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/contexts",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.sessions.contexts.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The session to create a context for.\nFormat: `projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/contexts",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.contexts.delete":

type ProjectsAgentSessionsContextsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified context.
func (r *ProjectsAgentSessionsContextsService) Delete(name string) *ProjectsAgentSessionsContextsDeleteCall {
	c := &ProjectsAgentSessionsContextsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentSessionsContextsDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsContextsDeleteCall {
	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 *ProjectsAgentSessionsContextsDeleteCall) Context(ctx context.Context) *ProjectsAgentSessionsContextsDeleteCall {
	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 *ProjectsAgentSessionsContextsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsContextsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.contexts.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsAgentSessionsContextsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes the specified context.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/contexts/{contextsId}",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.agent.sessions.contexts.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the context to delete. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`\nor `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+/contexts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.contexts.get":

type ProjectsAgentSessionsContextsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified context.
func (r *ProjectsAgentSessionsContextsService) Get(name string) *ProjectsAgentSessionsContextsGetCall {
	c := &ProjectsAgentSessionsContextsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentSessionsContextsGetCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsContextsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentSessionsContextsGetCall) IfNoneMatch(entityTag string) *ProjectsAgentSessionsContextsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentSessionsContextsGetCall) Context(ctx context.Context) *ProjectsAgentSessionsContextsGetCall {
	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 *ProjectsAgentSessionsContextsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsContextsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.contexts.get" call.
// Exactly one of *GoogleCloudDialogflowV2Context or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Context.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 *ProjectsAgentSessionsContextsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Context, 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 := &GoogleCloudDialogflowV2Context{
		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": "Retrieves the specified context.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/contexts/{contextsId}",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.sessions.contexts.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the context. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`\nor `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+/contexts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.contexts.list":

type ProjectsAgentSessionsContextsListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Returns the list of all contexts in the specified session.
func (r *ProjectsAgentSessionsContextsService) List(parent string) *ProjectsAgentSessionsContextsListCall {
	c := &ProjectsAgentSessionsContextsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of items to return in a single page. By
// default 100 and at most 1000.
func (c *ProjectsAgentSessionsContextsListCall) PageSize(pageSize int64) *ProjectsAgentSessionsContextsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous list request.
func (c *ProjectsAgentSessionsContextsListCall) PageToken(pageToken string) *ProjectsAgentSessionsContextsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsAgentSessionsContextsListCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsContextsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentSessionsContextsListCall) IfNoneMatch(entityTag string) *ProjectsAgentSessionsContextsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentSessionsContextsListCall) Context(ctx context.Context) *ProjectsAgentSessionsContextsListCall {
	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 *ProjectsAgentSessionsContextsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsContextsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/contexts")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.contexts.list" call.
// Exactly one of *GoogleCloudDialogflowV2ListContextsResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2ListContextsResponse.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 *ProjectsAgentSessionsContextsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2ListContextsResponse, 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 := &GoogleCloudDialogflowV2ListContextsResponse{
		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": "Returns the list of all contexts in the specified session.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/contexts",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.sessions.contexts.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of items to return in a single page. By\ndefault 100 and at most 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The next_page_token value returned from a previous list request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The session to list all contexts from.\nFormat: `projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/contexts",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2ListContextsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsAgentSessionsContextsListCall) Pages(ctx context.Context, f func(*GoogleCloudDialogflowV2ListContextsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dialogflow.projects.agent.sessions.contexts.patch":

type ProjectsAgentSessionsContextsPatchCall struct {
	s                              *Service
	nameid                         string
	googleclouddialogflowv2context *GoogleCloudDialogflowV2Context
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Patch: Updates the specified context.
func (r *ProjectsAgentSessionsContextsService) Patch(nameid string, googleclouddialogflowv2context *GoogleCloudDialogflowV2Context) *ProjectsAgentSessionsContextsPatchCall {
	c := &ProjectsAgentSessionsContextsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.googleclouddialogflowv2context = googleclouddialogflowv2context
	return c
}

// UpdateMask sets the optional parameter "updateMask": The mask to
// control which fields get updated.
func (c *ProjectsAgentSessionsContextsPatchCall) UpdateMask(updateMask string) *ProjectsAgentSessionsContextsPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsAgentSessionsContextsPatchCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsContextsPatchCall {
	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 *ProjectsAgentSessionsContextsPatchCall) Context(ctx context.Context) *ProjectsAgentSessionsContextsPatchCall {
	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 *ProjectsAgentSessionsContextsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsContextsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2context)
	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, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.nameid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.contexts.patch" call.
// Exactly one of *GoogleCloudDialogflowV2Context or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GoogleCloudDialogflowV2Context.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 *ProjectsAgentSessionsContextsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2Context, 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 := &GoogleCloudDialogflowV2Context{
		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": "Updates the specified context.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/contexts/{contextsId}",
	//   "httpMethod": "PATCH",
	//   "id": "dialogflow.projects.agent.sessions.contexts.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The unique identifier of the context. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`,\nor `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser\nID\u003e/sessions/\u003cSession ID\u003e/contexts/\u003cContext ID\u003e`.\n\nThe `Context ID` is always converted to lowercase, may only contain\ncharacters in a-zA-Z0-9_-% and may be at most 250 bytes long.\n\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.\n\nThe following context names are reserved for internal use by Dialogflow.\nYou should not use these contexts or create contexts with these names:\n\n* `__system_counters__`\n* `*_id_dialog_context`\n* `*_dialog_params_size`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+/contexts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Optional. The mask to control which fields get updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2Context"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.entityTypes.create":

type ProjectsAgentSessionsEntityTypesCreateCall struct {
	s                                        *Service
	parent                                   string
	googleclouddialogflowv2sessionentitytype *GoogleCloudDialogflowV2SessionEntityType
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// Create: Creates a session entity type.
//
// If the specified session entity type already exists, overrides the
// session
// entity type.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentSessionsEntityTypesService) Create(parent string, googleclouddialogflowv2sessionentitytype *GoogleCloudDialogflowV2SessionEntityType) *ProjectsAgentSessionsEntityTypesCreateCall {
	c := &ProjectsAgentSessionsEntityTypesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googleclouddialogflowv2sessionentitytype = googleclouddialogflowv2sessionentitytype
	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 *ProjectsAgentSessionsEntityTypesCreateCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsEntityTypesCreateCall {
	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 *ProjectsAgentSessionsEntityTypesCreateCall) Context(ctx context.Context) *ProjectsAgentSessionsEntityTypesCreateCall {
	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 *ProjectsAgentSessionsEntityTypesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsEntityTypesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2sessionentitytype)
	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, "v2/{+parent}/entityTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.entityTypes.create" call.
// Exactly one of *GoogleCloudDialogflowV2SessionEntityType or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2SessionEntityType.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 *ProjectsAgentSessionsEntityTypesCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2SessionEntityType, 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 := &GoogleCloudDialogflowV2SessionEntityType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a session entity type.\n\nIf the specified session entity type already exists, overrides the session\nentity type.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/entityTypes",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.agent.sessions.entityTypes.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The session to create a session entity type for.\nFormat: `projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser ID\u003e/\nsessions/\u003cSession ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entityTypes",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.entityTypes.delete":

type ProjectsAgentSessionsEntityTypesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the specified session entity type.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentSessionsEntityTypesService) Delete(name string) *ProjectsAgentSessionsEntityTypesDeleteCall {
	c := &ProjectsAgentSessionsEntityTypesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentSessionsEntityTypesDeleteCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsEntityTypesDeleteCall {
	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 *ProjectsAgentSessionsEntityTypesDeleteCall) Context(ctx context.Context) *ProjectsAgentSessionsEntityTypesDeleteCall {
	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 *ProjectsAgentSessionsEntityTypesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsEntityTypesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.entityTypes.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsAgentSessionsEntityTypesDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes the specified session entity type.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/entityTypes/{entityTypesId}",
	//   "httpMethod": "DELETE",
	//   "id": "dialogflow.projects.agent.sessions.entityTypes.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the entity type to delete. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type\nDisplay Name\u003e` or `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment\nID\u003e/users/\u003cUser ID\u003e/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type Display\nName\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.entityTypes.get":

type ProjectsAgentSessionsEntityTypesGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Retrieves the specified session entity type.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentSessionsEntityTypesService) Get(name string) *ProjectsAgentSessionsEntityTypesGetCall {
	c := &ProjectsAgentSessionsEntityTypesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsAgentSessionsEntityTypesGetCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsEntityTypesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentSessionsEntityTypesGetCall) IfNoneMatch(entityTag string) *ProjectsAgentSessionsEntityTypesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentSessionsEntityTypesGetCall) Context(ctx context.Context) *ProjectsAgentSessionsEntityTypesGetCall {
	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 *ProjectsAgentSessionsEntityTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsEntityTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.entityTypes.get" call.
// Exactly one of *GoogleCloudDialogflowV2SessionEntityType or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2SessionEntityType.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 *ProjectsAgentSessionsEntityTypesGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2SessionEntityType, 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 := &GoogleCloudDialogflowV2SessionEntityType{
		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": "Retrieves the specified session entity type.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/entityTypes/{entityTypesId}",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.sessions.entityTypes.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The name of the session entity type. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type\nDisplay Name\u003e` or `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment\nID\u003e/users/\u003cUser ID\u003e/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type Display\nName\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.agent.sessions.entityTypes.list":

type ProjectsAgentSessionsEntityTypesListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Returns the list of all session entity types in the specified
// session.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentSessionsEntityTypesService) List(parent string) *ProjectsAgentSessionsEntityTypesListCall {
	c := &ProjectsAgentSessionsEntityTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of items to return in a single page. By
// default 100 and at most 1000.
func (c *ProjectsAgentSessionsEntityTypesListCall) PageSize(pageSize int64) *ProjectsAgentSessionsEntityTypesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous list request.
func (c *ProjectsAgentSessionsEntityTypesListCall) PageToken(pageToken string) *ProjectsAgentSessionsEntityTypesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsAgentSessionsEntityTypesListCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsEntityTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsAgentSessionsEntityTypesListCall) IfNoneMatch(entityTag string) *ProjectsAgentSessionsEntityTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsAgentSessionsEntityTypesListCall) Context(ctx context.Context) *ProjectsAgentSessionsEntityTypesListCall {
	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 *ProjectsAgentSessionsEntityTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsEntityTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+parent}/entityTypes")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.entityTypes.list" call.
// Exactly one of *GoogleCloudDialogflowV2ListSessionEntityTypesResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudDialogflowV2ListSessionEntityTypesResponse.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 *ProjectsAgentSessionsEntityTypesListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2ListSessionEntityTypesResponse, 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 := &GoogleCloudDialogflowV2ListSessionEntityTypesResponse{
		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": "Returns the list of all session entity types in the specified session.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/entityTypes",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.agent.sessions.entityTypes.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of items to return in a single page. By\ndefault 100 and at most 1000.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The next_page_token value returned from a previous list request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The session to list all session entity types from.\nFormat: `projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e` or\n`projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment ID\u003e/users/\u003cUser ID\u003e/\nsessions/\u003cSession ID\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+parent}/entityTypes",
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2ListSessionEntityTypesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsAgentSessionsEntityTypesListCall) Pages(ctx context.Context, f func(*GoogleCloudDialogflowV2ListSessionEntityTypesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dialogflow.projects.agent.sessions.entityTypes.patch":

type ProjectsAgentSessionsEntityTypesPatchCall struct {
	s                                        *Service
	nameid                                   string
	googleclouddialogflowv2sessionentitytype *GoogleCloudDialogflowV2SessionEntityType
	urlParams_                               gensupport.URLParams
	ctx_                                     context.Context
	header_                                  http.Header
}

// Patch: Updates the specified session entity type.
//
// This method doesn't work with Google Assistant integration.
// Contact Dialogflow support if you need to use session entities
// with Google Assistant integration.
func (r *ProjectsAgentSessionsEntityTypesService) Patch(nameid string, googleclouddialogflowv2sessionentitytype *GoogleCloudDialogflowV2SessionEntityType) *ProjectsAgentSessionsEntityTypesPatchCall {
	c := &ProjectsAgentSessionsEntityTypesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	c.googleclouddialogflowv2sessionentitytype = googleclouddialogflowv2sessionentitytype
	return c
}

// UpdateMask sets the optional parameter "updateMask": The mask to
// control which fields get updated.
func (c *ProjectsAgentSessionsEntityTypesPatchCall) UpdateMask(updateMask string) *ProjectsAgentSessionsEntityTypesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	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 *ProjectsAgentSessionsEntityTypesPatchCall) Fields(s ...googleapi.Field) *ProjectsAgentSessionsEntityTypesPatchCall {
	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 *ProjectsAgentSessionsEntityTypesPatchCall) Context(ctx context.Context) *ProjectsAgentSessionsEntityTypesPatchCall {
	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 *ProjectsAgentSessionsEntityTypesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsAgentSessionsEntityTypesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	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.googleclouddialogflowv2sessionentitytype)
	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, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.nameid,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.agent.sessions.entityTypes.patch" call.
// Exactly one of *GoogleCloudDialogflowV2SessionEntityType or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleCloudDialogflowV2SessionEntityType.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 *ProjectsAgentSessionsEntityTypesPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudDialogflowV2SessionEntityType, 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 := &GoogleCloudDialogflowV2SessionEntityType{
		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": "Updates the specified session entity type.\n\nThis method doesn't work with Google Assistant integration.\nContact Dialogflow support if you need to use session entities\nwith Google Assistant integration.",
	//   "flatPath": "v2/projects/{projectsId}/agent/sessions/{sessionsId}/entityTypes/{entityTypesId}",
	//   "httpMethod": "PATCH",
	//   "id": "dialogflow.projects.agent.sessions.entityTypes.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The unique identifier of this session entity type. Format:\n`projects/\u003cProject ID\u003e/agent/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type\nDisplay Name\u003e`, or `projects/\u003cProject ID\u003e/agent/environments/\u003cEnvironment\nID\u003e/users/\u003cUser ID\u003e/sessions/\u003cSession ID\u003e/entityTypes/\u003cEntity Type Display\nName\u003e`.\nIf `Environment ID` is not specified, we assume default 'draft'\nenvironment. If `User ID` is not specified, we assume default '-' user.\n\n`\u003cEntity Type Display Name\u003e` must be the display name of an existing entity\ntype in the same agent that will be overridden or supplemented.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/agent/sessions/[^/]+/entityTypes/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "updateMask": {
	//       "description": "Optional. The mask to control which fields get updated.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudDialogflowV2SessionEntityType"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.locations.operations.cancel":

type ProjectsLocationsOperationsCancelCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Cancel: Starts asynchronous cancellation on a long-running operation.
//  The server
// makes a best effort to cancel the operation, but success is
// not
// guaranteed.  If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.  Clients can
// use
// Operations.GetOperation or
// other methods to check whether the cancellation succeeded or whether
// the
// operation completed despite cancellation. On successful
// cancellation,
// the operation is not deleted; instead, it becomes an operation
// with
// an Operation.error value with a google.rpc.Status.code of
// 1,
// corresponding to `Code.CANCELLED`.
func (r *ProjectsLocationsOperationsService) Cancel(name string) *ProjectsLocationsOperationsCancelCall {
	c := &ProjectsLocationsOperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsLocationsOperationsCancelCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsCancelCall {
	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 *ProjectsLocationsOperationsCancelCall) Context(ctx context.Context) *ProjectsLocationsOperationsCancelCall {
	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 *ProjectsLocationsOperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.locations.operations.cancel" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsLocationsOperationsCancelCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Starts asynchronous cancellation on a long-running operation.  The server\nmakes a best effort to cancel the operation, but success is not\nguaranteed.  If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.  Clients can use\nOperations.GetOperation or\nother methods to check whether the cancellation succeeded or whether the\noperation completed despite cancellation. On successful cancellation,\nthe operation is not deleted; instead, it becomes an operation with\nan Operation.error value with a google.rpc.Status.code of 1,\ncorresponding to `Code.CANCELLED`.",
	//   "flatPath": "v2/projects/{projectsId}/locations/{locationsId}/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.locations.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}:cancel",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.locations.operations.get":

type ProjectsLocationsOperationsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the latest state of a long-running operation.  Clients can
// use this
// method to poll the operation result at intervals as recommended by
// the API
// service.
func (r *ProjectsLocationsOperationsService) Get(name string) *ProjectsLocationsOperationsGetCall {
	c := &ProjectsLocationsOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsLocationsOperationsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsLocationsOperationsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsLocationsOperationsGetCall) Context(ctx context.Context) *ProjectsLocationsOperationsGetCall {
	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 *ProjectsLocationsOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.locations.operations.get" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsLocationsOperationsGetCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest state of a long-running operation.  Clients can use this\nmethod to poll the operation result at intervals as recommended by the API\nservice.",
	//   "flatPath": "v2/projects/{projectsId}/locations/{locationsId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.locations.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.locations.operations.list":

type ProjectsLocationsOperationsListCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists operations that match the specified filter in the
// request. If the
// server doesn't support this method, it returns
// `UNIMPLEMENTED`.
//
// NOTE: the `name` binding allows API services to override the
// binding
// to use different resource name schemes, such as `users/*/operations`.
// To
// override the binding, API services can add a binding such
// as
// "/v1/{name=users/*}/operations" to their service configuration.
// For backwards compatibility, the default name includes the
// operations
// collection id, however overriding users must ensure the name
// binding
// is the parent resource, without the operations collection id.
func (r *ProjectsLocationsOperationsService) List(name string) *ProjectsLocationsOperationsListCall {
	c := &ProjectsLocationsOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list
// filter.
func (c *ProjectsLocationsOperationsListCall) Filter(filter string) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list
// page size.
func (c *ProjectsLocationsOperationsListCall) PageSize(pageSize int64) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list
// page token.
func (c *ProjectsLocationsOperationsListCall) PageToken(pageToken string) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsLocationsOperationsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsLocationsOperationsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsLocationsOperationsListCall) Context(ctx context.Context) *ProjectsLocationsOperationsListCall {
	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 *ProjectsLocationsOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.locations.operations.list" call.
// Exactly one of *GoogleLongrunningListOperationsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleLongrunningListOperationsResponse.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 *ProjectsLocationsOperationsListCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningListOperationsResponse, 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 := &GoogleLongrunningListOperationsResponse{
		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": "Lists operations that match the specified filter in the request. If the\nserver doesn't support this method, it returns `UNIMPLEMENTED`.\n\nNOTE: the `name` binding allows API services to override the binding\nto use different resource name schemes, such as `users/*/operations`. To\noverride the binding, API services can add a binding such as\n`\"/v1/{name=users/*}/operations\"` to their service configuration.\nFor backwards compatibility, the default name includes the operations\ncollection id, however overriding users must ensure the name binding\nis the parent resource, without the operations collection id.",
	//   "flatPath": "v2/projects/{projectsId}/locations/{locationsId}/operations",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.locations.operations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/locations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The standard list page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}/operations",
	//   "response": {
	//     "$ref": "GoogleLongrunningListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsOperationsListCall) Pages(ctx context.Context, f func(*GoogleLongrunningListOperationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dialogflow.projects.operations.cancel":

type ProjectsOperationsCancelCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Cancel: Starts asynchronous cancellation on a long-running operation.
//  The server
// makes a best effort to cancel the operation, but success is
// not
// guaranteed.  If the server doesn't support this method, it
// returns
// `google.rpc.Code.UNIMPLEMENTED`.  Clients can
// use
// Operations.GetOperation or
// other methods to check whether the cancellation succeeded or whether
// the
// operation completed despite cancellation. On successful
// cancellation,
// the operation is not deleted; instead, it becomes an operation
// with
// an Operation.error value with a google.rpc.Status.code of
// 1,
// corresponding to `Code.CANCELLED`.
func (r *ProjectsOperationsService) Cancel(name string) *ProjectsOperationsCancelCall {
	c := &ProjectsOperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsOperationsCancelCall) Fields(s ...googleapi.Field) *ProjectsOperationsCancelCall {
	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 *ProjectsOperationsCancelCall) Context(ctx context.Context) *ProjectsOperationsCancelCall {
	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 *ProjectsOperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsOperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.operations.cancel" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *ProjectsOperationsCancelCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Starts asynchronous cancellation on a long-running operation.  The server\nmakes a best effort to cancel the operation, but success is not\nguaranteed.  If the server doesn't support this method, it returns\n`google.rpc.Code.UNIMPLEMENTED`.  Clients can use\nOperations.GetOperation or\nother methods to check whether the cancellation succeeded or whether the\noperation completed despite cancellation. On successful cancellation,\nthe operation is not deleted; instead, it becomes an operation with\nan Operation.error value with a google.rpc.Status.code of 1,\ncorresponding to `Code.CANCELLED`.",
	//   "flatPath": "v2/projects/{projectsId}/operations/{operationsId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "dialogflow.projects.operations.cancel",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource to be cancelled.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}:cancel",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.operations.get":

type ProjectsOperationsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the latest state of a long-running operation.  Clients can
// use this
// method to poll the operation result at intervals as recommended by
// the API
// service.
func (r *ProjectsOperationsService) Get(name string) *ProjectsOperationsGetCall {
	c := &ProjectsOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *ProjectsOperationsGetCall) Fields(s ...googleapi.Field) *ProjectsOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsOperationsGetCall) IfNoneMatch(entityTag string) *ProjectsOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsOperationsGetCall) Context(ctx context.Context) *ProjectsOperationsGetCall {
	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 *ProjectsOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.operations.get" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.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 *ProjectsOperationsGetCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, 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 := &GoogleLongrunningOperation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest state of a long-running operation.  Clients can use this\nmethod to poll the operation result at intervals as recommended by the API\nservice.",
	//   "flatPath": "v2/projects/{projectsId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/operations/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}",
	//   "response": {
	//     "$ref": "GoogleLongrunningOperation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// method id "dialogflow.projects.operations.list":

type ProjectsOperationsListCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists operations that match the specified filter in the
// request. If the
// server doesn't support this method, it returns
// `UNIMPLEMENTED`.
//
// NOTE: the `name` binding allows API services to override the
// binding
// to use different resource name schemes, such as `users/*/operations`.
// To
// override the binding, API services can add a binding such
// as
// "/v1/{name=users/*}/operations" to their service configuration.
// For backwards compatibility, the default name includes the
// operations
// collection id, however overriding users must ensure the name
// binding
// is the parent resource, without the operations collection id.
func (r *ProjectsOperationsService) List(name string) *ProjectsOperationsListCall {
	c := &ProjectsOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list
// filter.
func (c *ProjectsOperationsListCall) Filter(filter string) *ProjectsOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list
// page size.
func (c *ProjectsOperationsListCall) PageSize(pageSize int64) *ProjectsOperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list
// page token.
func (c *ProjectsOperationsListCall) PageToken(pageToken string) *ProjectsOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *ProjectsOperationsListCall) Fields(s ...googleapi.Field) *ProjectsOperationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsOperationsListCall) IfNoneMatch(entityTag string) *ProjectsOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsOperationsListCall) Context(ctx context.Context) *ProjectsOperationsListCall {
	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 *ProjectsOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200314")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v2/{+name}/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dialogflow.projects.operations.list" call.
// Exactly one of *GoogleLongrunningListOperationsResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleLongrunningListOperationsResponse.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 *ProjectsOperationsListCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningListOperationsResponse, 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 := &GoogleLongrunningListOperationsResponse{
		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": "Lists operations that match the specified filter in the request. If the\nserver doesn't support this method, it returns `UNIMPLEMENTED`.\n\nNOTE: the `name` binding allows API services to override the binding\nto use different resource name schemes, such as `users/*/operations`. To\noverride the binding, API services can add a binding such as\n`\"/v1/{name=users/*}/operations\"` to their service configuration.\nFor backwards compatibility, the default name includes the operations\ncollection id, however overriding users must ensure the name binding\nis the parent resource, without the operations collection id.",
	//   "flatPath": "v2/projects/{projectsId}/operations",
	//   "httpMethod": "GET",
	//   "id": "dialogflow.projects.operations.list",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "The standard list page size.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The standard list page token.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v2/{+name}/operations",
	//   "response": {
	//     "$ref": "GoogleLongrunningListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/dialogflow"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsOperationsListCall) Pages(ctx context.Context, f func(*GoogleLongrunningListOperationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}
