// 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 speech provides access to the Cloud Speech-to-Text API.
//
// This package is DEPRECATED. Use package cloud.google.com/go/speech/apiv1 instead.
//
// For product documentation, see: https://cloud.google.com/speech-to-text/docs/quickstart-protocol
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/speech/v1p1beta1"
//   ...
//   ctx := context.Background()
//   speechService, err := speech.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   speechService, err := speech.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, ...)
//   speechService, err := speech.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package speech // import "google.golang.org/api/speech/v1p1beta1"

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 = "speech:v1p1beta1"
const apiName = "speech"
const apiVersion = "v1p1beta1"
const basePath = "https://speech.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"
)

// 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",
	)
	// 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.Operations = NewOperationsService(s)
	s.Projects = NewProjectsService(s)
	s.Speech = NewSpeechService(s)
	return s, nil
}

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

	Operations *OperationsService

	Projects *ProjectsService

	Speech *SpeechService
}

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

func NewOperationsService(s *Service) *OperationsService {
	rs := &OperationsService{s: s}
	return rs
}

type OperationsService struct {
	s *Service
}

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

type ProjectsService struct {
	s *Service

	Locations *ProjectsLocationsService
}

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 NewSpeechService(s *Service) *SpeechService {
	rs := &SpeechService{s: s}
	return rs
}

type SpeechService struct {
	s *Service
}

// ListOperationsResponse: The response message for
// Operations.ListOperations.
type ListOperationsResponse 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 []*Operation `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 *ListOperationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListOperationsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LongRunningRecognizeMetadata: Describes the progress of a
// long-running `LongRunningRecognize` call. It is
// included in the `metadata` field of the `Operation` returned by
// the
// `GetOperation` call of the `google::longrunning::Operations` service.
type LongRunningRecognizeMetadata struct {
	// LastUpdateTime: Time of the most recent processing update.
	LastUpdateTime string `json:"lastUpdateTime,omitempty"`

	// ProgressPercent: Approximate percentage of audio processed thus far.
	// Guaranteed to be 100
	// when the audio is fully processed and the results are available.
	ProgressPercent int64 `json:"progressPercent,omitempty"`

	// StartTime: Time when the request was received.
	StartTime string `json:"startTime,omitempty"`

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

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

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

// LongRunningRecognizeRequest: The top-level message sent by the client
// for the `LongRunningRecognize`
// method.
type LongRunningRecognizeRequest struct {
	// Audio: Required. The audio data to be recognized.
	Audio *RecognitionAudio `json:"audio,omitempty"`

	// Config: Required. Provides information to the recognizer that
	// specifies how to
	// process the request.
	Config *RecognitionConfig `json:"config,omitempty"`

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

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

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

// LongRunningRecognizeResponse: The only message returned to the client
// by the `LongRunningRecognize` method.
// It contains the result as zero or more sequential
// `SpeechRecognitionResult`
// messages. It is included in the `result.response` field of the
// `Operation`
// returned by the `GetOperation` call of the
// `google::longrunning::Operations`
// service.
type LongRunningRecognizeResponse struct {
	// Results: Sequential list of transcription results corresponding
	// to
	// sequential portions of audio.
	Results []*SpeechRecognitionResult `json:"results,omitempty"`

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

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

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

// Operation: This resource represents a long-running operation that is
// the result of a
// network API call.
type Operation 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 *Status `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 *Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RecognitionAudio: Contains audio data in the encoding specified in
// the `RecognitionConfig`.
// Either `content` or `uri` must be supplied. Supplying both or
// neither
// returns google.rpc.Code.INVALID_ARGUMENT. See
// [content
// limits](https://cloud.google.com/speech-to-text/quotas#content).
type RecognitionAudio struct {
	// Content: The audio data bytes encoded as specified
	// in
	// `RecognitionConfig`. Note: as with all bytes fields, proto buffers
	// use a
	// pure binary representation, whereas JSON representations use base64.
	Content string `json:"content,omitempty"`

	// Uri: URI that points to a file that contains audio data bytes as
	// specified in
	// `RecognitionConfig`. The file must not be compressed (for example,
	// gzip).
	// Currently, only Google Cloud Storage URIs are
	// supported, which must be specified in the following
	// format:
	// `gs://bucket_name/object_name` (other URI formats
	// return
	// google.rpc.Code.INVALID_ARGUMENT). For more information, see
	// [Request URIs](https://cloud.google.com/storage/docs/reference-uris).
	Uri string `json:"uri,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 *RecognitionAudio) MarshalJSON() ([]byte, error) {
	type NoMethod RecognitionAudio
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RecognitionConfig: Provides information to the recognizer that
// specifies how to process the
// request.
type RecognitionConfig struct {
	// AlternativeLanguageCodes: A list of up to 3
	// additional
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language
	// tags,
	// listing possible alternative languages of the supplied audio.
	// See
	// [Language
	// Support](https://cloud.google.com/speech-to-text/docs/langua
	// ges) for a list
	// of the currently supported language codes. If alternative languages
	// are
	// listed, recognition result will contain recognition in the most
	// likely
	// language detected including the main language_code. The recognition
	// result
	// will include the language tag of the language detected in the audio.
	// Note:
	// This feature is only supported for Voice Command and Voice Search use
	// cases
	// and performance may vary for other use cases (e.g., phone
	// call
	// transcription).
	AlternativeLanguageCodes []string `json:"alternativeLanguageCodes,omitempty"`

	// AudioChannelCount: The number of channels in the input audio
	// data.
	// ONLY set this for MULTI-CHANNEL recognition.
	// Valid values for LINEAR16 and FLAC are `1`-`8`.
	// Valid values for OGG_OPUS are '1'-'254'.
	// Valid value for MULAW, AMR, AMR_WB and SPEEX_WITH_HEADER_BYTE is only
	// `1`.
	// If `0` or omitted, defaults to one channel (mono).
	// Note: We only recognize the first channel by default.
	// To perform independent recognition on each channel
	// set
	// `enable_separate_recognition_per_channel` to 'true'.
	AudioChannelCount int64 `json:"audioChannelCount,omitempty"`

	// DiarizationConfig: Config to enable speaker diarization and set
	// additional
	// parameters to make diarization better suited for your
	// application.
	// Note: When this is enabled, we send all the words from the beginning
	// of the
	// audio for the top alternative in every consecutive STREAMING
	// responses.
	// This is done in order to improve our speaker tags as our models learn
	// to
	// identify the speakers in the conversation over time.
	// For non-streaming requests, the diarization results will be provided
	// only
	// in the top alternative of the FINAL SpeechRecognitionResult.
	DiarizationConfig *SpeakerDiarizationConfig `json:"diarizationConfig,omitempty"`

	// DiarizationSpeakerCount: If set, specifies the estimated number of
	// speakers in the conversation.
	// Defaults to '2'. Ignored unless enable_speaker_diarization is set to
	// true.
	// Note: Use diarization_config instead.
	DiarizationSpeakerCount int64 `json:"diarizationSpeakerCount,omitempty"`

	// EnableAutomaticPunctuation: If 'true', adds punctuation to
	// recognition result hypotheses.
	// This feature is only available in select languages. Setting this
	// for
	// requests in other languages has no effect at all.
	// The default 'false' value does not add punctuation to result
	// hypotheses.
	// Note: This is currently offered as an experimental service,
	// complimentary
	// to all users. In the future this may be exclusively available as
	// a
	// premium feature.
	EnableAutomaticPunctuation bool `json:"enableAutomaticPunctuation,omitempty"`

	// EnableSeparateRecognitionPerChannel: This needs to be set to `true`
	// explicitly and `audio_channel_count` > 1
	// to get each channel recognized separately. The recognition result
	// will
	// contain a `channel_tag` field to state which channel that result
	// belongs
	// to. If this is not true, we will only recognize the first channel.
	// The
	// request is billed cumulatively for all channels
	// recognized:
	// `audio_channel_count` multiplied by the length of the audio.
	EnableSeparateRecognitionPerChannel bool `json:"enableSeparateRecognitionPerChannel,omitempty"`

	// EnableSpeakerDiarization: If 'true', enables speaker detection for
	// each recognized word in
	// the top alternative of the recognition result using a speaker_tag
	// provided
	// in the WordInfo.
	// Note: Use diarization_config instead.
	EnableSpeakerDiarization bool `json:"enableSpeakerDiarization,omitempty"`

	// EnableWordConfidence: If `true`, the top result includes a list of
	// words and the
	// confidence for those words. If `false`, no word-level
	// confidence
	// information is returned. The default is `false`.
	EnableWordConfidence bool `json:"enableWordConfidence,omitempty"`

	// EnableWordTimeOffsets: If `true`, the top result includes a list of
	// words and
	// the start and end time offsets (timestamps) for those words.
	// If
	// `false`, no word-level time offset information is returned. The
	// default is
	// `false`.
	EnableWordTimeOffsets bool `json:"enableWordTimeOffsets,omitempty"`

	// Encoding: Encoding of audio data sent in all `RecognitionAudio`
	// messages.
	// This field is optional for `FLAC` and `WAV` audio files and
	// required
	// for all other audio formats. For details, see AudioEncoding.
	//
	// Possible values:
	//   "ENCODING_UNSPECIFIED" - Not specified.
	//   "LINEAR16" - Uncompressed 16-bit signed little-endian samples
	// (Linear PCM).
	//   "FLAC" - `FLAC` (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.
	//   "MULAW" - 8-bit samples that compand 14-bit audio samples using
	// G.711 PCMU/mu-law.
	//   "AMR" - Adaptive Multi-Rate Narrowband codec. `sample_rate_hertz`
	// must be 8000.
	//   "AMR_WB" - Adaptive Multi-Rate Wideband codec. `sample_rate_hertz`
	// must be 16000.
	//   "OGG_OPUS" - Opus encoded audio frames in Ogg
	// container
	// ([OggOpus](https://wiki.xiph.org/OggOpus)).
	// `sample_rate_her
	// tz` must be one of 8000, 12000, 16000, 24000, or 48000.
	//   "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
	// Cloud Speech 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.
	//   "MP3" - MP3 audio. Support all standard MP3 bitrates (which range
	// from 32-320
	// kbps). When using this encoding, `sample_rate_hertz` has to match
	// the
	// sample rate of the file being used.
	Encoding string `json:"encoding,omitempty"`

	// LanguageCode: Required. The language of the supplied audio as
	// a
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language
	// tag.
	// Example: "en-US".
	// See
	// [Language
	// Support](https://cloud.google.com/speech-to-text/docs/langua
	// ges) for a list
	// of the currently supported language codes.
	LanguageCode string `json:"languageCode,omitempty"`

	// MaxAlternatives: Maximum number of recognition hypotheses to be
	// returned.
	// Specifically, the maximum number of `SpeechRecognitionAlternative`
	// messages
	// within each `SpeechRecognitionResult`.
	// The server may return fewer than `max_alternatives`.
	// Valid values are `0`-`30`. A value of `0` or `1` will return a
	// maximum of
	// one. If omitted, will return a maximum of one.
	MaxAlternatives int64 `json:"maxAlternatives,omitempty"`

	// Metadata: Metadata regarding this request.
	Metadata *RecognitionMetadata `json:"metadata,omitempty"`

	// Model: Which 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 RecognitionConfig.
	// <table>
	//   <tr>
	//     <td><b>Model</b></td>
	//     <td><b>Description</b></td>
	//   </tr>
	//   <tr>
	//     <td><code>command_and_search</code></td>
	//     <td>Best for short queries such as voice commands or voice
	// search.</td>
	//   </tr>
	//   <tr>
	//     <td><code>phone_call</code></td>
	//     <td>Best for audio that originated from a phone call (typically
	//     recorded at an 8khz sampling rate).</td>
	//   </tr>
	//   <tr>
	//     <td><code>video</code></td>
	//     <td>Best for audio that originated from from video or includes
	// multiple
	//         speakers. Ideally the audio is recorded at a 16khz or
	// greater
	//         sampling rate. This is a premium model that costs more than
	// the
	//         standard rate.</td>
	//   </tr>
	//   <tr>
	//     <td><code>default</code></td>
	//     <td>Best for audio that is not one of the specific audio models.
	//         For example, long-form audio. Ideally the audio is
	// high-fidelity,
	//         recorded at a 16khz or greater sampling rate.</td>
	//   </tr>
	// </table>
	Model string `json:"model,omitempty"`

	// ProfanityFilter: If set to `true`, the server will attempt to filter
	// out
	// profanities, replacing all but the initial character in each filtered
	// word
	// with asterisks, e.g. "f***". If set to `false` or omitted,
	// profanities
	// won't be filtered out.
	ProfanityFilter bool `json:"profanityFilter,omitempty"`

	// SampleRateHertz: Sample rate in Hertz of the audio data sent in
	// all
	// `RecognitionAudio` messages. Valid values are: 8000-48000.
	// 16000 is optimal. For best results, set the sampling rate of the
	// audio
	// source to 16000 Hz. If that's not possible, use the native sample
	// rate of
	// the audio source (instead of re-sampling).
	// This field is optional for FLAC and WAV audio files, but is
	// required for all other audio formats. For details, see AudioEncoding.
	SampleRateHertz int64 `json:"sampleRateHertz,omitempty"`

	// SpeechContexts: Array of SpeechContext.
	// A means to provide context to assist the speech recognition. For
	// more
	// information,
	// see
	// [speech
	// adaptation](https://cloud.google.com/speech-to-text/docs/c
	// ontext-strength).
	SpeechContexts []*SpeechContext `json:"speechContexts,omitempty"`

	// UseEnhanced: Set to true to use an enhanced model for speech
	// recognition.
	// If `use_enhanced` is set to true and the `model` field is not set,
	// then
	// an appropriate enhanced model is chosen if an enhanced model exists
	// for
	// the audio.
	//
	// If `use_enhanced` is true and an enhanced version of the specified
	// model
	// does not exist, then the speech is recognized using the standard
	// version
	// of the specified model.
	UseEnhanced bool `json:"useEnhanced,omitempty"`

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

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

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

// RecognitionMetadata: Description of audio data to be recognized.
type RecognitionMetadata struct {
	// AudioTopic: Description of the content. Eg. "Recordings of federal
	// supreme court
	// hearings from 2012".
	AudioTopic string `json:"audioTopic,omitempty"`

	// IndustryNaicsCodeOfAudio: The industry vertical to which this speech
	// recognition request most
	// closely applies. This is most indicative of the topics contained
	// in the audio.  Use the 6-digit NAICS code to identify the
	// industry
	// vertical - see https://www.naics.com/search/.
	IndustryNaicsCodeOfAudio int64 `json:"industryNaicsCodeOfAudio,omitempty"`

	// InteractionType: The use case most closely describing the audio
	// content to be recognized.
	//
	// Possible values:
	//   "INTERACTION_TYPE_UNSPECIFIED" - Use case is either unknown or is
	// something other than one of the other
	// values below.
	//   "DISCUSSION" - Multiple people in a conversation or discussion. For
	// example in a
	// meeting with two or more people actively participating. Typically
	// all the primary people speaking would be in the same room (if
	// not,
	// see PHONE_CALL)
	//   "PRESENTATION" - One or more persons lecturing or presenting to
	// others, mostly
	// uninterrupted.
	//   "PHONE_CALL" - A phone-call or video-conference in which two or
	// more people, who are
	// not in the same room, are actively participating.
	//   "VOICEMAIL" - A recorded message intended for another person to
	// listen to.
	//   "PROFESSIONALLY_PRODUCED" - Professionally produced audio (eg. TV
	// Show, Podcast).
	//   "VOICE_SEARCH" - Transcribe spoken questions and queries into text.
	//   "VOICE_COMMAND" - Transcribe voice commands, such as for
	// controlling a device.
	//   "DICTATION" - Transcribe speech to text to create a written
	// document, such as a
	// text-message, email or report.
	InteractionType string `json:"interactionType,omitempty"`

	// MicrophoneDistance: The audio type that most closely describes the
	// audio being recognized.
	//
	// Possible values:
	//   "MICROPHONE_DISTANCE_UNSPECIFIED" - Audio type is not known.
	//   "NEARFIELD" - The audio was captured from a closely placed
	// microphone. Eg. phone,
	// dictaphone, or handheld microphone. Generally if there speaker is
	// within
	// 1 meter of the microphone.
	//   "MIDFIELD" - The speaker if within 3 meters of the microphone.
	//   "FARFIELD" - The speaker is more than 3 meters away from the
	// microphone.
	MicrophoneDistance string `json:"microphoneDistance,omitempty"`

	// ObfuscatedId: Obfuscated (privacy-protected) ID of the user, to
	// identify number of
	// unique users using the service.
	ObfuscatedId int64 `json:"obfuscatedId,omitempty,string"`

	// OriginalMediaType: The original media the speech was recorded on.
	//
	// Possible values:
	//   "ORIGINAL_MEDIA_TYPE_UNSPECIFIED" - Unknown original media type.
	//   "AUDIO" - The speech data is an audio recording.
	//   "VIDEO" - The speech data originally recorded on a video.
	OriginalMediaType string `json:"originalMediaType,omitempty"`

	// OriginalMimeType: Mime type of the original audio file.  For example
	// `audio/m4a`,
	// `audio/x-alaw-basic`, `audio/mp3`, `audio/3gpp`.
	// A list of possible audio mime types is maintained
	// at
	// http://www.iana.org/assignments/media-types/media-types.xhtml#audio
	OriginalMimeType string `json:"originalMimeType,omitempty"`

	// RecordingDeviceName: The device used to make the recording.  Examples
	// 'Nexus 5X' or
	// 'Polycom SoundStation IP 6000' or 'POTS' or 'VoIP' or
	// 'Cardioid Microphone'.
	RecordingDeviceName string `json:"recordingDeviceName,omitempty"`

	// RecordingDeviceType: The type of device the speech was recorded with.
	//
	// Possible values:
	//   "RECORDING_DEVICE_TYPE_UNSPECIFIED" - The recording device is
	// unknown.
	//   "SMARTPHONE" - Speech was recorded on a smartphone.
	//   "PC" - Speech was recorded using a personal computer or tablet.
	//   "PHONE_LINE" - Speech was recorded over a phone line.
	//   "VEHICLE" - Speech was recorded in a vehicle.
	//   "OTHER_OUTDOOR_DEVICE" - Speech was recorded outdoors.
	//   "OTHER_INDOOR_DEVICE" - Speech was recorded indoors.
	RecordingDeviceType string `json:"recordingDeviceType,omitempty"`

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

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

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

// RecognizeRequest: The top-level message sent by the client for the
// `Recognize` method.
type RecognizeRequest struct {
	// Audio: Required. The audio data to be recognized.
	Audio *RecognitionAudio `json:"audio,omitempty"`

	// Config: Required. Provides information to the recognizer that
	// specifies how to
	// process the request.
	Config *RecognitionConfig `json:"config,omitempty"`

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

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

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

// RecognizeResponse: The only message returned to the client by the
// `Recognize` method. It
// contains the result as zero or more sequential
// `SpeechRecognitionResult`
// messages.
type RecognizeResponse struct {
	// Results: Sequential list of transcription results corresponding
	// to
	// sequential portions of audio.
	Results []*SpeechRecognitionResult `json:"results,omitempty"`

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

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

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

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

// SpeakerDiarizationConfig: Config to enable speaker diarization.
type SpeakerDiarizationConfig struct {
	// EnableSpeakerDiarization: If 'true', enables speaker detection for
	// each recognized word in
	// the top alternative of the recognition result using a speaker_tag
	// provided
	// in the WordInfo.
	EnableSpeakerDiarization bool `json:"enableSpeakerDiarization,omitempty"`

	// MaxSpeakerCount: Maximum number of speakers in the conversation. This
	// range gives you more
	// flexibility by allowing the system to automatically determine the
	// correct
	// number of speakers. If not set, the default value is 6.
	MaxSpeakerCount int64 `json:"maxSpeakerCount,omitempty"`

	// MinSpeakerCount: Minimum number of speakers in the conversation. This
	// range gives you more
	// flexibility by allowing the system to automatically determine the
	// correct
	// number of speakers. If not set, the default value is 2.
	MinSpeakerCount int64 `json:"minSpeakerCount,omitempty"`

	// SpeakerTag: Output only. Unused.
	SpeakerTag int64 `json:"speakerTag,omitempty"`

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

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

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

// SpeechContext: Provides "hints" to the speech recognizer to favor
// specific words and phrases
// in the results.
type SpeechContext struct {
	// Boost: Hint Boost. Positive value will increase the probability that
	// a specific
	// phrase will be recognized over other similar sounding phrases. The
	// higher
	// the boost, the higher the chance of false positive recognition as
	// well.
	// Negative boost values would correspond to anti-biasing. Anti-biasing
	// is not
	// enabled, so negative boost will simply be ignored. Though `boost`
	// can
	// accept a wide range of positive values, most use cases are best
	// served with
	// values between 0 and 20. We recommend using a binary search approach
	// to
	// finding the optimal value for your use case.
	Boost float64 `json:"boost,omitempty"`

	// Phrases: A list of strings containing words and phrases "hints" so
	// that
	// the speech recognition is more likely to recognize them. This can be
	// used
	// to improve the accuracy for specific words and phrases, for example,
	// if
	// specific commands are typically spoken by the user. This can also be
	// used
	// to add additional words to the vocabulary of the recognizer.
	// See
	// [usage
	// limits](https://cloud.google.com/speech-to-text/quotas#content).
	//
	// List
	//  items can also be set to classes for groups of words that
	// represent
	// common concepts that occur in natural language. For example, rather
	// than
	// providing phrase hints for every month of the year, using the $MONTH
	// class
	// improves the likelihood of correctly transcribing audio that
	// includes
	// months.
	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 *SpeechContext) MarshalJSON() ([]byte, error) {
	type NoMethod SpeechContext
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// SpeechRecognitionAlternative: Alternative hypotheses (a.k.a. n-best
// list).
type SpeechRecognitionAlternative struct {
	// Confidence: The confidence estimate between 0.0 and 1.0. A higher
	// number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative of a
	// non-streaming
	// result or, of a streaming result where `is_final=true`.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// Transcript: Transcript text representing the words that the user
	// spoke.
	Transcript string `json:"transcript,omitempty"`

	// Words: A list of word-specific information for each recognized
	// word.
	// Note: When `enable_speaker_diarization` is true, you will see all the
	// words
	// from the beginning of the audio.
	Words []*WordInfo `json:"words,omitempty"`

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

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

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

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

// SpeechRecognitionResult: A speech recognition result corresponding to
// a portion of the audio.
type SpeechRecognitionResult struct {
	// Alternatives: May contain one or more recognition hypotheses (up to
	// the
	// maximum specified in `max_alternatives`).
	// These alternatives are ordered in terms of accuracy, with the top
	// (first)
	// alternative being the most probable, as ranked by the recognizer.
	Alternatives []*SpeechRecognitionAlternative `json:"alternatives,omitempty"`

	// ChannelTag: For multi-channel audio, this is the channel number
	// corresponding to the
	// recognized result for the audio from that channel.
	// For audio_channel_count = N, its output values can range from '1' to
	// 'N'.
	ChannelTag int64 `json:"channelTag,omitempty"`

	// LanguageCode: Output only. The
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language
	// tag
	// of the language in this result. This language code was detected to
	// have
	// the most likelihood of being spoken in the audio.
	LanguageCode string `json:"languageCode,omitempty"`

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

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

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

// Status: The `Status` type defines a logical error model that is
// suitable for
// different programming environments, including REST APIs and RPC APIs.
// It is
// used by [gRPC](https://github.com/grpc). 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 Status struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

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

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

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

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

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

// WordInfo: Word-specific information for recognized words.
type WordInfo struct {
	// Confidence: The confidence estimate between 0.0 and 1.0. A higher
	// number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative of a
	// non-streaming
	// result or, of a streaming result where `is_final=true`.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// EndTime: Time offset relative to the beginning of the audio,
	// and corresponding to the end of the spoken word.
	// This field is only set if `enable_word_time_offsets=true` and only
	// in the top hypothesis.
	// This is an experimental feature and the accuracy of the time offset
	// can
	// vary.
	EndTime string `json:"endTime,omitempty"`

	// SpeakerTag: Output only. A distinct integer value is assigned for
	// every speaker within
	// the audio. This field specifies which one of those speakers was
	// detected to
	// have spoken this word. Value ranges from '1' to
	// diarization_speaker_count.
	// speaker_tag is set if enable_speaker_diarization = 'true' and only in
	// the
	// top alternative.
	SpeakerTag int64 `json:"speakerTag,omitempty"`

	// StartTime: Time offset relative to the beginning of the audio,
	// and corresponding to the start of the spoken word.
	// This field is only set if `enable_word_time_offsets=true` and only
	// in the top hypothesis.
	// This is an experimental feature and the accuracy of the time offset
	// can
	// vary.
	StartTime string `json:"startTime,omitempty"`

	// Word: The word corresponding to this set of information.
	Word string `json:"word,omitempty"`

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

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

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

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

// method id "speech.operations.get":

type OperationsGetCall 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 *OperationsService) Get(name string) *OperationsGetCall {
	c := &OperationsGetCall{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 *OperationsGetCall) Fields(s ...googleapi.Field) *OperationsGetCall {
	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 *OperationsGetCall) IfNoneMatch(entityTag string) *OperationsGetCall {
	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 *OperationsGetCall) Context(ctx context.Context) *OperationsGetCall {
	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 *OperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200316")
	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, "v1p1beta1/operations/{+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 "speech.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.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 *OperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, 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 := &Operation{
		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": "v1p1beta1/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "speech.operations.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The name of the operation resource.",
	//       "location": "path",
	//       "pattern": "^.*$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1p1beta1/operations/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "speech.operations.list":

type OperationsListCall struct {
	s            *Service
	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 *OperationsService) List() *OperationsListCall {
	c := &OperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Filter sets the optional parameter "filter": The standard list
// filter.
func (c *OperationsListCall) Filter(filter string) *OperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// Name sets the optional parameter "name": The name of the operation's
// parent resource.
func (c *OperationsListCall) Name(name string) *OperationsListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list
// page size.
func (c *OperationsListCall) PageSize(pageSize int64) *OperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list
// page token.
func (c *OperationsListCall) PageToken(pageToken string) *OperationsListCall {
	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 *OperationsListCall) Fields(s ...googleapi.Field) *OperationsListCall {
	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 *OperationsListCall) IfNoneMatch(entityTag string) *OperationsListCall {
	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 *OperationsListCall) Context(ctx context.Context) *OperationsListCall {
	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 *OperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200316")
	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, "v1p1beta1/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "speech.operations.list" call.
// Exactly one of *ListOperationsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.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 *OperationsListCall) Do(opts ...googleapi.CallOption) (*ListOperationsResponse, 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 := &ListOperationsResponse{
		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": "v1p1beta1/operations",
	//   "httpMethod": "GET",
	//   "id": "speech.operations.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "filter": {
	//       "description": "The standard list filter.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "The name of the operation's parent resource.",
	//       "location": "query",
	//       "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": "v1p1beta1/operations",
	//   "response": {
	//     "$ref": "ListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// 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 *OperationsListCall) Pages(ctx context.Context, f func(*ListOperationsResponse) 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 "speech.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/20200316")
	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, "v1p1beta1/{+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 "speech.projects.locations.operations.get" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.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) (*Operation, 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 := &Operation{
		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": "v1p1beta1/projects/{projectsId}/locations/{locationsId}/operations/{operationsId}",
	//   "httpMethod": "GET",
	//   "id": "speech.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": "v1p1beta1/{+name}",
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "speech.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/20200316")
	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, "v1p1beta1/{+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 "speech.projects.locations.operations.list" call.
// Exactly one of *ListOperationsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.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) (*ListOperationsResponse, 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 := &ListOperationsResponse{
		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": "v1p1beta1/projects/{projectsId}/locations/{locationsId}/operations",
	//   "httpMethod": "GET",
	//   "id": "speech.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": "v1p1beta1/{+name}/operations",
	//   "response": {
	//     "$ref": "ListOperationsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// 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(*ListOperationsResponse) 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 "speech.speech.longrunningrecognize":

type SpeechLongrunningrecognizeCall struct {
	s                           *Service
	longrunningrecognizerequest *LongRunningRecognizeRequest
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
	header_                     http.Header
}

// Longrunningrecognize: Performs asynchronous speech recognition:
// receive results via the
// google.longrunning.Operations interface. Returns either
// an
// `Operation.error` or an `Operation.response` which contains
// a `LongRunningRecognizeResponse` message.
// For more information on asynchronous speech recognition, see
// the
// [how-to](https://cloud.google.com/speech-to-text/docs/async-recogn
// ize).
func (r *SpeechService) Longrunningrecognize(longrunningrecognizerequest *LongRunningRecognizeRequest) *SpeechLongrunningrecognizeCall {
	c := &SpeechLongrunningrecognizeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.longrunningrecognizerequest = longrunningrecognizerequest
	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 *SpeechLongrunningrecognizeCall) Fields(s ...googleapi.Field) *SpeechLongrunningrecognizeCall {
	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 *SpeechLongrunningrecognizeCall) Context(ctx context.Context) *SpeechLongrunningrecognizeCall {
	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 *SpeechLongrunningrecognizeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SpeechLongrunningrecognizeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200316")
	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.longrunningrecognizerequest)
	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, "v1p1beta1/speech:longrunningrecognize")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "speech.speech.longrunningrecognize" call.
// Exactly one of *Operation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Operation.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 *SpeechLongrunningrecognizeCall) Do(opts ...googleapi.CallOption) (*Operation, 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 := &Operation{
		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": "Performs asynchronous speech recognition: receive results via the\ngoogle.longrunning.Operations interface. Returns either an\n`Operation.error` or an `Operation.response` which contains\na `LongRunningRecognizeResponse` message.\nFor more information on asynchronous speech recognition, see the\n[how-to](https://cloud.google.com/speech-to-text/docs/async-recognize).",
	//   "flatPath": "v1p1beta1/speech:longrunningrecognize",
	//   "httpMethod": "POST",
	//   "id": "speech.speech.longrunningrecognize",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1p1beta1/speech:longrunningrecognize",
	//   "request": {
	//     "$ref": "LongRunningRecognizeRequest"
	//   },
	//   "response": {
	//     "$ref": "Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "speech.speech.recognize":

type SpeechRecognizeCall struct {
	s                *Service
	recognizerequest *RecognizeRequest
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// Recognize: Performs synchronous speech recognition: receive results
// after all audio
// has been sent and processed.
func (r *SpeechService) Recognize(recognizerequest *RecognizeRequest) *SpeechRecognizeCall {
	c := &SpeechRecognizeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.recognizerequest = recognizerequest
	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 *SpeechRecognizeCall) Fields(s ...googleapi.Field) *SpeechRecognizeCall {
	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 *SpeechRecognizeCall) Context(ctx context.Context) *SpeechRecognizeCall {
	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 *SpeechRecognizeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SpeechRecognizeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200316")
	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.recognizerequest)
	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, "v1p1beta1/speech:recognize")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "speech.speech.recognize" call.
// Exactly one of *RecognizeResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RecognizeResponse.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 *SpeechRecognizeCall) Do(opts ...googleapi.CallOption) (*RecognizeResponse, 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 := &RecognizeResponse{
		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": "Performs synchronous speech recognition: receive results after all audio\nhas been sent and processed.",
	//   "flatPath": "v1p1beta1/speech:recognize",
	//   "httpMethod": "POST",
	//   "id": "speech.speech.recognize",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1p1beta1/speech:recognize",
	//   "request": {
	//     "$ref": "RecognizeRequest"
	//   },
	//   "response": {
	//     "$ref": "RecognizeResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
