// 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 bigquery provides access to the BigQuery API.
//
// This package is DEPRECATED. Use package cloud.google.com/go/bigquery instead.
//
// For product documentation, see: https://cloud.google.com/bigquery/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/bigquery/v2"
//   ...
//   ctx := context.Background()
//   bigqueryService, err := bigquery.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:
//
//   bigqueryService, err := bigquery.NewService(ctx, option.WithScopes(bigquery.DevstorageReadWriteScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   bigqueryService, err := bigquery.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, ...)
//   bigqueryService, err := bigquery.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package bigquery // import "google.golang.org/api/bigquery/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 = "bigquery:v2"
const apiName = "bigquery"
const apiVersion = "v2"
const basePath = "https://bigquery.googleapis.com/bigquery/v2/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data in Google BigQuery
	BigqueryScope = "https://www.googleapis.com/auth/bigquery"

	// Insert data into Google BigQuery
	BigqueryInsertdataScope = "https://www.googleapis.com/auth/bigquery.insertdata"

	// View your data in Google BigQuery
	BigqueryReadonlyScope = "https://www.googleapis.com/auth/bigquery.readonly"

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

	// View your data across Google Cloud Platform services
	CloudPlatformReadOnlyScope = "https://www.googleapis.com/auth/cloud-platform.read-only"

	// Manage your data and permissions in Google Cloud Storage
	DevstorageFullControlScope = "https://www.googleapis.com/auth/devstorage.full_control"

	// View your data in Google Cloud Storage
	DevstorageReadOnlyScope = "https://www.googleapis.com/auth/devstorage.read_only"

	// Manage your data in Google Cloud Storage
	DevstorageReadWriteScope = "https://www.googleapis.com/auth/devstorage.read_write"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/bigquery",
		"https://www.googleapis.com/auth/bigquery.insertdata",
		"https://www.googleapis.com/auth/bigquery.readonly",
		"https://www.googleapis.com/auth/cloud-platform",
		"https://www.googleapis.com/auth/cloud-platform.read-only",
		"https://www.googleapis.com/auth/devstorage.full_control",
		"https://www.googleapis.com/auth/devstorage.read_only",
		"https://www.googleapis.com/auth/devstorage.read_write",
	)
	// 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.Datasets = NewDatasetsService(s)
	s.Jobs = NewJobsService(s)
	s.Models = NewModelsService(s)
	s.Projects = NewProjectsService(s)
	s.Routines = NewRoutinesService(s)
	s.Tabledata = NewTabledataService(s)
	s.Tables = NewTablesService(s)
	return s, nil
}

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

	Datasets *DatasetsService

	Jobs *JobsService

	Models *ModelsService

	Projects *ProjectsService

	Routines *RoutinesService

	Tabledata *TabledataService

	Tables *TablesService
}

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

func NewDatasetsService(s *Service) *DatasetsService {
	rs := &DatasetsService{s: s}
	return rs
}

type DatasetsService struct {
	s *Service
}

func NewJobsService(s *Service) *JobsService {
	rs := &JobsService{s: s}
	return rs
}

type JobsService struct {
	s *Service
}

func NewModelsService(s *Service) *ModelsService {
	rs := &ModelsService{s: s}
	return rs
}

type ModelsService struct {
	s *Service
}

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

type ProjectsService struct {
	s *Service
}

func NewRoutinesService(s *Service) *RoutinesService {
	rs := &RoutinesService{s: s}
	return rs
}

type RoutinesService struct {
	s *Service
}

func NewTabledataService(s *Service) *TabledataService {
	rs := &TabledataService{s: s}
	return rs
}

type TabledataService struct {
	s *Service
}

func NewTablesService(s *Service) *TablesService {
	rs := &TablesService{s: s}
	return rs
}

type TablesService struct {
	s *Service
}

// AggregateClassificationMetrics: Aggregate metrics for
// classification/classifier models. For multi-class
// models, the metrics are either macro-averaged or micro-averaged.
// When
// macro-averaged, the metrics are calculated for each label and then
// an
// unweighted average is taken of those values. When micro-averaged,
// the
// metric is calculated globally by counting the total number of
// correctly
// predicted rows.
type AggregateClassificationMetrics struct {
	// Accuracy: Accuracy is the fraction of predictions given the correct
	// label. For
	// multiclass this is a micro-averaged metric.
	Accuracy float64 `json:"accuracy,omitempty"`

	// F1Score: The F1 score is an average of recall and precision. For
	// multiclass
	// this is a macro-averaged metric.
	F1Score float64 `json:"f1Score,omitempty"`

	// LogLoss: Logarithmic Loss. For multiclass this is a macro-averaged
	// metric.
	LogLoss float64 `json:"logLoss,omitempty"`

	// Precision: Precision is the fraction of actual positive predictions
	// that had
	// positive actual labels. For multiclass this is a
	// macro-averaged
	// metric treating each class as a binary classifier.
	Precision float64 `json:"precision,omitempty"`

	// Recall: Recall is the fraction of actual positive labels that were
	// given a
	// positive prediction. For multiclass this is a macro-averaged metric.
	Recall float64 `json:"recall,omitempty"`

	// RocAuc: Area Under a ROC Curve. For multiclass this is a
	// macro-averaged
	// metric.
	RocAuc float64 `json:"rocAuc,omitempty"`

	// Threshold: Threshold at which the metrics are computed. For
	// binary
	// classification models this is the positive class threshold.
	// For multi-class classfication models this is the
	// confidence
	// threshold.
	Threshold float64 `json:"threshold,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Accuracy") 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. "Accuracy") 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 *AggregateClassificationMetrics) MarshalJSON() ([]byte, error) {
	type NoMethod AggregateClassificationMetrics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *AggregateClassificationMetrics) UnmarshalJSON(data []byte) error {
	type NoMethod AggregateClassificationMetrics
	var s1 struct {
		Accuracy  gensupport.JSONFloat64 `json:"accuracy"`
		F1Score   gensupport.JSONFloat64 `json:"f1Score"`
		LogLoss   gensupport.JSONFloat64 `json:"logLoss"`
		Precision gensupport.JSONFloat64 `json:"precision"`
		Recall    gensupport.JSONFloat64 `json:"recall"`
		RocAuc    gensupport.JSONFloat64 `json:"rocAuc"`
		Threshold gensupport.JSONFloat64 `json:"threshold"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Accuracy = float64(s1.Accuracy)
	s.F1Score = float64(s1.F1Score)
	s.LogLoss = float64(s1.LogLoss)
	s.Precision = float64(s1.Precision)
	s.Recall = float64(s1.Recall)
	s.RocAuc = float64(s1.RocAuc)
	s.Threshold = float64(s1.Threshold)
	return nil
}

// Argument: Input/output argument of a function or a stored procedure.
type Argument struct {
	// ArgumentKind: Optional. Defaults to FIXED_TYPE.
	//
	// Possible values:
	//   "ARGUMENT_KIND_UNSPECIFIED"
	//   "FIXED_TYPE" - The argument is a variable with fully specified
	// type, which can be a
	// struct or an array, but not a table.
	//   "ANY_TYPE" - The argument is any type, including struct or array,
	// but not a table.
	// To be added: FIXED_TABLE, ANY_TABLE
	ArgumentKind string `json:"argumentKind,omitempty"`

	// DataType: Required unless argument_kind = ANY_TYPE.
	DataType *StandardSqlDataType `json:"dataType,omitempty"`

	// Mode: Optional. Specifies whether the argument is input or
	// output.
	// Can be set for procedures only.
	//
	// Possible values:
	//   "MODE_UNSPECIFIED"
	//   "IN" - The argument is input-only.
	//   "OUT" - The argument is output-only.
	//   "INOUT" - The argument is both an input and an output.
	Mode string `json:"mode,omitempty"`

	// Name: Optional. The name of this argument. Can be absent for function
	// return argument.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArgumentKind") 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. "ArgumentKind") 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 *Argument) MarshalJSON() ([]byte, error) {
	type NoMethod Argument
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ArimaCoefficients: Arima coefficients.
type ArimaCoefficients struct {
	// AutoRegressiveCoefficients: Auto-regressive coefficients, an array of
	// double.
	AutoRegressiveCoefficients []float64 `json:"autoRegressiveCoefficients,omitempty"`

	// InterceptCoefficient: Intercept coefficient, just a double not an
	// array.
	InterceptCoefficient float64 `json:"interceptCoefficient,omitempty"`

	// MovingAverageCoefficients: Moving-average coefficients, an array of
	// double.
	MovingAverageCoefficients []float64 `json:"movingAverageCoefficients,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AutoRegressiveCoefficients") 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.
	// "AutoRegressiveCoefficients") 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 *ArimaCoefficients) MarshalJSON() ([]byte, error) {
	type NoMethod ArimaCoefficients
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// ArimaFittingMetrics: ARIMA model fitting metrics.
type ArimaFittingMetrics struct {
	// Aic: AIC
	Aic float64 `json:"aic,omitempty"`

	// LogLikelihood: log-likelihood
	LogLikelihood float64 `json:"logLikelihood,omitempty"`

	// Variance: variance.
	Variance float64 `json:"variance,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Aic") 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. "Aic") 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 *ArimaFittingMetrics) MarshalJSON() ([]byte, error) {
	type NoMethod ArimaFittingMetrics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ArimaFittingMetrics) UnmarshalJSON(data []byte) error {
	type NoMethod ArimaFittingMetrics
	var s1 struct {
		Aic           gensupport.JSONFloat64 `json:"aic"`
		LogLikelihood gensupport.JSONFloat64 `json:"logLikelihood"`
		Variance      gensupport.JSONFloat64 `json:"variance"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Aic = float64(s1.Aic)
	s.LogLikelihood = float64(s1.LogLikelihood)
	s.Variance = float64(s1.Variance)
	return nil
}

// ArimaModelInfo: Arima model information.
type ArimaModelInfo struct {
	// ArimaCoefficients: Arima coefficients.
	ArimaCoefficients *ArimaCoefficients `json:"arimaCoefficients,omitempty"`

	// ArimaFittingMetrics: Arima fitting metrics.
	ArimaFittingMetrics *ArimaFittingMetrics `json:"arimaFittingMetrics,omitempty"`

	// NonSeasonalOrder: Non-seasonal order.
	NonSeasonalOrder *ArimaOrder `json:"nonSeasonalOrder,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArimaCoefficients")
	// 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. "ArimaCoefficients") 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 *ArimaModelInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ArimaModelInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ArimaOrder: Arima order, can be used for both non-seasonal and
// seasonal parts.
type ArimaOrder struct {
	// D: Order of the differencing part.
	D int64 `json:"d,omitempty,string"`

	// P: Order of the autoregressive part.
	P int64 `json:"p,omitempty,string"`

	// Q: Order of the moving-average part.
	Q int64 `json:"q,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "D") 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. "D") 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 *ArimaOrder) MarshalJSON() ([]byte, error) {
	type NoMethod ArimaOrder
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ArimaResult: (Auto-)arima fitting result. Wrap everything in
// ArimaResult for easier
// refactoring if we want to use model-specific iteration results.
type ArimaResult struct {
	// ArimaModelInfo: This message is repeated because there are multiple
	// arima models
	// fitted in auto-arima. For non-auto-arima model, its size is one.
	ArimaModelInfo []*ArimaModelInfo `json:"arimaModelInfo,omitempty"`

	// SeasonalPeriods: Seasonal periods. Repeated because multiple periods
	// are supported for
	// one time series.
	//
	// Possible values:
	//   "SEASONAL_PERIOD_TYPE_UNSPECIFIED"
	//   "NO_SEASONALITY" - No seasonality
	//   "DAILY" - Daily period, 24 hours.
	//   "WEEKLY" - Weekly period, 7 days.
	//   "MONTHLY" - Monthly period, can be as 30 days or irregular.
	//   "QUARTERLY" - Quarterly period, can be as 90 days or irregular.
	//   "YEARLY" - Yearly period, can be as 365 days or irregular.
	SeasonalPeriods []string `json:"seasonalPeriods,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArimaModelInfo") 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. "ArimaModelInfo") 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 *ArimaResult) MarshalJSON() ([]byte, error) {
	type NoMethod ArimaResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BigQueryModelTraining struct {
	// CurrentIteration: [Output-only, Beta] Index of current ML training
	// iteration. Updated during create model query job to show job
	// progress.
	CurrentIteration int64 `json:"currentIteration,omitempty"`

	// ExpectedTotalIterations: [Output-only, Beta] Expected number of
	// iterations for the create model query job specified as num_iterations
	// in the input query. The actual total number of iterations may be less
	// than this number due to early stop.
	ExpectedTotalIterations int64 `json:"expectedTotalIterations,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CurrentIteration") 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. "CurrentIteration") 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 *BigQueryModelTraining) MarshalJSON() ([]byte, error) {
	type NoMethod BigQueryModelTraining
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BigtableColumn struct {
	// Encoding: [Optional] The encoding of the values when the type is not
	// STRING. Acceptable encoding values are: TEXT - indicates values are
	// alphanumeric text strings. BINARY - indicates values are encoded
	// using HBase Bytes.toBytes family of functions. 'encoding' can also be
	// set at the column family level. However, the setting at this level
	// takes precedence if 'encoding' is set at both levels.
	Encoding string `json:"encoding,omitempty"`

	// FieldName: [Optional] If the qualifier is not a valid BigQuery field
	// identifier i.e. does not match [a-zA-Z][a-zA-Z0-9_]*, a valid
	// identifier must be provided as the column field name and is used as
	// field name in queries.
	FieldName string `json:"fieldName,omitempty"`

	// OnlyReadLatest: [Optional] If this is set, only the latest version of
	// value in this column are exposed. 'onlyReadLatest' can also be set at
	// the column family level. However, the setting at this level takes
	// precedence if 'onlyReadLatest' is set at both levels.
	OnlyReadLatest bool `json:"onlyReadLatest,omitempty"`

	// QualifierEncoded: [Required] Qualifier of the column. Columns in the
	// parent column family that has this exact qualifier are exposed as .
	// field. If the qualifier is valid UTF-8 string, it can be specified in
	// the qualifier_string field. Otherwise, a base-64 encoded value must
	// be set to qualifier_encoded. The column field name is the same as the
	// column qualifier. However, if the qualifier is not a valid BigQuery
	// field identifier i.e. does not match [a-zA-Z][a-zA-Z0-9_]*, a valid
	// identifier must be provided as field_name.
	QualifierEncoded string `json:"qualifierEncoded,omitempty"`

	QualifierString string `json:"qualifierString,omitempty"`

	// Type: [Optional] The type to convert the value in cells of this
	// column. The values are expected to be encoded using HBase
	// Bytes.toBytes function when using the BINARY encoding value.
	// Following BigQuery types are allowed (case-sensitive) - BYTES STRING
	// INTEGER FLOAT BOOLEAN Default type is BYTES. 'type' can also be set
	// at the column family level. However, the setting at this level takes
	// precedence if 'type' is set at both levels.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Encoding") 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. "Encoding") 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 *BigtableColumn) MarshalJSON() ([]byte, error) {
	type NoMethod BigtableColumn
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BigtableColumnFamily struct {
	// Columns: [Optional] Lists of columns that should be exposed as
	// individual fields as opposed to a list of (column name, value) pairs.
	// All columns whose qualifier matches a qualifier in this list can be
	// accessed as .. Other columns can be accessed as a list through
	// .Column field.
	Columns []*BigtableColumn `json:"columns,omitempty"`

	// Encoding: [Optional] The encoding of the values when the type is not
	// STRING. Acceptable encoding values are: TEXT - indicates values are
	// alphanumeric text strings. BINARY - indicates values are encoded
	// using HBase Bytes.toBytes family of functions. This can be overridden
	// for a specific column by listing that column in 'columns' and
	// specifying an encoding for it.
	Encoding string `json:"encoding,omitempty"`

	// FamilyId: Identifier of the column family.
	FamilyId string `json:"familyId,omitempty"`

	// OnlyReadLatest: [Optional] If this is set only the latest version of
	// value are exposed for all columns in this column family. This can be
	// overridden for a specific column by listing that column in 'columns'
	// and specifying a different setting for that column.
	OnlyReadLatest bool `json:"onlyReadLatest,omitempty"`

	// Type: [Optional] The type to convert the value in cells of this
	// column family. The values are expected to be encoded using HBase
	// Bytes.toBytes function when using the BINARY encoding value.
	// Following BigQuery types are allowed (case-sensitive) - BYTES STRING
	// INTEGER FLOAT BOOLEAN Default type is BYTES. This can be overridden
	// for a specific column by listing that column in 'columns' and
	// specifying a type for it.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Columns") 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. "Columns") 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 *BigtableColumnFamily) MarshalJSON() ([]byte, error) {
	type NoMethod BigtableColumnFamily
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type BigtableOptions struct {
	// ColumnFamilies: [Optional] List of column families to expose in the
	// table schema along with their types. This list restricts the column
	// families that can be referenced in queries and specifies their value
	// types. You can use this list to do type conversions - see the 'type'
	// field for more details. If you leave this list empty, all column
	// families are present in the table schema and their values are read as
	// BYTES. During a query only the column families referenced in that
	// query are read from Bigtable.
	ColumnFamilies []*BigtableColumnFamily `json:"columnFamilies,omitempty"`

	// IgnoreUnspecifiedColumnFamilies: [Optional] If field is true, then
	// the column families that are not specified in columnFamilies list are
	// not exposed in the table schema. Otherwise, they are read with BYTES
	// type values. The default value is false.
	IgnoreUnspecifiedColumnFamilies bool `json:"ignoreUnspecifiedColumnFamilies,omitempty"`

	// ReadRowkeyAsString: [Optional] If field is true, then the rowkey
	// column families will be read and converted to string. Otherwise they
	// are read with BYTES type values and users need to manually cast them
	// with CAST if necessary. The default value is false.
	ReadRowkeyAsString bool `json:"readRowkeyAsString,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnFamilies") 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. "ColumnFamilies") 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 *BigtableOptions) MarshalJSON() ([]byte, error) {
	type NoMethod BigtableOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BinaryClassificationMetrics: Evaluation metrics for binary
// classification/classifier models.
type BinaryClassificationMetrics struct {
	// AggregateClassificationMetrics: Aggregate classification metrics.
	AggregateClassificationMetrics *AggregateClassificationMetrics `json:"aggregateClassificationMetrics,omitempty"`

	// BinaryConfusionMatrixList: Binary confusion matrix at multiple
	// thresholds.
	BinaryConfusionMatrixList []*BinaryConfusionMatrix `json:"binaryConfusionMatrixList,omitempty"`

	// NegativeLabel: Label representing the negative class.
	NegativeLabel string `json:"negativeLabel,omitempty"`

	// PositiveLabel: Label representing the positive class.
	PositiveLabel string `json:"positiveLabel,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AggregateClassificationMetrics") 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.
	// "AggregateClassificationMetrics") 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 *BinaryClassificationMetrics) MarshalJSON() ([]byte, error) {
	type NoMethod BinaryClassificationMetrics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BinaryConfusionMatrix: Confusion matrix for binary classification
// models.
type BinaryConfusionMatrix struct {
	// Accuracy: The fraction of predictions given the correct label.
	Accuracy float64 `json:"accuracy,omitempty"`

	// F1Score: The equally weighted average of recall and precision.
	F1Score float64 `json:"f1Score,omitempty"`

	// FalseNegatives: Number of false samples predicted as false.
	FalseNegatives int64 `json:"falseNegatives,omitempty,string"`

	// FalsePositives: Number of false samples predicted as true.
	FalsePositives int64 `json:"falsePositives,omitempty,string"`

	// PositiveClassThreshold: Threshold value used when computing each of
	// the following metric.
	PositiveClassThreshold float64 `json:"positiveClassThreshold,omitempty"`

	// Precision: The fraction of actual positive predictions that had
	// positive actual
	// labels.
	Precision float64 `json:"precision,omitempty"`

	// Recall: The fraction of actual positive labels that were given a
	// positive
	// prediction.
	Recall float64 `json:"recall,omitempty"`

	// TrueNegatives: Number of true samples predicted as false.
	TrueNegatives int64 `json:"trueNegatives,omitempty,string"`

	// TruePositives: Number of true samples predicted as true.
	TruePositives int64 `json:"truePositives,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Accuracy") 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. "Accuracy") 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 *BinaryConfusionMatrix) MarshalJSON() ([]byte, error) {
	type NoMethod BinaryConfusionMatrix
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *BinaryConfusionMatrix) UnmarshalJSON(data []byte) error {
	type NoMethod BinaryConfusionMatrix
	var s1 struct {
		Accuracy               gensupport.JSONFloat64 `json:"accuracy"`
		F1Score                gensupport.JSONFloat64 `json:"f1Score"`
		PositiveClassThreshold gensupport.JSONFloat64 `json:"positiveClassThreshold"`
		Precision              gensupport.JSONFloat64 `json:"precision"`
		Recall                 gensupport.JSONFloat64 `json:"recall"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Accuracy = float64(s1.Accuracy)
	s.F1Score = float64(s1.F1Score)
	s.PositiveClassThreshold = float64(s1.PositiveClassThreshold)
	s.Precision = float64(s1.Precision)
	s.Recall = float64(s1.Recall)
	return nil
}

type BqmlIterationResult struct {
	// DurationMs: [Output-only, Beta] Time taken to run the training
	// iteration in milliseconds.
	DurationMs int64 `json:"durationMs,omitempty,string"`

	// EvalLoss: [Output-only, Beta] Eval loss computed on the eval data at
	// the end of the iteration. The eval loss is used for early stopping to
	// avoid overfitting. No eval loss if eval_split_method option is
	// specified as no_split or auto_split with input data size less than
	// 500 rows.
	EvalLoss float64 `json:"evalLoss,omitempty"`

	// Index: [Output-only, Beta] Index of the ML training iteration,
	// starting from zero for each training run.
	Index int64 `json:"index,omitempty"`

	// LearnRate: [Output-only, Beta] Learning rate used for this iteration,
	// it varies for different training iterations if learn_rate_strategy
	// option is not constant.
	LearnRate float64 `json:"learnRate,omitempty"`

	// TrainingLoss: [Output-only, Beta] Training loss computed on the
	// training data at the end of the iteration. The training loss function
	// is defined by model type.
	TrainingLoss float64 `json:"trainingLoss,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DurationMs") 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. "DurationMs") 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 *BqmlIterationResult) MarshalJSON() ([]byte, error) {
	type NoMethod BqmlIterationResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *BqmlIterationResult) UnmarshalJSON(data []byte) error {
	type NoMethod BqmlIterationResult
	var s1 struct {
		EvalLoss     gensupport.JSONFloat64 `json:"evalLoss"`
		LearnRate    gensupport.JSONFloat64 `json:"learnRate"`
		TrainingLoss gensupport.JSONFloat64 `json:"trainingLoss"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.EvalLoss = float64(s1.EvalLoss)
	s.LearnRate = float64(s1.LearnRate)
	s.TrainingLoss = float64(s1.TrainingLoss)
	return nil
}

type BqmlTrainingRun struct {
	// IterationResults: [Output-only, Beta] List of each iteration results.
	IterationResults []*BqmlIterationResult `json:"iterationResults,omitempty"`

	// StartTime: [Output-only, Beta] Training run start time in
	// milliseconds since the epoch.
	StartTime string `json:"startTime,omitempty"`

	// State: [Output-only, Beta] Different state applicable for a training
	// run. IN PROGRESS: Training run is in progress. FAILED: Training run
	// ended due to a non-retryable failure. SUCCEEDED: Training run
	// successfully completed. CANCELLED: Training run cancelled by the
	// user.
	State string `json:"state,omitempty"`

	// TrainingOptions: [Output-only, Beta] Training options used by this
	// training run. These options are mutable for subsequent training runs.
	// Default values are explicitly stored for options not specified in the
	// input query of the first training run. For subsequent training runs,
	// any option not explicitly specified in the input query will be copied
	// from the previous training run.
	TrainingOptions *BqmlTrainingRunTrainingOptions `json:"trainingOptions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IterationResults") 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. "IterationResults") 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 *BqmlTrainingRun) MarshalJSON() ([]byte, error) {
	type NoMethod BqmlTrainingRun
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BqmlTrainingRunTrainingOptions: [Output-only, Beta] Training options
// used by this training run. These options are mutable for subsequent
// training runs. Default values are explicitly stored for options not
// specified in the input query of the first training run. For
// subsequent training runs, any option not explicitly specified in the
// input query will be copied from the previous training run.
type BqmlTrainingRunTrainingOptions struct {
	EarlyStop bool `json:"earlyStop,omitempty"`

	L1Reg float64 `json:"l1Reg,omitempty"`

	L2Reg float64 `json:"l2Reg,omitempty"`

	LearnRate float64 `json:"learnRate,omitempty"`

	LearnRateStrategy string `json:"learnRateStrategy,omitempty"`

	LineSearchInitLearnRate float64 `json:"lineSearchInitLearnRate,omitempty"`

	MaxIteration int64 `json:"maxIteration,omitempty,string"`

	MinRelProgress float64 `json:"minRelProgress,omitempty"`

	WarmStart bool `json:"warmStart,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EarlyStop") 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. "EarlyStop") 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 *BqmlTrainingRunTrainingOptions) MarshalJSON() ([]byte, error) {
	type NoMethod BqmlTrainingRunTrainingOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *BqmlTrainingRunTrainingOptions) UnmarshalJSON(data []byte) error {
	type NoMethod BqmlTrainingRunTrainingOptions
	var s1 struct {
		L1Reg                   gensupport.JSONFloat64 `json:"l1Reg"`
		L2Reg                   gensupport.JSONFloat64 `json:"l2Reg"`
		LearnRate               gensupport.JSONFloat64 `json:"learnRate"`
		LineSearchInitLearnRate gensupport.JSONFloat64 `json:"lineSearchInitLearnRate"`
		MinRelProgress          gensupport.JSONFloat64 `json:"minRelProgress"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.L1Reg = float64(s1.L1Reg)
	s.L2Reg = float64(s1.L2Reg)
	s.LearnRate = float64(s1.LearnRate)
	s.LineSearchInitLearnRate = float64(s1.LineSearchInitLearnRate)
	s.MinRelProgress = float64(s1.MinRelProgress)
	return nil
}

// CategoricalValue: Representative value of a categorical feature.
type CategoricalValue struct {
	// CategoryCounts: Counts of all categories for the categorical feature.
	// If there are
	// more than ten categories, we return top ten (by count) and return
	// one more CategoryCount with category "_OTHER_" and count as
	// aggregate counts of remaining categories.
	CategoryCounts []*CategoryCount `json:"categoryCounts,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CategoryCounts") 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. "CategoryCounts") 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 *CategoricalValue) MarshalJSON() ([]byte, error) {
	type NoMethod CategoricalValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CategoryCount: Represents the count of a single category within the
// cluster.
type CategoryCount struct {
	// Category: The name of category.
	Category string `json:"category,omitempty"`

	// Count: The count of training samples matching the category within
	// the
	// cluster.
	Count int64 `json:"count,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Category") 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. "Category") 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 *CategoryCount) MarshalJSON() ([]byte, error) {
	type NoMethod CategoryCount
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Cluster: Message containing the information about one cluster.
type Cluster struct {
	// CentroidId: Centroid id.
	CentroidId int64 `json:"centroidId,omitempty,string"`

	// Count: Count of training data rows that were assigned to this
	// cluster.
	Count int64 `json:"count,omitempty,string"`

	// FeatureValues: Values of highly variant features for this cluster.
	FeatureValues []*FeatureValue `json:"featureValues,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CentroidId") 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. "CentroidId") 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 *Cluster) MarshalJSON() ([]byte, error) {
	type NoMethod Cluster
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ClusterInfo: Information about a single cluster for clustering model.
type ClusterInfo struct {
	// CentroidId: Centroid id.
	CentroidId int64 `json:"centroidId,omitempty,string"`

	// ClusterRadius: Cluster radius, the average distance from centroid
	// to each point assigned to the cluster.
	ClusterRadius float64 `json:"clusterRadius,omitempty"`

	// ClusterSize: Cluster size, the total number of points assigned to the
	// cluster.
	ClusterSize int64 `json:"clusterSize,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CentroidId") 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. "CentroidId") 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 *ClusterInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ClusterInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

type Clustering struct {
	// Fields: [Repeated] One or more fields on which data should be
	// clustered. Only top-level, non-repeated, simple-type fields are
	// supported. When you cluster a table using multiple columns, the order
	// of columns you specify is important. The order of the specified
	// columns determines the sort order of the data.
	Fields []string `json:"fields,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") 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. "Fields") 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 *Clustering) MarshalJSON() ([]byte, error) {
	type NoMethod Clustering
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ClusteringMetrics: Evaluation metrics for clustering models.
type ClusteringMetrics struct {
	// Clusters: [Beta] Information for all clusters.
	Clusters []*Cluster `json:"clusters,omitempty"`

	// DaviesBouldinIndex: Davies-Bouldin index.
	DaviesBouldinIndex float64 `json:"daviesBouldinIndex,omitempty"`

	// MeanSquaredDistance: Mean of squared distances between each sample to
	// its cluster centroid.
	MeanSquaredDistance float64 `json:"meanSquaredDistance,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Clusters") 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. "Clusters") 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 *ClusteringMetrics) MarshalJSON() ([]byte, error) {
	type NoMethod ClusteringMetrics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// ConfusionMatrix: Confusion matrix for multi-class classification
// models.
type ConfusionMatrix struct {
	// ConfidenceThreshold: Confidence threshold used when computing the
	// entries of the
	// confusion matrix.
	ConfidenceThreshold float64 `json:"confidenceThreshold,omitempty"`

	// Rows: One row per actual label.
	Rows []*Row `json:"rows,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ConfidenceThreshold")
	// 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. "ConfidenceThreshold") 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 *ConfusionMatrix) MarshalJSON() ([]byte, error) {
	type NoMethod ConfusionMatrix
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

type CsvOptions struct {
	// AllowJaggedRows: [Optional] Indicates if BigQuery should accept rows
	// that are missing trailing optional columns. If true, BigQuery treats
	// missing trailing columns as null values. If false, records with
	// missing trailing columns are treated as bad records, and if there are
	// too many bad records, an invalid error is returned in the job result.
	// The default value is false.
	AllowJaggedRows bool `json:"allowJaggedRows,omitempty"`

	// AllowQuotedNewlines: [Optional] Indicates if BigQuery should allow
	// quoted data sections that contain newline characters in a CSV file.
	// The default value is false.
	AllowQuotedNewlines bool `json:"allowQuotedNewlines,omitempty"`

	// Encoding: [Optional] The character encoding of the data. The
	// supported values are UTF-8 or ISO-8859-1. The default value is UTF-8.
	// BigQuery decodes the data after the raw, binary data has been split
	// using the values of the quote and fieldDelimiter properties.
	Encoding string `json:"encoding,omitempty"`

	// FieldDelimiter: [Optional] The separator for fields in a CSV file.
	// BigQuery converts the string to ISO-8859-1 encoding, and then uses
	// the first byte of the encoded string to split the data in its raw,
	// binary state. BigQuery also supports the escape sequence "\t" to
	// specify a tab separator. The default value is a comma (',').
	FieldDelimiter string `json:"fieldDelimiter,omitempty"`

	// Quote: [Optional] The value that is used to quote data sections in a
	// CSV file. BigQuery converts the string to ISO-8859-1 encoding, and
	// then uses the first byte of the encoded string to split the data in
	// its raw, binary state. The default value is a double-quote ('"'). If
	// your data does not contain quoted sections, set the property value to
	// an empty string. If your data contains quoted newline characters, you
	// must also set the allowQuotedNewlines property to true.
	//
	// Default: "
	Quote *string `json:"quote,omitempty"`

	// SkipLeadingRows: [Optional] The number of rows at the top of a CSV
	// file that BigQuery will skip when reading the data. The default value
	// is 0. This property is useful if you have header rows in the file
	// that should be skipped. When autodetect is on, the behavior is the
	// following: * skipLeadingRows unspecified - Autodetect tries to detect
	// headers in the first row. If they are not detected, the row is read
	// as data. Otherwise data is read starting from the second row. *
	// skipLeadingRows is 0 - Instructs autodetect that there are no headers
	// and data should be read starting from the first row. *
	// skipLeadingRows = N > 0 - Autodetect skips N-1 rows and tries to
	// detect headers in row N. If headers are not detected, row N is just
	// skipped. Otherwise row N is used to extract column names for the
	// detected schema.
	SkipLeadingRows int64 `json:"skipLeadingRows,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "AllowJaggedRows") 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. "AllowJaggedRows") 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 *CsvOptions) MarshalJSON() ([]byte, error) {
	type NoMethod CsvOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DataSplitResult: Data split result. This contains references to the
// training and evaluation
// data tables that were used to train the model.
type DataSplitResult struct {
	// EvaluationTable: Table reference of the evaluation data after split.
	EvaluationTable *TableReference `json:"evaluationTable,omitempty"`

	// TrainingTable: Table reference of the training data after split.
	TrainingTable *TableReference `json:"trainingTable,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EvaluationTable") 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. "EvaluationTable") 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 *DataSplitResult) MarshalJSON() ([]byte, error) {
	type NoMethod DataSplitResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type Dataset struct {
	// Access: [Optional] An array of objects that define dataset access for
	// one or more entities. You can set this property when inserting or
	// updating a dataset in order to control who is allowed to access the
	// data. If unspecified at dataset creation time, BigQuery adds default
	// dataset access for the following entities: access.specialGroup:
	// projectReaders; access.role: READER; access.specialGroup:
	// projectWriters; access.role: WRITER; access.specialGroup:
	// projectOwners; access.role: OWNER; access.userByEmail: [dataset
	// creator email]; access.role: OWNER;
	Access []*DatasetAccess `json:"access,omitempty"`

	// CreationTime: [Output-only] The time when this dataset was created,
	// in milliseconds since the epoch.
	CreationTime int64 `json:"creationTime,omitempty,string"`

	// DatasetReference: [Required] A reference that identifies the dataset.
	DatasetReference *DatasetReference `json:"datasetReference,omitempty"`

	DefaultEncryptionConfiguration *EncryptionConfiguration `json:"defaultEncryptionConfiguration,omitempty"`

	// DefaultPartitionExpirationMs: [Optional] The default partition
	// expiration for all partitioned tables in the dataset, in
	// milliseconds. Once this property is set, all newly-created
	// partitioned tables in the dataset will have an expirationMs property
	// in the timePartitioning settings set to this value, and changing the
	// value will only affect new tables, not existing ones. The storage in
	// a partition will have an expiration time of its partition time plus
	// this value. Setting this property overrides the use of
	// defaultTableExpirationMs for partitioned tables: only one of
	// defaultTableExpirationMs and defaultPartitionExpirationMs will be
	// used for any new partitioned table. If you provide an explicit
	// timePartitioning.expirationMs when creating or updating a partitioned
	// table, that value takes precedence over the default partition
	// expiration time indicated by this property.
	DefaultPartitionExpirationMs int64 `json:"defaultPartitionExpirationMs,omitempty,string"`

	// DefaultTableExpirationMs: [Optional] The default lifetime of all
	// tables in the dataset, in milliseconds. The minimum value is 3600000
	// milliseconds (one hour). Once this property is set, all newly-created
	// tables in the dataset will have an expirationTime property set to the
	// creation time plus the value in this property, and changing the value
	// will only affect new tables, not existing ones. When the
	// expirationTime for a given table is reached, that table will be
	// deleted automatically. If a table's expirationTime is modified or
	// removed before the table expires, or if you provide an explicit
	// expirationTime when creating a table, that value takes precedence
	// over the default expiration time indicated by this property.
	DefaultTableExpirationMs int64 `json:"defaultTableExpirationMs,omitempty,string"`

	// Description: [Optional] A user-friendly description of the dataset.
	Description string `json:"description,omitempty"`

	// Etag: [Output-only] A hash of the resource.
	Etag string `json:"etag,omitempty"`

	// FriendlyName: [Optional] A descriptive name for the dataset.
	FriendlyName string `json:"friendlyName,omitempty"`

	// Id: [Output-only] The fully-qualified unique name of the dataset in
	// the format projectId:datasetId. The dataset name without the project
	// name is given in the datasetId field. When creating a new dataset,
	// leave this field blank, and instead specify the datasetId field.
	Id string `json:"id,omitempty"`

	// Kind: [Output-only] The resource type.
	Kind string `json:"kind,omitempty"`

	// Labels: The labels associated with this dataset. You can use these to
	// organize and group your datasets. You can set this property when
	// inserting or updating a dataset. See Creating and Updating Dataset
	// Labels for more information.
	Labels map[string]string `json:"labels,omitempty"`

	// LastModifiedTime: [Output-only] The date when this dataset or any of
	// its tables was last modified, in milliseconds since the epoch.
	LastModifiedTime int64 `json:"lastModifiedTime,omitempty,string"`

	// Location: The geographic location where the dataset should reside.
	// The default value is US. See details at
	// https://cloud.google.com/bigquery/docs/locations.
	Location string `json:"location,omitempty"`

	// SelfLink: [Output-only] A URL that can be used to access the resource
	// again. You can use this URL in Get or Update requests to the
	// resource.
	SelfLink string `json:"selfLink,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Access") 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. "Access") 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 *Dataset) MarshalJSON() ([]byte, error) {
	type NoMethod Dataset
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DatasetAccess struct {
	// Domain: [Pick one] A domain to grant access to. Any users signed in
	// with the domain specified will be granted the specified access.
	// Example: "example.com". Maps to IAM policy member "domain:DOMAIN".
	Domain string `json:"domain,omitempty"`

	// GroupByEmail: [Pick one] An email address of a Google Group to grant
	// access to. Maps to IAM policy member "group:GROUP".
	GroupByEmail string `json:"groupByEmail,omitempty"`

	// IamMember: [Pick one] Some other type of member that appears in the
	// IAM Policy but isn't a user, group, domain, or special group.
	IamMember string `json:"iamMember,omitempty"`

	// Role: [Required] An IAM role ID that should be granted to the user,
	// group, or domain specified in this access entry. The following legacy
	// mappings will be applied: OWNER  roles/bigquery.dataOwner WRITER
	// roles/bigquery.dataEditor READER  roles/bigquery.dataViewer This
	// field will accept any of the above formats, but will return only the
	// legacy format. For example, if you set this field to
	// "roles/bigquery.dataOwner", it will be returned back as "OWNER".
	Role string `json:"role,omitempty"`

	// SpecialGroup: [Pick one] A special group to grant access to. Possible
	// values include: projectOwners: Owners of the enclosing project.
	// projectReaders: Readers of the enclosing project. projectWriters:
	// Writers of the enclosing project. allAuthenticatedUsers: All
	// authenticated BigQuery users. Maps to similarly-named IAM members.
	SpecialGroup string `json:"specialGroup,omitempty"`

	// UserByEmail: [Pick one] An email address of a user to grant access
	// to. For example: fred@example.com. Maps to IAM policy member
	// "user:EMAIL" or "serviceAccount:EMAIL".
	UserByEmail string `json:"userByEmail,omitempty"`

	// View: [Pick one] A view from a different dataset to grant access to.
	// Queries executed against that view will have read access to tables in
	// this dataset. The role field is not required when this field is set.
	// If that view is updated by any user, access to the view needs to be
	// granted again via an update operation.
	View *TableReference `json:"view,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Domain") 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. "Domain") 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 *DatasetAccess) MarshalJSON() ([]byte, error) {
	type NoMethod DatasetAccess
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DatasetList struct {
	// Datasets: An array of the dataset resources in the project. Each
	// resource contains basic information. For full information about a
	// particular dataset resource, use the Datasets: get method. This
	// property is omitted when there are no datasets in the project.
	Datasets []*DatasetListDatasets `json:"datasets,omitempty"`

	// Etag: A hash value of the results page. You can use this property to
	// determine if the page has changed since the last request.
	Etag string `json:"etag,omitempty"`

	// Kind: The list type. This property always returns the value
	// "bigquery#datasetList".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: A token that can be used to request the next results
	// page. This property is omitted on the final results page.
	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. "Datasets") 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. "Datasets") 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 *DatasetList) MarshalJSON() ([]byte, error) {
	type NoMethod DatasetList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DatasetListDatasets struct {
	// DatasetReference: The dataset reference. Use this property to access
	// specific parts of the dataset's ID, such as project ID or dataset ID.
	DatasetReference *DatasetReference `json:"datasetReference,omitempty"`

	// FriendlyName: A descriptive name for the dataset, if one exists.
	FriendlyName string `json:"friendlyName,omitempty"`

	// Id: The fully-qualified, unique, opaque ID of the dataset.
	Id string `json:"id,omitempty"`

	// Kind: The resource type. This property always returns the value
	// "bigquery#dataset".
	Kind string `json:"kind,omitempty"`

	// Labels: The labels associated with this dataset. You can use these to
	// organize and group your datasets.
	Labels map[string]string `json:"labels,omitempty"`

	// Location: The geographic location where the data resides.
	Location string `json:"location,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DatasetReference") 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. "DatasetReference") 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 *DatasetListDatasets) MarshalJSON() ([]byte, error) {
	type NoMethod DatasetListDatasets
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DatasetReference struct {
	// DatasetId: [Required] A unique ID for this dataset, without the
	// project name. The ID must contain only letters (a-z, A-Z), numbers
	// (0-9), or underscores (_). The maximum length is 1,024 characters.
	DatasetId string `json:"datasetId,omitempty"`

	// ProjectId: [Optional] The ID of the project containing this dataset.
	ProjectId string `json:"projectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DatasetId") 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. "DatasetId") 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 *DatasetReference) MarshalJSON() ([]byte, error) {
	type NoMethod DatasetReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type DestinationTableProperties struct {
	// Description: [Optional] The description for the destination table.
	// This will only be used if the destination table is newly created. If
	// the table already exists and a value different than the current
	// description is provided, the job will fail.
	Description string `json:"description,omitempty"`

	// FriendlyName: [Optional] The friendly name for the destination table.
	// This will only be used if the destination table is newly created. If
	// the table already exists and a value different than the current
	// friendly name is provided, the job will fail.
	FriendlyName string `json:"friendlyName,omitempty"`

	// Labels: [Optional] The labels associated with this table. You can use
	// these to organize and group your tables. This will only be used if
	// the destination table is newly created. If the table already exists
	// and labels are different than the current labels are provided, the
	// job will fail.
	Labels map[string]string `json:"labels,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 *DestinationTableProperties) MarshalJSON() ([]byte, error) {
	type NoMethod DestinationTableProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type EncryptionConfiguration struct {
	// KmsKeyName: [Optional] Describes the Cloud KMS encryption key that
	// will be used to protect destination BigQuery table. The BigQuery
	// Service Account associated with your project requires access to this
	// encryption key.
	KmsKeyName string `json:"kmsKeyName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "KmsKeyName") 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. "KmsKeyName") 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 *EncryptionConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod EncryptionConfiguration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Entry: A single entry in the confusion matrix.
type Entry struct {
	// ItemCount: Number of items being predicted as this label.
	ItemCount int64 `json:"itemCount,omitempty,string"`

	// PredictedLabel: The predicted label. For confidence_threshold > 0, we
	// will
	// also add an entry indicating the number of items under the
	// confidence threshold.
	PredictedLabel string `json:"predictedLabel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ItemCount") 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. "ItemCount") 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 *Entry) MarshalJSON() ([]byte, error) {
	type NoMethod Entry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ErrorProto struct {
	// DebugInfo: Debugging information. This property is internal to Google
	// and should not be used.
	DebugInfo string `json:"debugInfo,omitempty"`

	// Location: Specifies where the error occurred, if present.
	Location string `json:"location,omitempty"`

	// Message: A human-readable description of the error.
	Message string `json:"message,omitempty"`

	// Reason: A short error code that summarizes the error.
	Reason string `json:"reason,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DebugInfo") 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. "DebugInfo") 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 *ErrorProto) MarshalJSON() ([]byte, error) {
	type NoMethod ErrorProto
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EvaluationMetrics: Evaluation metrics of a model. These are either
// computed on all training
// data or just the eval data based on whether eval data was used
// during
// training. These are not present for imported models.
type EvaluationMetrics struct {
	// BinaryClassificationMetrics: Populated for binary
	// classification/classifier models.
	BinaryClassificationMetrics *BinaryClassificationMetrics `json:"binaryClassificationMetrics,omitempty"`

	// ClusteringMetrics: Populated for clustering models.
	ClusteringMetrics *ClusteringMetrics `json:"clusteringMetrics,omitempty"`

	// MultiClassClassificationMetrics: Populated for multi-class
	// classification/classifier models.
	MultiClassClassificationMetrics *MultiClassClassificationMetrics `json:"multiClassClassificationMetrics,omitempty"`

	// RankingMetrics: [Alpha] Populated for implicit feedback type matrix
	// factorization
	// models.
	RankingMetrics *RankingMetrics `json:"rankingMetrics,omitempty"`

	// RegressionMetrics: Populated for regression models and explicit
	// feedback type matrix
	// factorization models.
	RegressionMetrics *RegressionMetrics `json:"regressionMetrics,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "BinaryClassificationMetrics") 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.
	// "BinaryClassificationMetrics") 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 *EvaluationMetrics) MarshalJSON() ([]byte, error) {
	type NoMethod EvaluationMetrics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ExplainQueryStage struct {
	// CompletedParallelInputs: Number of parallel input segments completed.
	CompletedParallelInputs int64 `json:"completedParallelInputs,omitempty,string"`

	// ComputeMsAvg: Milliseconds the average shard spent on CPU-bound
	// tasks.
	ComputeMsAvg int64 `json:"computeMsAvg,omitempty,string"`

	// ComputeMsMax: Milliseconds the slowest shard spent on CPU-bound
	// tasks.
	ComputeMsMax int64 `json:"computeMsMax,omitempty,string"`

	// ComputeRatioAvg: Relative amount of time the average shard spent on
	// CPU-bound tasks.
	ComputeRatioAvg float64 `json:"computeRatioAvg,omitempty"`

	// ComputeRatioMax: Relative amount of time the slowest shard spent on
	// CPU-bound tasks.
	ComputeRatioMax float64 `json:"computeRatioMax,omitempty"`

	// EndMs: Stage end time represented as milliseconds since epoch.
	EndMs int64 `json:"endMs,omitempty,string"`

	// Id: Unique ID for stage within plan.
	Id int64 `json:"id,omitempty,string"`

	// InputStages: IDs for stages that are inputs to this stage.
	InputStages googleapi.Int64s `json:"inputStages,omitempty"`

	// Name: Human-readable name for stage.
	Name string `json:"name,omitempty"`

	// ParallelInputs: Number of parallel input segments to be processed.
	ParallelInputs int64 `json:"parallelInputs,omitempty,string"`

	// ReadMsAvg: Milliseconds the average shard spent reading input.
	ReadMsAvg int64 `json:"readMsAvg,omitempty,string"`

	// ReadMsMax: Milliseconds the slowest shard spent reading input.
	ReadMsMax int64 `json:"readMsMax,omitempty,string"`

	// ReadRatioAvg: Relative amount of time the average shard spent reading
	// input.
	ReadRatioAvg float64 `json:"readRatioAvg,omitempty"`

	// ReadRatioMax: Relative amount of time the slowest shard spent reading
	// input.
	ReadRatioMax float64 `json:"readRatioMax,omitempty"`

	// RecordsRead: Number of records read into the stage.
	RecordsRead int64 `json:"recordsRead,omitempty,string"`

	// RecordsWritten: Number of records written by the stage.
	RecordsWritten int64 `json:"recordsWritten,omitempty,string"`

	// ShuffleOutputBytes: Total number of bytes written to shuffle.
	ShuffleOutputBytes int64 `json:"shuffleOutputBytes,omitempty,string"`

	// ShuffleOutputBytesSpilled: Total number of bytes written to shuffle
	// and spilled to disk.
	ShuffleOutputBytesSpilled int64 `json:"shuffleOutputBytesSpilled,omitempty,string"`

	// SlotMs: Slot-milliseconds used by the stage.
	SlotMs int64 `json:"slotMs,omitempty,string"`

	// StartMs: Stage start time represented as milliseconds since epoch.
	StartMs int64 `json:"startMs,omitempty,string"`

	// Status: Current status for the stage.
	Status string `json:"status,omitempty"`

	// Steps: List of operations within the stage in dependency order
	// (approximately chronological).
	Steps []*ExplainQueryStep `json:"steps,omitempty"`

	// WaitMsAvg: Milliseconds the average shard spent waiting to be
	// scheduled.
	WaitMsAvg int64 `json:"waitMsAvg,omitempty,string"`

	// WaitMsMax: Milliseconds the slowest shard spent waiting to be
	// scheduled.
	WaitMsMax int64 `json:"waitMsMax,omitempty,string"`

	// WaitRatioAvg: Relative amount of time the average shard spent waiting
	// to be scheduled.
	WaitRatioAvg float64 `json:"waitRatioAvg,omitempty"`

	// WaitRatioMax: Relative amount of time the slowest shard spent waiting
	// to be scheduled.
	WaitRatioMax float64 `json:"waitRatioMax,omitempty"`

	// WriteMsAvg: Milliseconds the average shard spent on writing output.
	WriteMsAvg int64 `json:"writeMsAvg,omitempty,string"`

	// WriteMsMax: Milliseconds the slowest shard spent on writing output.
	WriteMsMax int64 `json:"writeMsMax,omitempty,string"`

	// WriteRatioAvg: Relative amount of time the average shard spent on
	// writing output.
	WriteRatioAvg float64 `json:"writeRatioAvg,omitempty"`

	// WriteRatioMax: Relative amount of time the slowest shard spent on
	// writing output.
	WriteRatioMax float64 `json:"writeRatioMax,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "CompletedParallelInputs") 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. "CompletedParallelInputs")
	// 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 *ExplainQueryStage) MarshalJSON() ([]byte, error) {
	type NoMethod ExplainQueryStage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ExplainQueryStage) UnmarshalJSON(data []byte) error {
	type NoMethod ExplainQueryStage
	var s1 struct {
		ComputeRatioAvg gensupport.JSONFloat64 `json:"computeRatioAvg"`
		ComputeRatioMax gensupport.JSONFloat64 `json:"computeRatioMax"`
		ReadRatioAvg    gensupport.JSONFloat64 `json:"readRatioAvg"`
		ReadRatioMax    gensupport.JSONFloat64 `json:"readRatioMax"`
		WaitRatioAvg    gensupport.JSONFloat64 `json:"waitRatioAvg"`
		WaitRatioMax    gensupport.JSONFloat64 `json:"waitRatioMax"`
		WriteRatioAvg   gensupport.JSONFloat64 `json:"writeRatioAvg"`
		WriteRatioMax   gensupport.JSONFloat64 `json:"writeRatioMax"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.ComputeRatioAvg = float64(s1.ComputeRatioAvg)
	s.ComputeRatioMax = float64(s1.ComputeRatioMax)
	s.ReadRatioAvg = float64(s1.ReadRatioAvg)
	s.ReadRatioMax = float64(s1.ReadRatioMax)
	s.WaitRatioAvg = float64(s1.WaitRatioAvg)
	s.WaitRatioMax = float64(s1.WaitRatioMax)
	s.WriteRatioAvg = float64(s1.WriteRatioAvg)
	s.WriteRatioMax = float64(s1.WriteRatioMax)
	return nil
}

type ExplainQueryStep struct {
	// Kind: Machine-readable operation type.
	Kind string `json:"kind,omitempty"`

	// Substeps: Human-readable stage descriptions.
	Substeps []string `json:"substeps,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Kind") 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. "Kind") 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 *ExplainQueryStep) MarshalJSON() ([]byte, error) {
	type NoMethod ExplainQueryStep
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ExternalDataConfiguration struct {
	// Autodetect: Try to detect schema and format options automatically.
	// Any option specified explicitly will be honored.
	Autodetect bool `json:"autodetect,omitempty"`

	// BigtableOptions: [Optional] Additional options if sourceFormat is set
	// to BIGTABLE.
	BigtableOptions *BigtableOptions `json:"bigtableOptions,omitempty"`

	// Compression: [Optional] The compression type of the data source.
	// Possible values include GZIP and NONE. The default value is NONE.
	// This setting is ignored for Google Cloud Bigtable, Google Cloud
	// Datastore backups and Avro formats.
	Compression string `json:"compression,omitempty"`

	// CsvOptions: Additional properties to set if sourceFormat is set to
	// CSV.
	CsvOptions *CsvOptions `json:"csvOptions,omitempty"`

	// GoogleSheetsOptions: [Optional] Additional options if sourceFormat is
	// set to GOOGLE_SHEETS.
	GoogleSheetsOptions *GoogleSheetsOptions `json:"googleSheetsOptions,omitempty"`

	// HivePartitioningMode: [Optional, Trusted Tester] Deprecated, do not
	// use. Please set hivePartitioningOptions instead.
	HivePartitioningMode string `json:"hivePartitioningMode,omitempty"`

	// HivePartitioningOptions: [Optional, Trusted Tester] Options to
	// configure hive partitioning support.
	HivePartitioningOptions *HivePartitioningOptions `json:"hivePartitioningOptions,omitempty"`

	// IgnoreUnknownValues: [Optional] Indicates if BigQuery should allow
	// extra values that are not represented in the table schema. If true,
	// the extra values are ignored. If false, records with extra columns
	// are treated as bad records, and if there are too many bad records, an
	// invalid error is returned in the job result. The default value is
	// false. The sourceFormat property determines what BigQuery treats as
	// an extra value: CSV: Trailing columns JSON: Named values that don't
	// match any column names Google Cloud Bigtable: This setting is
	// ignored. Google Cloud Datastore backups: This setting is ignored.
	// Avro: This setting is ignored.
	IgnoreUnknownValues bool `json:"ignoreUnknownValues,omitempty"`

	// MaxBadRecords: [Optional] The maximum number of bad records that
	// BigQuery can ignore when reading data. If the number of bad records
	// exceeds this value, an invalid error is returned in the job result.
	// This is only valid for CSV, JSON, and Google Sheets. The default
	// value is 0, which requires that all records are valid. This setting
	// is ignored for Google Cloud Bigtable, Google Cloud Datastore backups
	// and Avro formats.
	MaxBadRecords int64 `json:"maxBadRecords,omitempty"`

	// Schema: [Optional] The schema for the data. Schema is required for
	// CSV and JSON formats. Schema is disallowed for Google Cloud Bigtable,
	// Cloud Datastore backups, and Avro formats.
	Schema *TableSchema `json:"schema,omitempty"`

	// SourceFormat: [Required] The data format. For CSV files, specify
	// "CSV". For Google sheets, specify "GOOGLE_SHEETS". For
	// newline-delimited JSON, specify "NEWLINE_DELIMITED_JSON". For Avro
	// files, specify "AVRO". For Google Cloud Datastore backups, specify
	// "DATASTORE_BACKUP". [Beta] For Google Cloud Bigtable, specify
	// "BIGTABLE".
	SourceFormat string `json:"sourceFormat,omitempty"`

	// SourceUris: [Required] The fully-qualified URIs that point to your
	// data in Google Cloud. For Google Cloud Storage URIs: Each URI can
	// contain one '*' wildcard character and it must come after the
	// 'bucket' name. Size limits related to load jobs apply to external
	// data sources. For Google Cloud Bigtable URIs: Exactly one URI can be
	// specified and it has be a fully specified and valid HTTPS URL for a
	// Google Cloud Bigtable table. For Google Cloud Datastore backups,
	// exactly one URI can be specified. Also, the '*' wildcard character is
	// not allowed.
	SourceUris []string `json:"sourceUris,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Autodetect") 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. "Autodetect") 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 *ExternalDataConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod ExternalDataConfiguration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FeatureValue: Representative value of a single feature within the
// cluster.
type FeatureValue struct {
	// CategoricalValue: The categorical feature value.
	CategoricalValue *CategoricalValue `json:"categoricalValue,omitempty"`

	// FeatureColumn: The feature column name.
	FeatureColumn string `json:"featureColumn,omitempty"`

	// NumericalValue: The numerical feature value. This is the centroid
	// value for this
	// feature.
	NumericalValue float64 `json:"numericalValue,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CategoricalValue") 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. "CategoricalValue") 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 *FeatureValue) MarshalJSON() ([]byte, error) {
	type NoMethod FeatureValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

type GetQueryResultsResponse struct {
	// CacheHit: Whether the query result was fetched from the query cache.
	CacheHit bool `json:"cacheHit,omitempty"`

	// Errors: [Output-only] The first errors or warnings encountered during
	// the running of the job. The final message includes the number of
	// errors that caused the process to stop. Errors here do not
	// necessarily mean that the job has completed or was unsuccessful.
	Errors []*ErrorProto `json:"errors,omitempty"`

	// Etag: A hash of this response.
	Etag string `json:"etag,omitempty"`

	// JobComplete: Whether the query has completed or not. If rows or
	// totalRows are present, this will always be true. If this is false,
	// totalRows will not be available.
	JobComplete bool `json:"jobComplete,omitempty"`

	// JobReference: Reference to the BigQuery Job that was created to run
	// the query. This field will be present even if the original request
	// timed out, in which case GetQueryResults can be used to read the
	// results once the query has completed. Since this API only returns the
	// first page of results, subsequent pages can be fetched via the same
	// mechanism (GetQueryResults).
	JobReference *JobReference `json:"jobReference,omitempty"`

	// Kind: The resource type of the response.
	Kind string `json:"kind,omitempty"`

	// NumDmlAffectedRows: [Output-only] The number of rows affected by a
	// DML statement. Present only for DML statements INSERT, UPDATE or
	// DELETE.
	NumDmlAffectedRows int64 `json:"numDmlAffectedRows,omitempty,string"`

	// PageToken: A token used for paging results.
	PageToken string `json:"pageToken,omitempty"`

	// Rows: An object with as many results as can be contained within the
	// maximum permitted reply size. To get any additional rows, you can
	// call GetQueryResults and specify the jobReference returned above.
	// Present only when the query completes successfully.
	Rows []*TableRow `json:"rows,omitempty"`

	// Schema: The schema of the results. Present only when the query
	// completes successfully.
	Schema *TableSchema `json:"schema,omitempty"`

	// TotalBytesProcessed: The total number of bytes processed for this
	// query.
	TotalBytesProcessed int64 `json:"totalBytesProcessed,omitempty,string"`

	// TotalRows: The total number of rows in the complete query result set,
	// which can be more than the number of rows in this single page of
	// results. Present only when the query completes successfully.
	TotalRows uint64 `json:"totalRows,omitempty,string"`

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

	// ForceSendFields is a list of field names (e.g. "CacheHit") 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. "CacheHit") 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 *GetQueryResultsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GetQueryResultsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GetServiceAccountResponse struct {
	// Email: The service account email address.
	Email string `json:"email,omitempty"`

	// Kind: The resource type of the response.
	Kind string `json:"kind,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Email") 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. "Email") 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 *GetServiceAccountResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GetServiceAccountResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type GoogleSheetsOptions struct {
	// Range: [Optional] Range of a sheet to query from. Only used when
	// non-empty. Typical format:
	// sheet_name!top_left_cell_id:bottom_right_cell_id For example:
	// sheet1!A1:B20
	Range string `json:"range,omitempty"`

	// SkipLeadingRows: [Optional] The number of rows at the top of a sheet
	// that BigQuery will skip when reading the data. The default value is
	// 0. This property is useful if you have header rows that should be
	// skipped. When autodetect is on, behavior is the following: *
	// skipLeadingRows unspecified - Autodetect tries to detect headers in
	// the first row. If they are not detected, the row is read as data.
	// Otherwise data is read starting from the second row. *
	// skipLeadingRows is 0 - Instructs autodetect that there are no headers
	// and data should be read starting from the first row. *
	// skipLeadingRows = N > 0 - Autodetect skips N-1 rows and tries to
	// detect headers in row N. If headers are not detected, row N is just
	// skipped. Otherwise row N is used to extract column names for the
	// detected schema.
	SkipLeadingRows int64 `json:"skipLeadingRows,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Range") 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. "Range") 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 *GoogleSheetsOptions) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleSheetsOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type HivePartitioningOptions struct {
	// Mode: [Optional, Trusted Tester] When set, what mode of hive
	// partitioning to use when reading data. Two modes are supported. (1)
	// AUTO: automatically infer partition key name(s) and type(s). (2)
	// STRINGS: automatically infer partition key name(s). All types are
	// interpreted as strings. Not all storage formats support hive
	// partitioning. Requesting hive partitioning on an unsupported format
	// will lead to an error. Currently supported types include: AVRO, CSV,
	// JSON, ORC and Parquet.
	Mode string `json:"mode,omitempty"`

	// SourceUriPrefix: [Optional, Trusted Tester] When hive partition
	// detection is requested, a common prefix for all source uris should be
	// supplied. The prefix must end immediately before the partition key
	// encoding begins. For example, consider files following this data
	// layout.
	// gs://bucket/path_to_table/dt=2019-01-01/country=BR/id=7/file.avro
	// gs://bucket/path_to_table/dt=2018-12-31/country=CA/id=3/file.avro
	// When hive partitioning is requested with either AUTO or STRINGS
	// detection, the common prefix can be either of
	// gs://bucket/path_to_table or gs://bucket/path_to_table/ (trailing
	// slash does not matter).
	SourceUriPrefix string `json:"sourceUriPrefix,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Mode") 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. "Mode") 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 *HivePartitioningOptions) MarshalJSON() ([]byte, error) {
	type NoMethod HivePartitioningOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IterationResult: Information about a single iteration of the training
// run.
type IterationResult struct {
	ArimaResult *ArimaResult `json:"arimaResult,omitempty"`

	// ClusterInfos: Information about top clusters for clustering models.
	ClusterInfos []*ClusterInfo `json:"clusterInfos,omitempty"`

	// DurationMs: Time taken to run the iteration in milliseconds.
	DurationMs int64 `json:"durationMs,omitempty,string"`

	// EvalLoss: Loss computed on the eval data at the end of iteration.
	EvalLoss float64 `json:"evalLoss,omitempty"`

	// Index: Index of the iteration, 0 based.
	Index int64 `json:"index,omitempty"`

	// LearnRate: Learn rate used for this iteration.
	LearnRate float64 `json:"learnRate,omitempty"`

	// TrainingLoss: Loss computed on the training data at the end of
	// iteration.
	TrainingLoss float64 `json:"trainingLoss,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArimaResult") 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. "ArimaResult") 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 *IterationResult) MarshalJSON() ([]byte, error) {
	type NoMethod IterationResult
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *IterationResult) UnmarshalJSON(data []byte) error {
	type NoMethod IterationResult
	var s1 struct {
		EvalLoss     gensupport.JSONFloat64 `json:"evalLoss"`
		LearnRate    gensupport.JSONFloat64 `json:"learnRate"`
		TrainingLoss gensupport.JSONFloat64 `json:"trainingLoss"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.EvalLoss = float64(s1.EvalLoss)
	s.LearnRate = float64(s1.LearnRate)
	s.TrainingLoss = float64(s1.TrainingLoss)
	return nil
}

type Job struct {
	// Configuration: [Required] Describes the job configuration.
	Configuration *JobConfiguration `json:"configuration,omitempty"`

	// Etag: [Output-only] A hash of this resource.
	Etag string `json:"etag,omitempty"`

	// Id: [Output-only] Opaque ID field of the job
	Id string `json:"id,omitempty"`

	// JobReference: [Optional] Reference describing the unique-per-user
	// name of the job.
	JobReference *JobReference `json:"jobReference,omitempty"`

	// Kind: [Output-only] The type of the resource.
	Kind string `json:"kind,omitempty"`

	// SelfLink: [Output-only] A URL that can be used to access this
	// resource again.
	SelfLink string `json:"selfLink,omitempty"`

	// Statistics: [Output-only] Information about the job, including
	// starting time and ending time of the job.
	Statistics *JobStatistics `json:"statistics,omitempty"`

	// Status: [Output-only] The status of this job. Examine this value when
	// polling an asynchronous job to see if the job is complete.
	Status *JobStatus `json:"status,omitempty"`

	// UserEmail: [Output-only] Email address of the user who ran the job.
	UserEmail string `json:"user_email,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Configuration") 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. "Configuration") 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 *Job) MarshalJSON() ([]byte, error) {
	type NoMethod Job
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobCancelResponse struct {
	// Job: The final state of the job.
	Job *Job `json:"job,omitempty"`

	// Kind: The resource type of the response.
	Kind string `json:"kind,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Job") 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. "Job") 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 *JobCancelResponse) MarshalJSON() ([]byte, error) {
	type NoMethod JobCancelResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobConfiguration struct {
	// Copy: [Pick one] Copies a table.
	Copy *JobConfigurationTableCopy `json:"copy,omitempty"`

	// DryRun: [Optional] If set, don't actually run this job. A valid query
	// will return a mostly empty response with some processing statistics,
	// while an invalid query will return the same error it would if it
	// wasn't a dry run. Behavior of non-query jobs is undefined.
	DryRun bool `json:"dryRun,omitempty"`

	// Extract: [Pick one] Configures an extract job.
	Extract *JobConfigurationExtract `json:"extract,omitempty"`

	// JobTimeoutMs: [Optional] Job timeout in milliseconds. If this time
	// limit is exceeded, BigQuery may attempt to terminate the job.
	JobTimeoutMs int64 `json:"jobTimeoutMs,omitempty,string"`

	// JobType: [Output-only] The type of the job. Can be QUERY, LOAD,
	// EXTRACT, COPY or UNKNOWN.
	JobType string `json:"jobType,omitempty"`

	// Labels: The labels associated with this job. You can use these to
	// organize and group your jobs. Label keys and values can be no longer
	// than 63 characters, can only contain lowercase letters, numeric
	// characters, underscores and dashes. International characters are
	// allowed. Label values are optional. Label keys must start with a
	// letter and each label in the list must have a different key.
	Labels map[string]string `json:"labels,omitempty"`

	// Load: [Pick one] Configures a load job.
	Load *JobConfigurationLoad `json:"load,omitempty"`

	// Query: [Pick one] Configures a query job.
	Query *JobConfigurationQuery `json:"query,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Copy") 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. "Copy") 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 *JobConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod JobConfiguration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobConfigurationExtract struct {
	// Compression: [Optional] The compression type to use for exported
	// files. Possible values include GZIP, DEFLATE, SNAPPY, and NONE. The
	// default value is NONE. DEFLATE and SNAPPY are only supported for
	// Avro. Not applicable when extracting models.
	Compression string `json:"compression,omitempty"`

	// DestinationFormat: [Optional] The exported file format. Possible
	// values include CSV, NEWLINE_DELIMITED_JSON or AVRO for tables and
	// ML_TF_SAVED_MODEL or ML_XGBOOST_BOOSTER for models. The default value
	// for tables is CSV. Tables with nested or repeated fields cannot be
	// exported as CSV. The default value for models is ML_TF_SAVED_MODEL.
	DestinationFormat string `json:"destinationFormat,omitempty"`

	// DestinationUri: [Pick one] DEPRECATED: Use destinationUris instead,
	// passing only one URI as necessary. The fully-qualified Google Cloud
	// Storage URI where the extracted table should be written.
	DestinationUri string `json:"destinationUri,omitempty"`

	// DestinationUris: [Pick one] A list of fully-qualified Google Cloud
	// Storage URIs where the extracted table should be written.
	DestinationUris []string `json:"destinationUris,omitempty"`

	// FieldDelimiter: [Optional] Delimiter to use between fields in the
	// exported data. Default is ','. Not applicable when extracting models.
	FieldDelimiter string `json:"fieldDelimiter,omitempty"`

	// PrintHeader: [Optional] Whether to print out a header row in the
	// results. Default is true. Not applicable when extracting models.
	//
	// Default: true
	PrintHeader *bool `json:"printHeader,omitempty"`

	// SourceModel: A reference to the model being exported.
	SourceModel *ModelReference `json:"sourceModel,omitempty"`

	// SourceTable: A reference to the table being exported.
	SourceTable *TableReference `json:"sourceTable,omitempty"`

	// UseAvroLogicalTypes: [Optional] If destinationFormat is set to
	// "AVRO", this flag indicates whether to enable extracting applicable
	// column types (such as TIMESTAMP) to their corresponding AVRO logical
	// types (timestamp-micros), instead of only using their raw types
	// (avro-long). Not applicable when extracting models.
	UseAvroLogicalTypes bool `json:"useAvroLogicalTypes,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Compression") 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. "Compression") 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 *JobConfigurationExtract) MarshalJSON() ([]byte, error) {
	type NoMethod JobConfigurationExtract
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobConfigurationLoad struct {
	// AllowJaggedRows: [Optional] Accept rows that are missing trailing
	// optional columns. The missing values are treated as nulls. If false,
	// records with missing trailing columns are treated as bad records, and
	// if there are too many bad records, an invalid error is returned in
	// the job result. The default value is false. Only applicable to CSV,
	// ignored for other formats.
	AllowJaggedRows bool `json:"allowJaggedRows,omitempty"`

	// AllowQuotedNewlines: Indicates if BigQuery should allow quoted data
	// sections that contain newline characters in a CSV file. The default
	// value is false.
	AllowQuotedNewlines bool `json:"allowQuotedNewlines,omitempty"`

	// Autodetect: [Optional] Indicates if we should automatically infer the
	// options and schema for CSV and JSON sources.
	Autodetect bool `json:"autodetect,omitempty"`

	// Clustering: [Beta] Clustering specification for the destination
	// table. Must be specified with time-based partitioning, data in the
	// table will be first partitioned and subsequently clustered.
	Clustering *Clustering `json:"clustering,omitempty"`

	// CreateDisposition: [Optional] Specifies whether the job is allowed to
	// create new tables. The following values are supported:
	// CREATE_IF_NEEDED: If the table does not exist, BigQuery creates the
	// table. CREATE_NEVER: The table must already exist. If it does not, a
	// 'notFound' error is returned in the job result. The default value is
	// CREATE_IF_NEEDED. Creation, truncation and append actions occur as
	// one atomic update upon job completion.
	CreateDisposition string `json:"createDisposition,omitempty"`

	// DestinationEncryptionConfiguration: Custom encryption configuration
	// (e.g., Cloud KMS keys).
	DestinationEncryptionConfiguration *EncryptionConfiguration `json:"destinationEncryptionConfiguration,omitempty"`

	// DestinationTable: [Required] The destination table to load the data
	// into.
	DestinationTable *TableReference `json:"destinationTable,omitempty"`

	// DestinationTableProperties: [Beta] [Optional] Properties with which
	// to create the destination table if it is new.
	DestinationTableProperties *DestinationTableProperties `json:"destinationTableProperties,omitempty"`

	// Encoding: [Optional] The character encoding of the data. The
	// supported values are UTF-8 or ISO-8859-1. The default value is UTF-8.
	// BigQuery decodes the data after the raw, binary data has been split
	// using the values of the quote and fieldDelimiter properties.
	Encoding string `json:"encoding,omitempty"`

	// FieldDelimiter: [Optional] The separator for fields in a CSV file.
	// The separator can be any ISO-8859-1 single-byte character. To use a
	// character in the range 128-255, you must encode the character as
	// UTF8. BigQuery converts the string to ISO-8859-1 encoding, and then
	// uses the first byte of the encoded string to split the data in its
	// raw, binary state. BigQuery also supports the escape sequence "\t" to
	// specify a tab separator. The default value is a comma (',').
	FieldDelimiter string `json:"fieldDelimiter,omitempty"`

	// HivePartitioningMode: [Optional, Trusted Tester] Deprecated, do not
	// use. Please set hivePartitioningOptions instead.
	HivePartitioningMode string `json:"hivePartitioningMode,omitempty"`

	// HivePartitioningOptions: [Optional, Trusted Tester] Options to
	// configure hive partitioning support.
	HivePartitioningOptions *HivePartitioningOptions `json:"hivePartitioningOptions,omitempty"`

	// IgnoreUnknownValues: [Optional] Indicates if BigQuery should allow
	// extra values that are not represented in the table schema. If true,
	// the extra values are ignored. If false, records with extra columns
	// are treated as bad records, and if there are too many bad records, an
	// invalid error is returned in the job result. The default value is
	// false. The sourceFormat property determines what BigQuery treats as
	// an extra value: CSV: Trailing columns JSON: Named values that don't
	// match any column names
	IgnoreUnknownValues bool `json:"ignoreUnknownValues,omitempty"`

	// MaxBadRecords: [Optional] The maximum number of bad records that
	// BigQuery can ignore when running the job. If the number of bad
	// records exceeds this value, an invalid error is returned in the job
	// result. This is only valid for CSV and JSON. The default value is 0,
	// which requires that all records are valid.
	MaxBadRecords int64 `json:"maxBadRecords,omitempty"`

	// NullMarker: [Optional] Specifies a string that represents a null
	// value in a CSV file. For example, if you specify "\N", BigQuery
	// interprets "\N" as a null value when loading a CSV file. The default
	// value is the empty string. If you set this property to a custom
	// value, BigQuery throws an error if an empty string is present for all
	// data types except for STRING and BYTE. For STRING and BYTE columns,
	// BigQuery interprets the empty string as an empty value.
	NullMarker string `json:"nullMarker,omitempty"`

	// ProjectionFields: If sourceFormat is set to "DATASTORE_BACKUP",
	// indicates which entity properties to load into BigQuery from a Cloud
	// Datastore backup. Property names are case sensitive and must be
	// top-level properties. If no properties are specified, BigQuery loads
	// all properties. If any named property isn't found in the Cloud
	// Datastore backup, an invalid error is returned in the job result.
	ProjectionFields []string `json:"projectionFields,omitempty"`

	// Quote: [Optional] The value that is used to quote data sections in a
	// CSV file. BigQuery converts the string to ISO-8859-1 encoding, and
	// then uses the first byte of the encoded string to split the data in
	// its raw, binary state. The default value is a double-quote ('"'). If
	// your data does not contain quoted sections, set the property value to
	// an empty string. If your data contains quoted newline characters, you
	// must also set the allowQuotedNewlines property to true.
	//
	// Default: "
	Quote *string `json:"quote,omitempty"`

	// RangePartitioning: [TrustedTester] Range partitioning specification
	// for this table. Only one of timePartitioning and rangePartitioning
	// should be specified.
	RangePartitioning *RangePartitioning `json:"rangePartitioning,omitempty"`

	// Schema: [Optional] The schema for the destination table. The schema
	// can be omitted if the destination table already exists, or if you're
	// loading data from Google Cloud Datastore.
	Schema *TableSchema `json:"schema,omitempty"`

	// SchemaInline: [Deprecated] The inline schema. For CSV schemas,
	// specify as "Field1:Type1[,Field2:Type2]*". For example, "foo:STRING,
	// bar:INTEGER, baz:FLOAT".
	SchemaInline string `json:"schemaInline,omitempty"`

	// SchemaInlineFormat: [Deprecated] The format of the schemaInline
	// property.
	SchemaInlineFormat string `json:"schemaInlineFormat,omitempty"`

	// SchemaUpdateOptions: Allows the schema of the destination table to be
	// updated as a side effect of the load job if a schema is autodetected
	// or supplied in the job configuration. Schema update options are
	// supported in two cases: when writeDisposition is WRITE_APPEND; when
	// writeDisposition is WRITE_TRUNCATE and the destination table is a
	// partition of a table, specified by partition decorators. For normal
	// tables, WRITE_TRUNCATE will always overwrite the schema. One or more
	// of the following values are specified: ALLOW_FIELD_ADDITION: allow
	// adding a nullable field to the schema. ALLOW_FIELD_RELAXATION: allow
	// relaxing a required field in the original schema to nullable.
	SchemaUpdateOptions []string `json:"schemaUpdateOptions,omitempty"`

	// SkipLeadingRows: [Optional] The number of rows at the top of a CSV
	// file that BigQuery will skip when loading the data. The default value
	// is 0. This property is useful if you have header rows in the file
	// that should be skipped.
	SkipLeadingRows int64 `json:"skipLeadingRows,omitempty"`

	// SourceFormat: [Optional] The format of the data files. For CSV files,
	// specify "CSV". For datastore backups, specify "DATASTORE_BACKUP". For
	// newline-delimited JSON, specify "NEWLINE_DELIMITED_JSON". For Avro,
	// specify "AVRO". For parquet, specify "PARQUET". For orc, specify
	// "ORC". The default value is CSV.
	SourceFormat string `json:"sourceFormat,omitempty"`

	// SourceUris: [Required] The fully-qualified URIs that point to your
	// data in Google Cloud. For Google Cloud Storage URIs: Each URI can
	// contain one '*' wildcard character and it must come after the
	// 'bucket' name. Size limits related to load jobs apply to external
	// data sources. For Google Cloud Bigtable URIs: Exactly one URI can be
	// specified and it has be a fully specified and valid HTTPS URL for a
	// Google Cloud Bigtable table. For Google Cloud Datastore backups:
	// Exactly one URI can be specified. Also, the '*' wildcard character is
	// not allowed.
	SourceUris []string `json:"sourceUris,omitempty"`

	// TimePartitioning: Time-based partitioning specification for the
	// destination table. Only one of timePartitioning and rangePartitioning
	// should be specified.
	TimePartitioning *TimePartitioning `json:"timePartitioning,omitempty"`

	// UseAvroLogicalTypes: [Optional] If sourceFormat is set to "AVRO",
	// indicates whether to enable interpreting logical types into their
	// corresponding types (ie. TIMESTAMP), instead of only using their raw
	// types (ie. INTEGER).
	UseAvroLogicalTypes bool `json:"useAvroLogicalTypes,omitempty"`

	// WriteDisposition: [Optional] Specifies the action that occurs if the
	// destination table already exists. The following values are supported:
	// WRITE_TRUNCATE: If the table already exists, BigQuery overwrites the
	// table data. WRITE_APPEND: If the table already exists, BigQuery
	// appends the data to the table. WRITE_EMPTY: If the table already
	// exists and contains data, a 'duplicate' error is returned in the job
	// result. The default value is WRITE_APPEND. Each action is atomic and
	// only occurs if BigQuery is able to complete the job successfully.
	// Creation, truncation and append actions occur as one atomic update
	// upon job completion.
	WriteDisposition string `json:"writeDisposition,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AllowJaggedRows") 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. "AllowJaggedRows") 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 *JobConfigurationLoad) MarshalJSON() ([]byte, error) {
	type NoMethod JobConfigurationLoad
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobConfigurationQuery struct {
	// AllowLargeResults: [Optional] If true and query uses legacy SQL
	// dialect, allows the query to produce arbitrarily large result tables
	// at a slight cost in performance. Requires destinationTable to be set.
	// For standard SQL queries, this flag is ignored and large results are
	// always allowed. However, you must still set destinationTable when
	// result size exceeds the allowed maximum response size.
	AllowLargeResults bool `json:"allowLargeResults,omitempty"`

	// Clustering: [Beta] Clustering specification for the destination
	// table. Must be specified with time-based partitioning, data in the
	// table will be first partitioned and subsequently clustered.
	Clustering *Clustering `json:"clustering,omitempty"`

	// ConnectionProperties: Connection properties.
	ConnectionProperties []interface{} `json:"connectionProperties,omitempty"`

	// CreateDisposition: [Optional] Specifies whether the job is allowed to
	// create new tables. The following values are supported:
	// CREATE_IF_NEEDED: If the table does not exist, BigQuery creates the
	// table. CREATE_NEVER: The table must already exist. If it does not, a
	// 'notFound' error is returned in the job result. The default value is
	// CREATE_IF_NEEDED. Creation, truncation and append actions occur as
	// one atomic update upon job completion.
	CreateDisposition string `json:"createDisposition,omitempty"`

	// DefaultDataset: [Optional] Specifies the default dataset to use for
	// unqualified table names in the query. Note that this does not alter
	// behavior of unqualified dataset names.
	DefaultDataset *DatasetReference `json:"defaultDataset,omitempty"`

	// DestinationEncryptionConfiguration: Custom encryption configuration
	// (e.g., Cloud KMS keys).
	DestinationEncryptionConfiguration *EncryptionConfiguration `json:"destinationEncryptionConfiguration,omitempty"`

	// DestinationTable: [Optional] Describes the table where the query
	// results should be stored. If not present, a new table will be created
	// to store the results. This property must be set for large results
	// that exceed the maximum response size.
	DestinationTable *TableReference `json:"destinationTable,omitempty"`

	// FlattenResults: [Optional] If true and query uses legacy SQL dialect,
	// flattens all nested and repeated fields in the query results.
	// allowLargeResults must be true if this is set to false. For standard
	// SQL queries, this flag is ignored and results are never flattened.
	//
	// Default: true
	FlattenResults *bool `json:"flattenResults,omitempty"`

	// MaximumBillingTier: [Optional] Limits the billing tier for this job.
	// Queries that have resource usage beyond this tier will fail (without
	// incurring a charge). If unspecified, this will be set to your project
	// default.
	//
	// Default: 1
	MaximumBillingTier *int64 `json:"maximumBillingTier,omitempty"`

	// MaximumBytesBilled: [Optional] Limits the bytes billed for this job.
	// Queries that will have bytes billed beyond this limit will fail
	// (without incurring a charge). If unspecified, this will be set to
	// your project default.
	MaximumBytesBilled int64 `json:"maximumBytesBilled,omitempty,string"`

	// ParameterMode: Standard SQL only. Set to POSITIONAL to use positional
	// (?) query parameters or to NAMED to use named (@myparam) query
	// parameters in this query.
	ParameterMode string `json:"parameterMode,omitempty"`

	// PreserveNulls: [Deprecated] This property is deprecated.
	PreserveNulls bool `json:"preserveNulls,omitempty"`

	// Priority: [Optional] Specifies a priority for the query. Possible
	// values include INTERACTIVE and BATCH. The default value is
	// INTERACTIVE.
	Priority string `json:"priority,omitempty"`

	// Query: [Required] SQL query text to execute. The useLegacySql field
	// can be used to indicate whether the query uses legacy SQL or standard
	// SQL.
	Query string `json:"query,omitempty"`

	// QueryParameters: Query parameters for standard SQL queries.
	QueryParameters []*QueryParameter `json:"queryParameters,omitempty"`

	// RangePartitioning: [TrustedTester] Range partitioning specification
	// for this table. Only one of timePartitioning and rangePartitioning
	// should be specified.
	RangePartitioning *RangePartitioning `json:"rangePartitioning,omitempty"`

	// SchemaUpdateOptions: Allows the schema of the destination table to be
	// updated as a side effect of the query job. Schema update options are
	// supported in two cases: when writeDisposition is WRITE_APPEND; when
	// writeDisposition is WRITE_TRUNCATE and the destination table is a
	// partition of a table, specified by partition decorators. For normal
	// tables, WRITE_TRUNCATE will always overwrite the schema. One or more
	// of the following values are specified: ALLOW_FIELD_ADDITION: allow
	// adding a nullable field to the schema. ALLOW_FIELD_RELAXATION: allow
	// relaxing a required field in the original schema to nullable.
	SchemaUpdateOptions []string `json:"schemaUpdateOptions,omitempty"`

	// TableDefinitions: [Optional] If querying an external data source
	// outside of BigQuery, describes the data format, location and other
	// properties of the data source. By defining these properties, the data
	// source can then be queried as if it were a standard BigQuery table.
	TableDefinitions map[string]ExternalDataConfiguration `json:"tableDefinitions,omitempty"`

	// TimePartitioning: Time-based partitioning specification for the
	// destination table. Only one of timePartitioning and rangePartitioning
	// should be specified.
	TimePartitioning *TimePartitioning `json:"timePartitioning,omitempty"`

	// UseLegacySql: Specifies whether to use BigQuery's legacy SQL dialect
	// for this query. The default value is true. If set to false, the query
	// will use BigQuery's standard SQL:
	// https://cloud.google.com/bigquery/sql-reference/ When useLegacySql is
	// set to false, the value of flattenResults is ignored; query will be
	// run as if flattenResults is false.
	//
	// Default: true
	UseLegacySql *bool `json:"useLegacySql,omitempty"`

	// UseQueryCache: [Optional] Whether to look for the result in the query
	// cache. The query cache is a best-effort cache that will be flushed
	// whenever tables in the query are modified. Moreover, the query cache
	// is only available when a query does not have a destination table
	// specified. The default value is true.
	//
	// Default: true
	UseQueryCache *bool `json:"useQueryCache,omitempty"`

	// UserDefinedFunctionResources: Describes user-defined function
	// resources used in the query.
	UserDefinedFunctionResources []*UserDefinedFunctionResource `json:"userDefinedFunctionResources,omitempty"`

	// WriteDisposition: [Optional] Specifies the action that occurs if the
	// destination table already exists. The following values are supported:
	// WRITE_TRUNCATE: If the table already exists, BigQuery overwrites the
	// table data and uses the schema from the query result. WRITE_APPEND:
	// If the table already exists, BigQuery appends the data to the table.
	// WRITE_EMPTY: If the table already exists and contains data, a
	// 'duplicate' error is returned in the job result. The default value is
	// WRITE_EMPTY. Each action is atomic and only occurs if BigQuery is
	// able to complete the job successfully. Creation, truncation and
	// append actions occur as one atomic update upon job completion.
	WriteDisposition string `json:"writeDisposition,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AllowLargeResults")
	// 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. "AllowLargeResults") 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 *JobConfigurationQuery) MarshalJSON() ([]byte, error) {
	type NoMethod JobConfigurationQuery
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobConfigurationTableCopy struct {
	// CreateDisposition: [Optional] Specifies whether the job is allowed to
	// create new tables. The following values are supported:
	// CREATE_IF_NEEDED: If the table does not exist, BigQuery creates the
	// table. CREATE_NEVER: The table must already exist. If it does not, a
	// 'notFound' error is returned in the job result. The default value is
	// CREATE_IF_NEEDED. Creation, truncation and append actions occur as
	// one atomic update upon job completion.
	CreateDisposition string `json:"createDisposition,omitempty"`

	// DestinationEncryptionConfiguration: Custom encryption configuration
	// (e.g., Cloud KMS keys).
	DestinationEncryptionConfiguration *EncryptionConfiguration `json:"destinationEncryptionConfiguration,omitempty"`

	// DestinationTable: [Required] The destination table
	DestinationTable *TableReference `json:"destinationTable,omitempty"`

	// SourceTable: [Pick one] Source table to copy.
	SourceTable *TableReference `json:"sourceTable,omitempty"`

	// SourceTables: [Pick one] Source tables to copy.
	SourceTables []*TableReference `json:"sourceTables,omitempty"`

	// WriteDisposition: [Optional] Specifies the action that occurs if the
	// destination table already exists. The following values are supported:
	// WRITE_TRUNCATE: If the table already exists, BigQuery overwrites the
	// table data. WRITE_APPEND: If the table already exists, BigQuery
	// appends the data to the table. WRITE_EMPTY: If the table already
	// exists and contains data, a 'duplicate' error is returned in the job
	// result. The default value is WRITE_EMPTY. Each action is atomic and
	// only occurs if BigQuery is able to complete the job successfully.
	// Creation, truncation and append actions occur as one atomic update
	// upon job completion.
	WriteDisposition string `json:"writeDisposition,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateDisposition")
	// 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. "CreateDisposition") 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 *JobConfigurationTableCopy) MarshalJSON() ([]byte, error) {
	type NoMethod JobConfigurationTableCopy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobList struct {
	// Etag: A hash of this page of results.
	Etag string `json:"etag,omitempty"`

	// Jobs: List of jobs that were requested.
	Jobs []*JobListJobs `json:"jobs,omitempty"`

	// Kind: The resource type of the response.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: A token to request the next page of results.
	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. "Etag") 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. "Etag") 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 *JobList) MarshalJSON() ([]byte, error) {
	type NoMethod JobList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobListJobs struct {
	// Configuration: [Full-projection-only] Specifies the job
	// configuration.
	Configuration *JobConfiguration `json:"configuration,omitempty"`

	// ErrorResult: A result object that will be present only if the job has
	// failed.
	ErrorResult *ErrorProto `json:"errorResult,omitempty"`

	// Id: Unique opaque ID of the job.
	Id string `json:"id,omitempty"`

	// JobReference: Job reference uniquely identifying the job.
	JobReference *JobReference `json:"jobReference,omitempty"`

	// Kind: The resource type.
	Kind string `json:"kind,omitempty"`

	// State: Running state of the job. When the state is DONE, errorResult
	// can be checked to determine whether the job succeeded or failed.
	State string `json:"state,omitempty"`

	// Statistics: [Output-only] Information about the job, including
	// starting time and ending time of the job.
	Statistics *JobStatistics `json:"statistics,omitempty"`

	// Status: [Full-projection-only] Describes the state of the job.
	Status *JobStatus `json:"status,omitempty"`

	// UserEmail: [Full-projection-only] Email address of the user who ran
	// the job.
	UserEmail string `json:"user_email,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Configuration") 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. "Configuration") 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 *JobListJobs) MarshalJSON() ([]byte, error) {
	type NoMethod JobListJobs
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobReference struct {
	// JobId: [Required] The ID of the job. The ID must contain only letters
	// (a-z, A-Z), numbers (0-9), underscores (_), or dashes (-). The
	// maximum length is 1,024 characters.
	JobId string `json:"jobId,omitempty"`

	// Location: The geographic location of the job. See details at
	// https://cloud.google.com/bigquery/docs/locations#specifying_your_location.
	Location string `json:"location,omitempty"`

	// ProjectId: [Required] The ID of the project containing this job.
	ProjectId string `json:"projectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "JobId") 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. "JobId") 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 *JobReference) MarshalJSON() ([]byte, error) {
	type NoMethod JobReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobStatistics struct {
	// CompletionRatio: [TrustedTester] [Output-only] Job progress (0.0 ->
	// 1.0) for LOAD and EXTRACT jobs.
	CompletionRatio float64 `json:"completionRatio,omitempty"`

	// CreationTime: [Output-only] Creation time of this job, in
	// milliseconds since the epoch. This field will be present on all jobs.
	CreationTime int64 `json:"creationTime,omitempty,string"`

	// EndTime: [Output-only] End time of this job, in milliseconds since
	// the epoch. This field will be present whenever a job is in the DONE
	// state.
	EndTime int64 `json:"endTime,omitempty,string"`

	// Extract: [Output-only] Statistics for an extract job.
	Extract *JobStatistics4 `json:"extract,omitempty"`

	// Load: [Output-only] Statistics for a load job.
	Load *JobStatistics3 `json:"load,omitempty"`

	// NumChildJobs: [Output-only] Number of child jobs executed.
	NumChildJobs int64 `json:"numChildJobs,omitempty,string"`

	// ParentJobId: [Output-only] If this is a child job, the id of the
	// parent.
	ParentJobId string `json:"parentJobId,omitempty"`

	// Query: [Output-only] Statistics for a query job.
	Query *JobStatistics2 `json:"query,omitempty"`

	// QuotaDeferments: [Output-only] Quotas which delayed this job's start
	// time.
	QuotaDeferments []string `json:"quotaDeferments,omitempty"`

	// ReservationUsage: [Output-only] Job resource usage breakdown by
	// reservation.
	ReservationUsage []*JobStatisticsReservationUsage `json:"reservationUsage,omitempty"`

	// ReservationId: [Output-only] Name of the primary reservation assigned
	// to this job. Note that this could be different than reservations
	// reported in the reservation usage field if parent reservations were
	// used to execute this job.
	ReservationId string `json:"reservation_id,omitempty"`

	// RowLevelSecurityStatistics: [Output-only] [Preview] Statistics for
	// row-level security. Present only for query and extract jobs.
	RowLevelSecurityStatistics *RowLevelSecurityStatistics `json:"rowLevelSecurityStatistics,omitempty"`

	// ScriptStatistics: [Output-only] Statistics for a child job of a
	// script.
	ScriptStatistics *ScriptStatistics `json:"scriptStatistics,omitempty"`

	// StartTime: [Output-only] Start time of this job, in milliseconds
	// since the epoch. This field will be present when the job transitions
	// from the PENDING state to either RUNNING or DONE.
	StartTime int64 `json:"startTime,omitempty,string"`

	// TotalBytesProcessed: [Output-only] [Deprecated] Use the bytes
	// processed in the query statistics instead.
	TotalBytesProcessed int64 `json:"totalBytesProcessed,omitempty,string"`

	// TotalSlotMs: [Output-only] Slot-milliseconds for the job.
	TotalSlotMs int64 `json:"totalSlotMs,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CompletionRatio") 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. "CompletionRatio") 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 *JobStatistics) MarshalJSON() ([]byte, error) {
	type NoMethod JobStatistics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

type JobStatisticsReservationUsage struct {
	// Name: [Output-only] Reservation name or "unreserved" for on-demand
	// resources usage.
	Name string `json:"name,omitempty"`

	// SlotMs: [Output-only] Slot-milliseconds the job spent in the given
	// reservation.
	SlotMs int64 `json:"slotMs,omitempty,string"`

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

type JobStatistics2 struct {
	// BillingTier: [Output-only] Billing tier for the job.
	BillingTier int64 `json:"billingTier,omitempty"`

	// CacheHit: [Output-only] Whether the query result was fetched from the
	// query cache.
	CacheHit bool `json:"cacheHit,omitempty"`

	// DdlAffectedRowAccessPolicyCount: [Output-only] [Preview] The number
	// of row access policies affected by a DDL statement. Present only for
	// DROP ALL ROW ACCESS POLICIES queries.
	DdlAffectedRowAccessPolicyCount int64 `json:"ddlAffectedRowAccessPolicyCount,omitempty,string"`

	// DdlOperationPerformed: The DDL operation performed, possibly
	// dependent on the pre-existence of the DDL target. Possible values
	// (new values might be added in the future): "CREATE": The query
	// created the DDL target. "SKIP": No-op. Example cases: the query is
	// CREATE TABLE IF NOT EXISTS while the table already exists, or the
	// query is DROP TABLE IF EXISTS while the table does not exist.
	// "REPLACE": The query replaced the DDL target. Example case: the query
	// is CREATE OR REPLACE TABLE, and the table already exists. "DROP": The
	// query deleted the DDL target.
	DdlOperationPerformed string `json:"ddlOperationPerformed,omitempty"`

	// DdlTargetRoutine: The DDL target routine. Present only for
	// CREATE/DROP FUNCTION/PROCEDURE queries.
	DdlTargetRoutine *RoutineReference `json:"ddlTargetRoutine,omitempty"`

	// DdlTargetRowAccessPolicy: [Output-only] [Preview] The DDL target row
	// access policy. Present only for CREATE/DROP ROW ACCESS POLICY
	// queries.
	DdlTargetRowAccessPolicy *RowAccessPolicyReference `json:"ddlTargetRowAccessPolicy,omitempty"`

	// DdlTargetTable: [Output-only] The DDL target table. Present only for
	// CREATE/DROP TABLE/VIEW and DROP ALL ROW ACCESS POLICIES queries.
	DdlTargetTable *TableReference `json:"ddlTargetTable,omitempty"`

	// EstimatedBytesProcessed: [Output-only] The original estimate of bytes
	// processed for the job.
	EstimatedBytesProcessed int64 `json:"estimatedBytesProcessed,omitempty,string"`

	// ModelTraining: [Output-only, Beta] Information about create model
	// query job progress.
	ModelTraining *BigQueryModelTraining `json:"modelTraining,omitempty"`

	// ModelTrainingCurrentIteration: [Output-only, Beta] Deprecated; do not
	// use.
	ModelTrainingCurrentIteration int64 `json:"modelTrainingCurrentIteration,omitempty"`

	// ModelTrainingExpectedTotalIteration: [Output-only, Beta] Deprecated;
	// do not use.
	ModelTrainingExpectedTotalIteration int64 `json:"modelTrainingExpectedTotalIteration,omitempty,string"`

	// NumDmlAffectedRows: [Output-only] The number of rows affected by a
	// DML statement. Present only for DML statements INSERT, UPDATE or
	// DELETE.
	NumDmlAffectedRows int64 `json:"numDmlAffectedRows,omitempty,string"`

	// QueryPlan: [Output-only] Describes execution plan for the query.
	QueryPlan []*ExplainQueryStage `json:"queryPlan,omitempty"`

	// ReferencedRoutines: [Output-only] Referenced routines (persistent
	// user-defined functions and stored procedures) for the job.
	ReferencedRoutines []*RoutineReference `json:"referencedRoutines,omitempty"`

	// ReferencedTables: [Output-only] Referenced tables for the job.
	// Queries that reference more than 50 tables will not have a complete
	// list.
	ReferencedTables []*TableReference `json:"referencedTables,omitempty"`

	// ReservationUsage: [Output-only] Job resource usage breakdown by
	// reservation.
	ReservationUsage []*JobStatistics2ReservationUsage `json:"reservationUsage,omitempty"`

	// Schema: [Output-only] The schema of the results. Present only for
	// successful dry run of non-legacy SQL queries.
	Schema *TableSchema `json:"schema,omitempty"`

	// StatementType: The type of query statement, if valid. Possible values
	// (new values might be added in the future): "SELECT": SELECT query.
	// "INSERT": INSERT query; see
	// https://cloud.google.com/bigquery/docs/reference/standard-sql/data-manipulation-language. "UPDATE": UPDATE query; see https://cloud.google.com/bigquery/docs/reference/standard-sql/data-manipulation-language. "DELETE": DELETE query; see https://cloud.google.com/bigquery/docs/reference/standard-sql/data-manipulation-language. "MERGE": MERGE query; see https://cloud.google.com/bigquery/docs/reference/standard-sql/data-manipulation-language. "ALTER_TABLE": ALTER TABLE query. "ALTER_VIEW": ALTER VIEW query. "ASSERT": ASSERT condition AS 'description'. "CREATE_FUNCTION": CREATE FUNCTION query. "CREATE_MODEL": CREATE [OR REPLACE] MODEL ... AS SELECT ... . "CREATE_PROCEDURE": CREATE PROCEDURE query. "CREATE_TABLE": CREATE [OR REPLACE] TABLE without AS SELECT. "CREATE_TABLE_AS_SELECT": CREATE [OR REPLACE] TABLE ... AS SELECT ... . "CREATE_VIEW": CREATE [OR REPLACE] VIEW ... AS SELECT ... . "DROP_FUNCTION" : DROP FUNCTION query. "DROP_PROCEDURE": DROP PROCEDURE query. "DROP_TABLE": DROP TABLE query. "DROP_VIEW": DROP VIEW
	// query.
	StatementType string `json:"statementType,omitempty"`

	// Timeline: [Output-only] [Beta] Describes a timeline of job execution.
	Timeline []*QueryTimelineSample `json:"timeline,omitempty"`

	// TotalBytesBilled: [Output-only] Total bytes billed for the job.
	TotalBytesBilled int64 `json:"totalBytesBilled,omitempty,string"`

	// TotalBytesProcessed: [Output-only] Total bytes processed for the job.
	TotalBytesProcessed int64 `json:"totalBytesProcessed,omitempty,string"`

	// TotalBytesProcessedAccuracy: [Output-only] For dry-run jobs,
	// totalBytesProcessed is an estimate and this field specifies the
	// accuracy of the estimate. Possible values can be: UNKNOWN: accuracy
	// of the estimate is unknown. PRECISE: estimate is precise.
	// LOWER_BOUND: estimate is lower bound of what the query would cost.
	// UPPER_BOUND: estimate is upper bound of what the query would cost.
	TotalBytesProcessedAccuracy string `json:"totalBytesProcessedAccuracy,omitempty"`

	// TotalPartitionsProcessed: [Output-only] Total number of partitions
	// processed from all partitioned tables referenced in the job.
	TotalPartitionsProcessed int64 `json:"totalPartitionsProcessed,omitempty,string"`

	// TotalSlotMs: [Output-only] Slot-milliseconds for the job.
	TotalSlotMs int64 `json:"totalSlotMs,omitempty,string"`

	// UndeclaredQueryParameters: Standard SQL only: list of undeclared
	// query parameters detected during a dry run validation.
	UndeclaredQueryParameters []*QueryParameter `json:"undeclaredQueryParameters,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BillingTier") 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. "BillingTier") 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 *JobStatistics2) MarshalJSON() ([]byte, error) {
	type NoMethod JobStatistics2
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobStatistics2ReservationUsage struct {
	// Name: [Output-only] Reservation name or "unreserved" for on-demand
	// resources usage.
	Name string `json:"name,omitempty"`

	// SlotMs: [Output-only] Slot-milliseconds the job spent in the given
	// reservation.
	SlotMs int64 `json:"slotMs,omitempty,string"`

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

type JobStatistics3 struct {
	// BadRecords: [Output-only] The number of bad records encountered. Note
	// that if the job has failed because of more bad records encountered
	// than the maximum allowed in the load job configuration, then this
	// number can be less than the total number of bad records present in
	// the input data.
	BadRecords int64 `json:"badRecords,omitempty,string"`

	// InputFileBytes: [Output-only] Number of bytes of source data in a
	// load job.
	InputFileBytes int64 `json:"inputFileBytes,omitempty,string"`

	// InputFiles: [Output-only] Number of source files in a load job.
	InputFiles int64 `json:"inputFiles,omitempty,string"`

	// OutputBytes: [Output-only] Size of the loaded data in bytes. Note
	// that while a load job is in the running state, this value may change.
	OutputBytes int64 `json:"outputBytes,omitempty,string"`

	// OutputRows: [Output-only] Number of rows imported in a load job. Note
	// that while an import job is in the running state, this value may
	// change.
	OutputRows int64 `json:"outputRows,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "BadRecords") 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. "BadRecords") 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 *JobStatistics3) MarshalJSON() ([]byte, error) {
	type NoMethod JobStatistics3
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobStatistics4 struct {
	// DestinationUriFileCounts: [Output-only] Number of files per
	// destination URI or URI pattern specified in the extract
	// configuration. These values will be in the same order as the URIs
	// specified in the 'destinationUris' field.
	DestinationUriFileCounts googleapi.Int64s `json:"destinationUriFileCounts,omitempty"`

	// InputBytes: [Output-only] Number of user bytes extracted into the
	// result. This is the byte count as computed by BigQuery for billing
	// purposes.
	InputBytes int64 `json:"inputBytes,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "DestinationUriFileCounts") 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. "DestinationUriFileCounts")
	// 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 *JobStatistics4) MarshalJSON() ([]byte, error) {
	type NoMethod JobStatistics4
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JobStatus struct {
	// ErrorResult: [Output-only] Final error result of the job. If present,
	// indicates that the job has completed and was unsuccessful.
	ErrorResult *ErrorProto `json:"errorResult,omitempty"`

	// Errors: [Output-only] The first errors encountered during the running
	// of the job. The final message includes the number of errors that
	// caused the process to stop. Errors here do not necessarily mean that
	// the job has completed or was unsuccessful.
	Errors []*ErrorProto `json:"errors,omitempty"`

	// State: [Output-only] Running state of the job.
	State string `json:"state,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ErrorResult") 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. "ErrorResult") 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 *JobStatus) MarshalJSON() ([]byte, error) {
	type NoMethod JobStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type JsonValue interface{}

type ListModelsResponse struct {
	// Models: Models in the requested dataset. Only the following fields
	// are populated:
	// model_reference, model_type, creation_time, last_modified_time
	// and
	// labels.
	Models []*Model `json:"models,omitempty"`

	// NextPageToken: A token to request the next page of results.
	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. "Models") 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. "Models") 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 *ListModelsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListModelsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ListRoutinesResponse struct {
	// NextPageToken: A token to request the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Routines: Routines in the requested dataset. Unless read_mask is set
	// in the request,
	// only the following fields are populated:
	// etag, project_id, dataset_id, routine_id, routine_type,
	// creation_time,
	// last_modified_time, and language.
	Routines []*Routine `json:"routines,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 *ListRoutinesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListRoutinesResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LocationMetadata: BigQuery-specific metadata about a location. This
// will be set on
// google.cloud.location.Location.metadata in Cloud Location
// API
// responses.
type LocationMetadata struct {
	// LegacyLocationId: The legacy BigQuery location ID, e.g. “EU” for
	// the “europe” location.
	// This is for any API consumers that need the legacy “US” and
	// “EU” locations.
	LegacyLocationId string `json:"legacyLocationId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LegacyLocationId") 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. "LegacyLocationId") 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 *LocationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod LocationMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type MaterializedViewDefinition struct {
	// EnableRefresh: [Optional] [TrustedTester] Enable automatic refresh of
	// the materialized view when the base table is updated. The default
	// value is "true".
	EnableRefresh bool `json:"enableRefresh,omitempty"`

	// LastRefreshTime: [Output-only] [TrustedTester] The time when this
	// materialized view was last modified, in milliseconds since the epoch.
	LastRefreshTime int64 `json:"lastRefreshTime,omitempty,string"`

	// Query: [Required] A query whose result is persisted.
	Query string `json:"query,omitempty"`

	// RefreshIntervalMs: [Optional] [TrustedTester] The maximum frequency
	// at which this materialized view will be refreshed. The default value
	// is "1800000" (30 minutes).
	RefreshIntervalMs int64 `json:"refreshIntervalMs,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "EnableRefresh") 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. "EnableRefresh") 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 *MaterializedViewDefinition) MarshalJSON() ([]byte, error) {
	type NoMethod MaterializedViewDefinition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type Model struct {
	// CreationTime: Output only. The time when this model was created, in
	// millisecs since the epoch.
	CreationTime int64 `json:"creationTime,omitempty,string"`

	// Description: Optional. A user-friendly description of this model.
	Description string `json:"description,omitempty"`

	// EncryptionConfiguration: Custom encryption configuration (e.g., Cloud
	// KMS keys). This shows the
	// encryption configuration of the model data while stored in
	// BigQuery
	// storage. This field can be used with PatchModel to update encryption
	// key
	// for an already encrypted model.
	EncryptionConfiguration *EncryptionConfiguration `json:"encryptionConfiguration,omitempty"`

	// Etag: Output only. A hash of this resource.
	Etag string `json:"etag,omitempty"`

	// ExpirationTime: Optional. The time when this model expires, in
	// milliseconds since the epoch.
	// If not present, the model will persist indefinitely. Expired
	// models
	// will be deleted and their storage reclaimed.  The
	// defaultTableExpirationMs
	// property of the encapsulating dataset can be used to set a
	// default
	// expirationTime on newly created models.
	ExpirationTime int64 `json:"expirationTime,omitempty,string"`

	// FeatureColumns: Output only. Input feature columns that were used to
	// train this model.
	FeatureColumns []*StandardSqlField `json:"featureColumns,omitempty"`

	// FriendlyName: Optional. A descriptive name for this model.
	FriendlyName string `json:"friendlyName,omitempty"`

	// LabelColumns: Output only. Label columns that were used to train this
	// model.
	// The output of the model will have a "predicted_" prefix to these
	// columns.
	LabelColumns []*StandardSqlField `json:"labelColumns,omitempty"`

	// Labels: The labels associated with this model. You can use these to
	// organize
	// and group your models. Label keys and values can be no longer
	// than 63 characters, can only contain lowercase letters,
	// numeric
	// characters, underscores and dashes. International characters are
	// allowed.
	// Label values are optional. Label keys must start with a letter and
	// each
	// label in the list must have a different key.
	Labels map[string]string `json:"labels,omitempty"`

	// LastModifiedTime: Output only. The time when this model was last
	// modified, in millisecs since the epoch.
	LastModifiedTime int64 `json:"lastModifiedTime,omitempty,string"`

	// Location: Output only. The geographic location where the model
	// resides. This value
	// is inherited from the dataset.
	Location string `json:"location,omitempty"`

	// ModelReference: Required. Unique identifier for this model.
	ModelReference *ModelReference `json:"modelReference,omitempty"`

	// ModelType: Output only. Type of the model resource.
	//
	// Possible values:
	//   "MODEL_TYPE_UNSPECIFIED"
	//   "LINEAR_REGRESSION" - Linear regression model.
	//   "LOGISTIC_REGRESSION" - Logistic regression based classification
	// model.
	//   "KMEANS" - K-means clustering model.
	//   "MATRIX_FACTORIZATION" - Matrix factorization model.
	//   "DNN_CLASSIFIER" - DNN classifier model.
	//   "TENSORFLOW" - [Beta] An imported TensorFlow model.
	//   "DNN_REGRESSOR" - DNN regressor model.
	//   "BOOSTED_TREE_REGRESSOR" - Boosted tree regressor model.
	//   "BOOSTED_TREE_CLASSIFIER" - Boosted tree classifier model.
	//   "AUTOML_REGRESSOR" - AutoML Tables regression model.
	//   "AUTOML_CLASSIFIER" - AutoML Tables classification model.
	ModelType string `json:"modelType,omitempty"`

	// TrainingRuns: Output only. Information for all training runs in
	// increasing order of start_time.
	TrainingRuns []*TrainingRun `json:"trainingRuns,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CreationTime") 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. "CreationTime") 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 *Model) MarshalJSON() ([]byte, error) {
	type NoMethod Model
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ModelDefinition struct {
	// ModelOptions: [Output-only, Beta] Model options used for the first
	// training run. These options are immutable for subsequent training
	// runs. Default values are used for any options not specified in the
	// input query.
	ModelOptions *ModelDefinitionModelOptions `json:"modelOptions,omitempty"`

	// TrainingRuns: [Output-only, Beta] Information about ml training runs,
	// each training run comprises of multiple iterations and there may be
	// multiple training runs for the model if warm start is used or if a
	// user decides to continue a previously cancelled query.
	TrainingRuns []*BqmlTrainingRun `json:"trainingRuns,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ModelOptions") 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. "ModelOptions") 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 *ModelDefinition) MarshalJSON() ([]byte, error) {
	type NoMethod ModelDefinition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ModelDefinitionModelOptions: [Output-only, Beta] Model options used
// for the first training run. These options are immutable for
// subsequent training runs. Default values are used for any options not
// specified in the input query.
type ModelDefinitionModelOptions struct {
	Labels []string `json:"labels,omitempty"`

	LossType string `json:"lossType,omitempty"`

	ModelType string `json:"modelType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Labels") 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. "Labels") 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 *ModelDefinitionModelOptions) MarshalJSON() ([]byte, error) {
	type NoMethod ModelDefinitionModelOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ModelReference struct {
	// DatasetId: [Required] The ID of the dataset containing this model.
	DatasetId string `json:"datasetId,omitempty"`

	// ModelId: [Required] The ID of the model. The ID must contain only
	// letters (a-z, A-Z), numbers (0-9), or underscores (_). The maximum
	// length is 1,024 characters.
	ModelId string `json:"modelId,omitempty"`

	// ProjectId: [Required] The ID of the project containing this model.
	ProjectId string `json:"projectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DatasetId") 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. "DatasetId") 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 *ModelReference) MarshalJSON() ([]byte, error) {
	type NoMethod ModelReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MultiClassClassificationMetrics: Evaluation metrics for multi-class
// classification/classifier models.
type MultiClassClassificationMetrics struct {
	// AggregateClassificationMetrics: Aggregate classification metrics.
	AggregateClassificationMetrics *AggregateClassificationMetrics `json:"aggregateClassificationMetrics,omitempty"`

	// ConfusionMatrixList: Confusion matrix at different thresholds.
	ConfusionMatrixList []*ConfusionMatrix `json:"confusionMatrixList,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AggregateClassificationMetrics") 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.
	// "AggregateClassificationMetrics") 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 *MultiClassClassificationMetrics) MarshalJSON() ([]byte, error) {
	type NoMethod MultiClassClassificationMetrics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ProjectList struct {
	// Etag: A hash of the page of results
	Etag string `json:"etag,omitempty"`

	// Kind: The type of list.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: A token to request the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Projects: Projects to which you have at least READ access.
	Projects []*ProjectListProjects `json:"projects,omitempty"`

	// TotalItems: The total number of projects in the list.
	TotalItems int64 `json:"totalItems,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Etag") 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. "Etag") 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 *ProjectList) MarshalJSON() ([]byte, error) {
	type NoMethod ProjectList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ProjectListProjects struct {
	// FriendlyName: A descriptive name for this project.
	FriendlyName string `json:"friendlyName,omitempty"`

	// Id: An opaque ID of this project.
	Id string `json:"id,omitempty"`

	// Kind: The resource type.
	Kind string `json:"kind,omitempty"`

	// NumericId: The numeric ID of this project.
	NumericId uint64 `json:"numericId,omitempty,string"`

	// ProjectReference: A unique reference to this project.
	ProjectReference *ProjectReference `json:"projectReference,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FriendlyName") 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. "FriendlyName") 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 *ProjectListProjects) MarshalJSON() ([]byte, error) {
	type NoMethod ProjectListProjects
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ProjectReference struct {
	// ProjectId: [Required] ID of the project. Can be either the numeric ID
	// or the assigned ID of the project.
	ProjectId string `json:"projectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ProjectId") 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. "ProjectId") 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 *ProjectReference) MarshalJSON() ([]byte, error) {
	type NoMethod ProjectReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type QueryParameter struct {
	// Name: [Optional] If unset, this is a positional parameter. Otherwise,
	// should be unique within a query.
	Name string `json:"name,omitempty"`

	// ParameterType: [Required] The type of this parameter.
	ParameterType *QueryParameterType `json:"parameterType,omitempty"`

	// ParameterValue: [Required] The value of this parameter.
	ParameterValue *QueryParameterValue `json:"parameterValue,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 *QueryParameter) MarshalJSON() ([]byte, error) {
	type NoMethod QueryParameter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type QueryParameterType struct {
	// ArrayType: [Optional] The type of the array's elements, if this is an
	// array.
	ArrayType *QueryParameterType `json:"arrayType,omitempty"`

	// StructTypes: [Optional] The types of the fields of this struct, in
	// order, if this is a struct.
	StructTypes []*QueryParameterTypeStructTypes `json:"structTypes,omitempty"`

	// Type: [Required] The top level type of this field.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArrayType") 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. "ArrayType") 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 *QueryParameterType) MarshalJSON() ([]byte, error) {
	type NoMethod QueryParameterType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type QueryParameterTypeStructTypes struct {
	// Description: [Optional] Human-oriented description of the field.
	Description string `json:"description,omitempty"`

	// Name: [Optional] The name of this field.
	Name string `json:"name,omitempty"`

	// Type: [Required] The type of this field.
	Type *QueryParameterType `json:"type,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 *QueryParameterTypeStructTypes) MarshalJSON() ([]byte, error) {
	type NoMethod QueryParameterTypeStructTypes
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type QueryParameterValue struct {
	// ArrayValues: [Optional] The array values, if this is an array type.
	ArrayValues []*QueryParameterValue `json:"arrayValues,omitempty"`

	// StructValues: [Optional] The struct field values, in order of the
	// struct type's declaration.
	StructValues map[string]QueryParameterValue `json:"structValues,omitempty"`

	// Value: [Optional] The value of this value, if a simple scalar type.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArrayValues") 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. "ArrayValues") 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 *QueryParameterValue) MarshalJSON() ([]byte, error) {
	type NoMethod QueryParameterValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type QueryRequest struct {
	// ConnectionProperties: Connection properties.
	ConnectionProperties []interface{} `json:"connectionProperties,omitempty"`

	// DefaultDataset: [Optional] Specifies the default datasetId and
	// projectId to assume for any unqualified table names in the query. If
	// not set, all table names in the query string must be qualified in the
	// format 'datasetId.tableId'.
	DefaultDataset *DatasetReference `json:"defaultDataset,omitempty"`

	// DryRun: [Optional] If set to true, BigQuery doesn't run the job.
	// Instead, if the query is valid, BigQuery returns statistics about the
	// job such as how many bytes would be processed. If the query is
	// invalid, an error returns. The default value is false.
	DryRun bool `json:"dryRun,omitempty"`

	// Kind: The resource type of the request.
	Kind string `json:"kind,omitempty"`

	// Location: The geographic location where the job should run. See
	// details at
	// https://cloud.google.com/bigquery/docs/locations#specifying_your_location.
	Location string `json:"location,omitempty"`

	// MaxResults: [Optional] The maximum number of rows of data to return
	// per page of results. Setting this flag to a small value such as 1000
	// and then paging through results might improve reliability when the
	// query result set is large. In addition to this limit, responses are
	// also limited to 10 MB. By default, there is no maximum row count, and
	// only the byte limit applies.
	MaxResults int64 `json:"maxResults,omitempty"`

	// ParameterMode: Standard SQL only. Set to POSITIONAL to use positional
	// (?) query parameters or to NAMED to use named (@myparam) query
	// parameters in this query.
	ParameterMode string `json:"parameterMode,omitempty"`

	// PreserveNulls: [Deprecated] This property is deprecated.
	PreserveNulls bool `json:"preserveNulls,omitempty"`

	// Query: [Required] A query string, following the BigQuery query
	// syntax, of the query to execute. Example: "SELECT count(f1) FROM
	// [myProjectId:myDatasetId.myTableId]".
	Query string `json:"query,omitempty"`

	// QueryParameters: Query parameters for Standard SQL queries.
	QueryParameters []*QueryParameter `json:"queryParameters,omitempty"`

	// TimeoutMs: [Optional] How long to wait for the query to complete, in
	// milliseconds, before the request times out and returns. Note that
	// this is only a timeout for the request, not the query. If the query
	// takes longer to run than the timeout value, the call returns without
	// any results and with the 'jobComplete' flag set to false. You can
	// call GetQueryResults() to wait for the query to complete and read the
	// results. The default value is 10000 milliseconds (10 seconds).
	TimeoutMs int64 `json:"timeoutMs,omitempty"`

	// UseLegacySql: Specifies whether to use BigQuery's legacy SQL dialect
	// for this query. The default value is true. If set to false, the query
	// will use BigQuery's standard SQL:
	// https://cloud.google.com/bigquery/sql-reference/ When useLegacySql is
	// set to false, the value of flattenResults is ignored; query will be
	// run as if flattenResults is false.
	//
	// Default: true
	UseLegacySql *bool `json:"useLegacySql,omitempty"`

	// UseQueryCache: [Optional] Whether to look for the result in the query
	// cache. The query cache is a best-effort cache that will be flushed
	// whenever tables in the query are modified. The default value is true.
	//
	// Default: true
	UseQueryCache *bool `json:"useQueryCache,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ConnectionProperties") 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. "ConnectionProperties") 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 *QueryRequest) MarshalJSON() ([]byte, error) {
	type NoMethod QueryRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type QueryResponse struct {
	// CacheHit: Whether the query result was fetched from the query cache.
	CacheHit bool `json:"cacheHit,omitempty"`

	// Errors: [Output-only] The first errors or warnings encountered during
	// the running of the job. The final message includes the number of
	// errors that caused the process to stop. Errors here do not
	// necessarily mean that the job has completed or was unsuccessful.
	Errors []*ErrorProto `json:"errors,omitempty"`

	// JobComplete: Whether the query has completed or not. If rows or
	// totalRows are present, this will always be true. If this is false,
	// totalRows will not be available.
	JobComplete bool `json:"jobComplete,omitempty"`

	// JobReference: Reference to the Job that was created to run the query.
	// This field will be present even if the original request timed out, in
	// which case GetQueryResults can be used to read the results once the
	// query has completed. Since this API only returns the first page of
	// results, subsequent pages can be fetched via the same mechanism
	// (GetQueryResults).
	JobReference *JobReference `json:"jobReference,omitempty"`

	// Kind: The resource type.
	Kind string `json:"kind,omitempty"`

	// NumDmlAffectedRows: [Output-only] The number of rows affected by a
	// DML statement. Present only for DML statements INSERT, UPDATE or
	// DELETE.
	NumDmlAffectedRows int64 `json:"numDmlAffectedRows,omitempty,string"`

	// PageToken: A token used for paging results.
	PageToken string `json:"pageToken,omitempty"`

	// Rows: An object with as many results as can be contained within the
	// maximum permitted reply size. To get any additional rows, you can
	// call GetQueryResults and specify the jobReference returned above.
	Rows []*TableRow `json:"rows,omitempty"`

	// Schema: The schema of the results. Present only when the query
	// completes successfully.
	Schema *TableSchema `json:"schema,omitempty"`

	// TotalBytesProcessed: The total number of bytes processed for this
	// query. If this query was a dry run, this is the number of bytes that
	// would be processed if the query were run.
	TotalBytesProcessed int64 `json:"totalBytesProcessed,omitempty,string"`

	// TotalRows: The total number of rows in the complete query result set,
	// which can be more than the number of rows in this single page of
	// results.
	TotalRows uint64 `json:"totalRows,omitempty,string"`

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

	// ForceSendFields is a list of field names (e.g. "CacheHit") 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. "CacheHit") 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 *QueryResponse) MarshalJSON() ([]byte, error) {
	type NoMethod QueryResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type QueryTimelineSample struct {
	// ActiveUnits: Total number of units currently being processed by
	// workers. This does not correspond directly to slot usage. This is the
	// largest value observed since the last sample.
	ActiveUnits int64 `json:"activeUnits,omitempty,string"`

	// CompletedUnits: Total parallel units of work completed by this query.
	CompletedUnits int64 `json:"completedUnits,omitempty,string"`

	// ElapsedMs: Milliseconds elapsed since the start of query execution.
	ElapsedMs int64 `json:"elapsedMs,omitempty,string"`

	// PendingUnits: Total parallel units of work remaining for the active
	// stages.
	PendingUnits int64 `json:"pendingUnits,omitempty,string"`

	// TotalSlotMs: Cumulative slot-ms consumed by the query.
	TotalSlotMs int64 `json:"totalSlotMs,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "ActiveUnits") 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. "ActiveUnits") 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 *QueryTimelineSample) MarshalJSON() ([]byte, error) {
	type NoMethod QueryTimelineSample
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RangePartitioning struct {
	// Field: [TrustedTester] [Required] The table is partitioned by this
	// field. The field must be a top-level NULLABLE/REQUIRED field. The
	// only supported type is INTEGER/INT64.
	Field string `json:"field,omitempty"`

	// Range: [TrustedTester] [Required] Defines the ranges for range
	// partitioning.
	Range *RangePartitioningRange `json:"range,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Field") 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. "Field") 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 *RangePartitioning) MarshalJSON() ([]byte, error) {
	type NoMethod RangePartitioning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RangePartitioningRange: [TrustedTester] [Required] Defines the ranges
// for range partitioning.
type RangePartitioningRange struct {
	// End: [TrustedTester] [Required] The end of range partitioning,
	// exclusive.
	End int64 `json:"end,omitempty,string"`

	// Interval: [TrustedTester] [Required] The width of each interval.
	Interval int64 `json:"interval,omitempty,string"`

	// Start: [TrustedTester] [Required] The start of range partitioning,
	// inclusive.
	Start int64 `json:"start,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "End") 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. "End") 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 *RangePartitioningRange) MarshalJSON() ([]byte, error) {
	type NoMethod RangePartitioningRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RankingMetrics: Evaluation metrics used by weighted-ALS models
// specified by
// feedback_type=implicit.
type RankingMetrics struct {
	// AverageRank: Determines the goodness of a ranking by computing the
	// percentile rank
	// from the predicted confidence and dividing it by the original rank.
	AverageRank float64 `json:"averageRank,omitempty"`

	// MeanAveragePrecision: Calculates a precision per user for all the
	// items by ranking them and
	// then averages all the precisions across all the users.
	MeanAveragePrecision float64 `json:"meanAveragePrecision,omitempty"`

	// MeanSquaredError: Similar to the mean squared error computed in
	// regression and explicit
	// recommendation models except instead of computing the rating
	// directly,
	// the output from evaluate is computed against a preference which is 1
	// or 0
	// depending on if the rating exists or not.
	MeanSquaredError float64 `json:"meanSquaredError,omitempty"`

	// NormalizedDiscountedCumulativeGain: A metric to determine the
	// goodness of a ranking calculated from the
	// predicted confidence by comparing it to an ideal rank measured by
	// the
	// original ratings.
	NormalizedDiscountedCumulativeGain float64 `json:"normalizedDiscountedCumulativeGain,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AverageRank") 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. "AverageRank") 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 *RankingMetrics) MarshalJSON() ([]byte, error) {
	type NoMethod RankingMetrics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *RankingMetrics) UnmarshalJSON(data []byte) error {
	type NoMethod RankingMetrics
	var s1 struct {
		AverageRank                        gensupport.JSONFloat64 `json:"averageRank"`
		MeanAveragePrecision               gensupport.JSONFloat64 `json:"meanAveragePrecision"`
		MeanSquaredError                   gensupport.JSONFloat64 `json:"meanSquaredError"`
		NormalizedDiscountedCumulativeGain gensupport.JSONFloat64 `json:"normalizedDiscountedCumulativeGain"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.AverageRank = float64(s1.AverageRank)
	s.MeanAveragePrecision = float64(s1.MeanAveragePrecision)
	s.MeanSquaredError = float64(s1.MeanSquaredError)
	s.NormalizedDiscountedCumulativeGain = float64(s1.NormalizedDiscountedCumulativeGain)
	return nil
}

// RegressionMetrics: Evaluation metrics for regression and explicit
// feedback type matrix
// factorization models.
type RegressionMetrics struct {
	// MeanAbsoluteError: Mean absolute error.
	MeanAbsoluteError float64 `json:"meanAbsoluteError,omitempty"`

	// MeanSquaredError: Mean squared error.
	MeanSquaredError float64 `json:"meanSquaredError,omitempty"`

	// MeanSquaredLogError: Mean squared log error.
	MeanSquaredLogError float64 `json:"meanSquaredLogError,omitempty"`

	// MedianAbsoluteError: Median absolute error.
	MedianAbsoluteError float64 `json:"medianAbsoluteError,omitempty"`

	// RSquared: R^2 score.
	RSquared float64 `json:"rSquared,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MeanAbsoluteError")
	// 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. "MeanAbsoluteError") 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 *RegressionMetrics) MarshalJSON() ([]byte, error) {
	type NoMethod RegressionMetrics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *RegressionMetrics) UnmarshalJSON(data []byte) error {
	type NoMethod RegressionMetrics
	var s1 struct {
		MeanAbsoluteError   gensupport.JSONFloat64 `json:"meanAbsoluteError"`
		MeanSquaredError    gensupport.JSONFloat64 `json:"meanSquaredError"`
		MeanSquaredLogError gensupport.JSONFloat64 `json:"meanSquaredLogError"`
		MedianAbsoluteError gensupport.JSONFloat64 `json:"medianAbsoluteError"`
		RSquared            gensupport.JSONFloat64 `json:"rSquared"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.MeanAbsoluteError = float64(s1.MeanAbsoluteError)
	s.MeanSquaredError = float64(s1.MeanSquaredError)
	s.MeanSquaredLogError = float64(s1.MeanSquaredLogError)
	s.MedianAbsoluteError = float64(s1.MedianAbsoluteError)
	s.RSquared = float64(s1.RSquared)
	return nil
}

// Routine: A user-defined function or a stored procedure.
type Routine struct {
	// Arguments: Optional.
	Arguments []*Argument `json:"arguments,omitempty"`

	// CreationTime: Output only. The time when this routine was created, in
	// milliseconds since
	// the epoch.
	CreationTime int64 `json:"creationTime,omitempty,string"`

	// DefinitionBody: Required. The body of the routine.
	//
	// For functions, this is the expression in the AS clause.
	//
	// If language=SQL, it is the substring inside (but excluding)
	// the
	// parentheses. For example, for the function created with the
	// following
	// statement:
	//
	// `CREATE FUNCTION JoinLines(x string, y string) as (concat(x, "\n",
	// y))`
	//
	// The definition_body is `concat(x, "\n", y)` (\n is not replaced
	// with
	// linebreak).
	//
	// If language=JAVASCRIPT, it is the evaluated string in the AS
	// clause.
	// For example, for the function created with the following
	// statement:
	//
	// `CREATE FUNCTION f() RETURNS STRING LANGUAGE js AS 'return
	// "\n";\n'`
	//
	// The definition_body is
	//
	// `return "\n";\n`
	//
	// Note that both \n are replaced with linebreaks.
	DefinitionBody string `json:"definitionBody,omitempty"`

	// Description: Optional. [Experimental] The description of the routine
	// if defined.
	Description string `json:"description,omitempty"`

	// Etag: Output only. A hash of this resource.
	Etag string `json:"etag,omitempty"`

	// ImportedLibraries: Optional. If language = "JAVASCRIPT", this field
	// stores the path of the
	// imported JAVASCRIPT libraries.
	ImportedLibraries []string `json:"importedLibraries,omitempty"`

	// Language: Optional. Defaults to "SQL".
	//
	// Possible values:
	//   "LANGUAGE_UNSPECIFIED"
	//   "SQL" - SQL language.
	//   "JAVASCRIPT" - JavaScript language.
	Language string `json:"language,omitempty"`

	// LastModifiedTime: Output only. The time when this routine was last
	// modified, in milliseconds
	// since the epoch.
	LastModifiedTime int64 `json:"lastModifiedTime,omitempty,string"`

	// ReturnType: Optional if language = "SQL"; required otherwise.
	//
	// If absent, the return type is inferred from definition_body at query
	// time
	// in each query that references this routine. If present, then the
	// evaluated
	// result will be cast to the specified returned type at query
	// time.
	//
	// For example, for the functions created with the following
	// statements:
	//
	// * `CREATE FUNCTION Add(x FLOAT64, y FLOAT64) RETURNS FLOAT64 AS (x +
	// y);`
	//
	// * `CREATE FUNCTION Increment(x FLOAT64) AS (Add(x, 1));`
	//
	// * `CREATE FUNCTION Decrement(x FLOAT64) RETURNS FLOAT64 AS (Add(x,
	// -1));`
	//
	// The return_type is `{type_kind: "FLOAT64"}` for `Add` and
	// `Decrement`, and
	// is absent for `Increment` (inferred as FLOAT64 at query
	// time).
	//
	// Suppose the function `Add` is replaced by
	//   `CREATE OR REPLACE FUNCTION Add(x INT64, y INT64) AS (x +
	// y);`
	//
	// Then the inferred return type of `Increment` is automatically changed
	// to
	// INT64 at query time, while the return type of `Decrement` remains
	// FLOAT64.
	ReturnType *StandardSqlDataType `json:"returnType,omitempty"`

	// RoutineReference: Required. Reference describing the ID of this
	// routine.
	RoutineReference *RoutineReference `json:"routineReference,omitempty"`

	// RoutineType: Required. The type of routine.
	//
	// Possible values:
	//   "ROUTINE_TYPE_UNSPECIFIED"
	//   "SCALAR_FUNCTION" - Non-builtin permanent scalar function.
	//   "PROCEDURE" - Stored procedure.
	RoutineType string `json:"routineType,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Arguments") 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. "Arguments") 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 *Routine) MarshalJSON() ([]byte, error) {
	type NoMethod Routine
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RoutineReference struct {
	// DatasetId: [Required] The ID of the dataset containing this routine.
	DatasetId string `json:"datasetId,omitempty"`

	// ProjectId: [Required] The ID of the project containing this routine.
	ProjectId string `json:"projectId,omitempty"`

	// RoutineId: [Required] The ID of the routine. The ID must contain only
	// letters (a-z, A-Z), numbers (0-9), or underscores (_). The maximum
	// length is 256 characters.
	RoutineId string `json:"routineId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DatasetId") 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. "DatasetId") 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 *RoutineReference) MarshalJSON() ([]byte, error) {
	type NoMethod RoutineReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Row: A single row in the confusion matrix.
type Row struct {
	// ActualLabel: The original label of this row.
	ActualLabel string `json:"actualLabel,omitempty"`

	// Entries: Info describing predicted label distribution.
	Entries []*Entry `json:"entries,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActualLabel") 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. "ActualLabel") 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 *Row) MarshalJSON() ([]byte, error) {
	type NoMethod Row
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RowAccessPolicyReference struct {
	// DatasetId: [Required] The ID of the dataset containing this row
	// access policy.
	DatasetId string `json:"datasetId,omitempty"`

	// PolicyId: [Required] The ID of the row access policy. The ID must
	// contain only letters (a-z, A-Z), numbers (0-9), or underscores (_).
	// The maximum length is 256 characters.
	PolicyId string `json:"policyId,omitempty"`

	// ProjectId: [Required] The ID of the project containing this row
	// access policy.
	ProjectId string `json:"projectId,omitempty"`

	// TableId: [Required] The ID of the table containing this row access
	// policy.
	TableId string `json:"tableId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DatasetId") 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. "DatasetId") 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 *RowAccessPolicyReference) MarshalJSON() ([]byte, error) {
	type NoMethod RowAccessPolicyReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type RowLevelSecurityStatistics struct {
	// RowLevelSecurityApplied: [Output-only] [Preview] Whether any accessed
	// data was protected by row access policies.
	RowLevelSecurityApplied bool `json:"rowLevelSecurityApplied,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "RowLevelSecurityApplied") 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. "RowLevelSecurityApplied")
	// 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 *RowLevelSecurityStatistics) MarshalJSON() ([]byte, error) {
	type NoMethod RowLevelSecurityStatistics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ScriptStackFrame struct {
	// EndColumn: [Output-only] One-based end column.
	EndColumn int64 `json:"endColumn,omitempty"`

	// EndLine: [Output-only] One-based end line.
	EndLine int64 `json:"endLine,omitempty"`

	// ProcedureId: [Output-only] Name of the active procedure, empty if in
	// a top-level script.
	ProcedureId string `json:"procedureId,omitempty"`

	// StartColumn: [Output-only] One-based start column.
	StartColumn int64 `json:"startColumn,omitempty"`

	// StartLine: [Output-only] One-based start line.
	StartLine int64 `json:"startLine,omitempty"`

	// Text: [Output-only] Text of the current statement/expression.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndColumn") 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. "EndColumn") 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 *ScriptStackFrame) MarshalJSON() ([]byte, error) {
	type NoMethod ScriptStackFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ScriptStatistics struct {
	// EvaluationKind: [Output-only] Whether this child job was a statement
	// or expression.
	EvaluationKind string `json:"evaluationKind,omitempty"`

	// StackFrames: Stack trace showing the line/column/procedure name of
	// each frame on the stack at the point where the current evaluation
	// happened. The leaf frame is first, the primary script is last. Never
	// empty.
	StackFrames []*ScriptStackFrame `json:"stackFrames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EvaluationKind") 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. "EvaluationKind") 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 *ScriptStatistics) MarshalJSON() ([]byte, error) {
	type NoMethod ScriptStatistics
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// StandardSqlDataType: The type of a variable, e.g., a function
// argument.
// Examples:
// INT64: {type_kind="INT64"}
// ARRAY<STRING>: {type_kind="ARRAY",
// array_element_type="STRING"}
// STRUCT<x STRING, y ARRAY<DATE>>:
//   {type_kind="STRUCT",
//    struct_type={fields=[
//      {name="x", type={type_kind="STRING"}},
//      {name="y", type={type_kind="ARRAY", array_element_type="DATE"}}
//    ]}}
type StandardSqlDataType struct {
	// ArrayElementType: The type of the array's elements, if type_kind =
	// "ARRAY".
	ArrayElementType *StandardSqlDataType `json:"arrayElementType,omitempty"`

	// StructType: The fields of this struct, in order, if type_kind =
	// "STRUCT".
	StructType *StandardSqlStructType `json:"structType,omitempty"`

	// TypeKind: Required. The top level type of this field.
	// Can be any standard SQL data type (e.g., "INT64", "DATE", "ARRAY").
	//
	// Possible values:
	//   "TYPE_KIND_UNSPECIFIED" - Invalid type.
	//   "INT64" - Encoded as a string in decimal format.
	//   "BOOL" - Encoded as a boolean "false" or "true".
	//   "FLOAT64" - Encoded as a number, or string "NaN", "Infinity" or
	// "-Infinity".
	//   "STRING" - Encoded as a string value.
	//   "BYTES" - Encoded as a base64 string per RFC 4648, section 4.
	//   "TIMESTAMP" - Encoded as an RFC 3339 timestamp with mandatory "Z"
	// time zone string:
	// 1985-04-12T23:20:50.52Z
	//   "DATE" - Encoded as RFC 3339 full-date format string: 1985-04-12
	//   "TIME" - Encoded as RFC 3339 partial-time format string:
	// 23:20:50.52
	//   "DATETIME" - Encoded as RFC 3339 full-date "T" partial-time:
	// 1985-04-12T23:20:50.52
	//   "GEOGRAPHY" - Encoded as WKT
	//   "NUMERIC" - Encoded as a decimal string.
	//   "ARRAY" - Encoded as a list with types matching Type.array_type.
	//   "STRUCT" - Encoded as a list with fields of type
	// Type.struct_type[i]. List is used
	// because a JSON object cannot have duplicate field names.
	TypeKind string `json:"typeKind,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ArrayElementType") 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. "ArrayElementType") 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 *StandardSqlDataType) MarshalJSON() ([]byte, error) {
	type NoMethod StandardSqlDataType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// StandardSqlField: A field or a column.
type StandardSqlField struct {
	// Name: Optional. The name of this field. Can be absent for struct
	// fields.
	Name string `json:"name,omitempty"`

	// Type: Optional. The type of this parameter. Absent if not
	// explicitly
	// specified (e.g., CREATE FUNCTION statement can omit the return
	// type;
	// in this case the output parameter does not have this "type" field).
	Type *StandardSqlDataType `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 *StandardSqlField) MarshalJSON() ([]byte, error) {
	type NoMethod StandardSqlField
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type StandardSqlStructType struct {
	Fields []*StandardSqlField `json:"fields,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") 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. "Fields") 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 *StandardSqlStructType) MarshalJSON() ([]byte, error) {
	type NoMethod StandardSqlStructType
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type Streamingbuffer struct {
	// EstimatedBytes: [Output-only] A lower-bound estimate of the number of
	// bytes currently in the streaming buffer.
	EstimatedBytes uint64 `json:"estimatedBytes,omitempty,string"`

	// EstimatedRows: [Output-only] A lower-bound estimate of the number of
	// rows currently in the streaming buffer.
	EstimatedRows uint64 `json:"estimatedRows,omitempty,string"`

	// OldestEntryTime: [Output-only] Contains the timestamp of the oldest
	// entry in the streaming buffer, in milliseconds since the epoch, if
	// the streaming buffer is available.
	OldestEntryTime uint64 `json:"oldestEntryTime,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "EstimatedBytes") 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. "EstimatedBytes") 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 *Streamingbuffer) MarshalJSON() ([]byte, error) {
	type NoMethod Streamingbuffer
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type Table struct {
	// Clustering: [Beta] Clustering specification for the table. Must be
	// specified with partitioning, data in the table will be first
	// partitioned and subsequently clustered.
	Clustering *Clustering `json:"clustering,omitempty"`

	// CreationTime: [Output-only] The time when this table was created, in
	// milliseconds since the epoch.
	CreationTime int64 `json:"creationTime,omitempty,string"`

	// Description: [Optional] A user-friendly description of this table.
	Description string `json:"description,omitempty"`

	// EncryptionConfiguration: Custom encryption configuration (e.g., Cloud
	// KMS keys).
	EncryptionConfiguration *EncryptionConfiguration `json:"encryptionConfiguration,omitempty"`

	// Etag: [Output-only] A hash of the table metadata. Used to ensure
	// there were no concurrent modifications to the resource when
	// attempting an update. Not guaranteed to change when the table
	// contents or the fields numRows, numBytes, numLongTermBytes or
	// lastModifiedTime change.
	Etag string `json:"etag,omitempty"`

	// ExpirationTime: [Optional] The time when this table expires, in
	// milliseconds since the epoch. If not present, the table will persist
	// indefinitely. Expired tables will be deleted and their storage
	// reclaimed. The defaultTableExpirationMs property of the encapsulating
	// dataset can be used to set a default expirationTime on newly created
	// tables.
	ExpirationTime int64 `json:"expirationTime,omitempty,string"`

	// ExternalDataConfiguration: [Optional] Describes the data format,
	// location, and other properties of a table stored outside of BigQuery.
	// By defining these properties, the data source can then be queried as
	// if it were a standard BigQuery table.
	ExternalDataConfiguration *ExternalDataConfiguration `json:"externalDataConfiguration,omitempty"`

	// FriendlyName: [Optional] A descriptive name for this table.
	FriendlyName string `json:"friendlyName,omitempty"`

	// Id: [Output-only] An opaque ID uniquely identifying the table.
	Id string `json:"id,omitempty"`

	// Kind: [Output-only] The type of the resource.
	Kind string `json:"kind,omitempty"`

	// Labels: The labels associated with this table. You can use these to
	// organize and group your tables. Label keys and values can be no
	// longer than 63 characters, can only contain lowercase letters,
	// numeric characters, underscores and dashes. International characters
	// are allowed. Label values are optional. Label keys must start with a
	// letter and each label in the list must have a different key.
	Labels map[string]string `json:"labels,omitempty"`

	// LastModifiedTime: [Output-only] The time when this table was last
	// modified, in milliseconds since the epoch.
	LastModifiedTime uint64 `json:"lastModifiedTime,omitempty,string"`

	// Location: [Output-only] The geographic location where the table
	// resides. This value is inherited from the dataset.
	Location string `json:"location,omitempty"`

	// MaterializedView: [Optional] Materialized view definition.
	MaterializedView *MaterializedViewDefinition `json:"materializedView,omitempty"`

	// Model: [Output-only, Beta] Present iff this table represents a ML
	// model. Describes the training information for the model, and it is
	// required to run 'PREDICT' queries.
	Model *ModelDefinition `json:"model,omitempty"`

	// NumBytes: [Output-only] The size of this table in bytes, excluding
	// any data in the streaming buffer.
	NumBytes int64 `json:"numBytes,omitempty,string"`

	// NumLongTermBytes: [Output-only] The number of bytes in the table that
	// are considered "long-term storage".
	NumLongTermBytes int64 `json:"numLongTermBytes,omitempty,string"`

	// NumPhysicalBytes: [Output-only] [TrustedTester] The physical size of
	// this table in bytes, excluding any data in the streaming buffer. This
	// includes compression and storage used for time travel.
	NumPhysicalBytes int64 `json:"numPhysicalBytes,omitempty,string"`

	// NumRows: [Output-only] The number of rows of data in this table,
	// excluding any data in the streaming buffer.
	NumRows uint64 `json:"numRows,omitempty,string"`

	// RangePartitioning: [TrustedTester] Range partitioning specification
	// for this table. Only one of timePartitioning and rangePartitioning
	// should be specified.
	RangePartitioning *RangePartitioning `json:"rangePartitioning,omitempty"`

	// RequirePartitionFilter: [Optional] If set to true, queries over this
	// table require a partition filter that can be used for partition
	// elimination to be specified.
	RequirePartitionFilter bool `json:"requirePartitionFilter,omitempty"`

	// Schema: [Optional] Describes the schema of this table.
	Schema *TableSchema `json:"schema,omitempty"`

	// SelfLink: [Output-only] A URL that can be used to access this
	// resource again.
	SelfLink string `json:"selfLink,omitempty"`

	// StreamingBuffer: [Output-only] Contains information regarding this
	// table's streaming buffer, if one is present. This field will be
	// absent if the table is not being streamed to or if there is no data
	// in the streaming buffer.
	StreamingBuffer *Streamingbuffer `json:"streamingBuffer,omitempty"`

	// TableReference: [Required] Reference describing the ID of this table.
	TableReference *TableReference `json:"tableReference,omitempty"`

	// TimePartitioning: Time-based partitioning specification for this
	// table. Only one of timePartitioning and rangePartitioning should be
	// specified.
	TimePartitioning *TimePartitioning `json:"timePartitioning,omitempty"`

	// Type: [Output-only] Describes the table type. The following values
	// are supported: TABLE: A normal BigQuery table. VIEW: A virtual table
	// defined by a SQL query. [TrustedTester] MATERIALIZED_VIEW: SQL query
	// whose result is persisted. EXTERNAL: A table that references data
	// stored in an external storage system, such as Google Cloud Storage.
	// The default value is TABLE.
	Type string `json:"type,omitempty"`

	// View: [Optional] The view definition.
	View *ViewDefinition `json:"view,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Clustering") 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. "Clustering") 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 *Table) MarshalJSON() ([]byte, error) {
	type NoMethod Table
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableCell struct {
	V interface{} `json:"v,omitempty"`

	// ForceSendFields is a list of field names (e.g. "V") 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. "V") 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 *TableCell) MarshalJSON() ([]byte, error) {
	type NoMethod TableCell
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableDataInsertAllRequest struct {
	// IgnoreUnknownValues: [Optional] Accept rows that contain values that
	// do not match the schema. The unknown values are ignored. Default is
	// false, which treats unknown values as errors.
	IgnoreUnknownValues bool `json:"ignoreUnknownValues,omitempty"`

	// Kind: The resource type of the response.
	Kind string `json:"kind,omitempty"`

	// Rows: The rows to insert.
	Rows []*TableDataInsertAllRequestRows `json:"rows,omitempty"`

	// SkipInvalidRows: [Optional] Insert all valid rows of a request, even
	// if invalid rows exist. The default value is false, which causes the
	// entire request to fail if any invalid rows exist.
	SkipInvalidRows bool `json:"skipInvalidRows,omitempty"`

	// TemplateSuffix: If specified, treats the destination table as a base
	// template, and inserts the rows into an instance table named
	// "{destination}{templateSuffix}". BigQuery will manage creation of the
	// instance table, using the schema of the base template table. See
	// https://cloud.google.com/bigquery/streaming-data-into-bigquery#template-tables for considerations when working with templates
	// tables.
	TemplateSuffix string `json:"templateSuffix,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IgnoreUnknownValues")
	// 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. "IgnoreUnknownValues") 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 *TableDataInsertAllRequest) MarshalJSON() ([]byte, error) {
	type NoMethod TableDataInsertAllRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableDataInsertAllRequestRows struct {
	// InsertId: [Optional] A unique ID for each row. BigQuery uses this
	// property to detect duplicate insertion requests on a best-effort
	// basis.
	InsertId string `json:"insertId,omitempty"`

	// Json: [Required] A JSON object that contains a row of data. The
	// object's properties and values must match the destination table's
	// schema.
	Json map[string]JsonValue `json:"json,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InsertId") 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. "InsertId") 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 *TableDataInsertAllRequestRows) MarshalJSON() ([]byte, error) {
	type NoMethod TableDataInsertAllRequestRows
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableDataInsertAllResponse struct {
	// InsertErrors: An array of errors for rows that were not inserted.
	InsertErrors []*TableDataInsertAllResponseInsertErrors `json:"insertErrors,omitempty"`

	// Kind: The resource type of the response.
	Kind string `json:"kind,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "InsertErrors") 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. "InsertErrors") 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 *TableDataInsertAllResponse) MarshalJSON() ([]byte, error) {
	type NoMethod TableDataInsertAllResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableDataInsertAllResponseInsertErrors struct {
	// Errors: Error information for the row indicated by the index
	// property.
	Errors []*ErrorProto `json:"errors,omitempty"`

	// Index: The index of the row that error applies to.
	Index int64 `json:"index,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Errors") 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. "Errors") 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 *TableDataInsertAllResponseInsertErrors) MarshalJSON() ([]byte, error) {
	type NoMethod TableDataInsertAllResponseInsertErrors
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableDataList struct {
	// Etag: A hash of this page of results.
	Etag string `json:"etag,omitempty"`

	// Kind: The resource type of the response.
	Kind string `json:"kind,omitempty"`

	// PageToken: A token used for paging results. Providing this token
	// instead of the startIndex parameter can help you retrieve stable
	// results when an underlying table is changing.
	PageToken string `json:"pageToken,omitempty"`

	// Rows: Rows of results.
	Rows []*TableRow `json:"rows,omitempty"`

	// TotalRows: The total number of rows in the complete table.
	TotalRows int64 `json:"totalRows,omitempty,string"`

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

	// ForceSendFields is a list of field names (e.g. "Etag") 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. "Etag") 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 *TableDataList) MarshalJSON() ([]byte, error) {
	type NoMethod TableDataList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableFieldSchema struct {
	// Categories: [Optional] The categories attached to this field, used
	// for field-level access control.
	Categories *TableFieldSchemaCategories `json:"categories,omitempty"`

	// Description: [Optional] The field description. The maximum length is
	// 1,024 characters.
	Description string `json:"description,omitempty"`

	// Fields: [Optional] Describes the nested schema fields if the type
	// property is set to RECORD.
	Fields []*TableFieldSchema `json:"fields,omitempty"`

	// Mode: [Optional] The field mode. Possible values include NULLABLE,
	// REQUIRED and REPEATED. The default value is NULLABLE.
	Mode string `json:"mode,omitempty"`

	// Name: [Required] The field name. The name must contain only letters
	// (a-z, A-Z), numbers (0-9), or underscores (_), and must start with a
	// letter or underscore. The maximum length is 128 characters.
	Name string `json:"name,omitempty"`

	PolicyTags *TableFieldSchemaPolicyTags `json:"policyTags,omitempty"`

	// Type: [Required] The field data type. Possible values include STRING,
	// BYTES, INTEGER, INT64 (same as INTEGER), FLOAT, FLOAT64 (same as
	// FLOAT), BOOLEAN, BOOL (same as BOOLEAN), TIMESTAMP, DATE, TIME,
	// DATETIME, RECORD (where RECORD indicates that the field contains a
	// nested schema) or STRUCT (same as RECORD).
	Type string `json:"type,omitempty"`

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

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

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

// TableFieldSchemaCategories: [Optional] The categories attached to
// this field, used for field-level access control.
type TableFieldSchemaCategories struct {
	// Names: A list of category resource names. For example,
	// "projects/1/taxonomies/2/categories/3". At most 5 categories are
	// allowed.
	Names []string `json:"names,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Names") 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. "Names") 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 *TableFieldSchemaCategories) MarshalJSON() ([]byte, error) {
	type NoMethod TableFieldSchemaCategories
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableFieldSchemaPolicyTags struct {
	// Names: A list of category resource names. For example,
	// "projects/1/location/eu/taxonomies/2/policyTags/3". At most 1 policy
	// tag is allowed.
	Names []string `json:"names,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Names") 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. "Names") 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 *TableFieldSchemaPolicyTags) MarshalJSON() ([]byte, error) {
	type NoMethod TableFieldSchemaPolicyTags
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableList struct {
	// Etag: A hash of this page of results.
	Etag string `json:"etag,omitempty"`

	// Kind: The type of list.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: A token to request the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Tables: Tables in the requested dataset.
	Tables []*TableListTables `json:"tables,omitempty"`

	// TotalItems: The total number of tables in the dataset.
	TotalItems int64 `json:"totalItems,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Etag") 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. "Etag") 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 *TableList) MarshalJSON() ([]byte, error) {
	type NoMethod TableList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableListTables struct {
	// Clustering: [Beta] Clustering specification for this table, if
	// configured.
	Clustering *Clustering `json:"clustering,omitempty"`

	// CreationTime: The time when this table was created, in milliseconds
	// since the epoch.
	CreationTime int64 `json:"creationTime,omitempty,string"`

	// ExpirationTime: [Optional] The time when this table expires, in
	// milliseconds since the epoch. If not present, the table will persist
	// indefinitely. Expired tables will be deleted and their storage
	// reclaimed.
	ExpirationTime int64 `json:"expirationTime,omitempty,string"`

	// FriendlyName: The user-friendly name for this table.
	FriendlyName string `json:"friendlyName,omitempty"`

	// Id: An opaque ID of the table
	Id string `json:"id,omitempty"`

	// Kind: The resource type.
	Kind string `json:"kind,omitempty"`

	// Labels: The labels associated with this table. You can use these to
	// organize and group your tables.
	Labels map[string]string `json:"labels,omitempty"`

	// RangePartitioning: The range partitioning specification for this
	// table, if configured.
	RangePartitioning *RangePartitioning `json:"rangePartitioning,omitempty"`

	// TableReference: A reference uniquely identifying the table.
	TableReference *TableReference `json:"tableReference,omitempty"`

	// TimePartitioning: The time-based partitioning specification for this
	// table, if configured.
	TimePartitioning *TimePartitioning `json:"timePartitioning,omitempty"`

	// Type: The type of table. Possible values are: TABLE, VIEW.
	Type string `json:"type,omitempty"`

	// View: Additional details for a view.
	View *TableListTablesView `json:"view,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Clustering") 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. "Clustering") 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 *TableListTables) MarshalJSON() ([]byte, error) {
	type NoMethod TableListTables
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableListTablesView: Additional details for a view.
type TableListTablesView struct {
	// UseLegacySql: True if view is defined in legacy SQL dialect, false if
	// in standard SQL.
	UseLegacySql bool `json:"useLegacySql,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UseLegacySql") 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. "UseLegacySql") 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 *TableListTablesView) MarshalJSON() ([]byte, error) {
	type NoMethod TableListTablesView
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableReference struct {
	// DatasetId: [Required] The ID of the dataset containing this table.
	DatasetId string `json:"datasetId,omitempty"`

	// ProjectId: [Required] The ID of the project containing this table.
	ProjectId string `json:"projectId,omitempty"`

	// TableId: [Required] The ID of the table. The ID must contain only
	// letters (a-z, A-Z), numbers (0-9), or underscores (_). The maximum
	// length is 1,024 characters.
	TableId string `json:"tableId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DatasetId") 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. "DatasetId") 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 *TableReference) MarshalJSON() ([]byte, error) {
	type NoMethod TableReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableRow struct {
	// F: Represents a single row in the result set, consisting of one or
	// more fields.
	F []*TableCell `json:"f,omitempty"`

	// ForceSendFields is a list of field names (e.g. "F") 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. "F") 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 *TableRow) MarshalJSON() ([]byte, error) {
	type NoMethod TableRow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TableSchema struct {
	// Fields: Describes the fields in a table.
	Fields []*TableFieldSchema `json:"fields,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") 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. "Fields") 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 *TableSchema) MarshalJSON() ([]byte, error) {
	type NoMethod TableSchema
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TimePartitioning struct {
	// ExpirationMs: [Optional] Number of milliseconds for which to keep the
	// storage for partitions in the table. The storage in a partition will
	// have an expiration time of its partition time plus this value.
	ExpirationMs int64 `json:"expirationMs,omitempty,string"`

	// Field: [Beta] [Optional] If not set, the table is partitioned by
	// pseudo column, referenced via either '_PARTITIONTIME' as TIMESTAMP
	// type, or '_PARTITIONDATE' as DATE type. If field is specified, the
	// table is instead partitioned by this field. The field must be a
	// top-level TIMESTAMP or DATE field. Its mode must be NULLABLE or
	// REQUIRED.
	Field string `json:"field,omitempty"`

	RequirePartitionFilter bool `json:"requirePartitionFilter,omitempty"`

	// Type: [Required] The only type supported is DAY, which will generate
	// one partition per day.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExpirationMs") 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. "ExpirationMs") 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 *TimePartitioning) MarshalJSON() ([]byte, error) {
	type NoMethod TimePartitioning
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type TrainingOptions struct {
	// BatchSize: Batch size for dnn models.
	BatchSize int64 `json:"batchSize,omitempty,string"`

	// DataSplitColumn: The column to split data with. This column won't be
	// used as a
	// feature.
	// 1. When data_split_method is CUSTOM, the corresponding column
	// should
	// be boolean. The rows with true value tag are eval data, and the
	// false
	// are training data.
	// 2. When data_split_method is SEQ, the first
	// DATA_SPLIT_EVAL_FRACTION
	// rows (from smallest to largest) in the corresponding column are
	// used
	// as training data, and the rest are eval data. It respects the
	// order
	// in Orderable data
	// types:
	// https://cloud.google.com/bigquery/docs/reference/standard-sql/d
	// ata-types#data-type-properties
	DataSplitColumn string `json:"dataSplitColumn,omitempty"`

	// DataSplitEvalFraction: The fraction of evaluation data over the whole
	// input data. The rest
	// of data will be used as training data. The format should be
	// double.
	// Accurate to two decimal places.
	// Default value is 0.2.
	DataSplitEvalFraction float64 `json:"dataSplitEvalFraction,omitempty"`

	// DataSplitMethod: The data split type for training and evaluation,
	// e.g. RANDOM.
	//
	// Possible values:
	//   "DATA_SPLIT_METHOD_UNSPECIFIED"
	//   "RANDOM" - Splits data randomly.
	//   "CUSTOM" - Splits data with the user provided tags.
	//   "SEQUENTIAL" - Splits data sequentially.
	//   "NO_SPLIT" - Data split will be skipped.
	//   "AUTO_SPLIT" - Splits data automatically: Uses NO_SPLIT if the data
	// size is small.
	// Otherwise uses RANDOM.
	DataSplitMethod string `json:"dataSplitMethod,omitempty"`

	// DistanceType: Distance type for clustering models.
	//
	// Possible values:
	//   "DISTANCE_TYPE_UNSPECIFIED"
	//   "EUCLIDEAN" - Eculidean distance.
	//   "COSINE" - Cosine distance.
	DistanceType string `json:"distanceType,omitempty"`

	// Dropout: Dropout probability for dnn models.
	Dropout float64 `json:"dropout,omitempty"`

	// EarlyStop: Whether to stop early when the loss doesn't improve
	// significantly
	// any more (compared to min_relative_progress). Used only for
	// iterative
	// training algorithms.
	EarlyStop bool `json:"earlyStop,omitempty"`

	// FeedbackType: Feedback type that specifies which algorithm to run for
	// matrix
	// factorization.
	//
	// Possible values:
	//   "FEEDBACK_TYPE_UNSPECIFIED"
	//   "IMPLICIT" - Use weighted-als for implicit feedback problems.
	//   "EXPLICIT" - Use nonweighted-als for explicit feedback problems.
	FeedbackType string `json:"feedbackType,omitempty"`

	// HiddenUnits: Hidden units for dnn models.
	HiddenUnits googleapi.Int64s `json:"hiddenUnits,omitempty"`

	// InitialLearnRate: Specifies the initial learning rate for the line
	// search learn rate
	// strategy.
	InitialLearnRate float64 `json:"initialLearnRate,omitempty"`

	// InputLabelColumns: Name of input label columns in training data.
	InputLabelColumns []string `json:"inputLabelColumns,omitempty"`

	// ItemColumn: Item column specified for matrix factorization models.
	ItemColumn string `json:"itemColumn,omitempty"`

	// KmeansInitializationColumn: The column used to provide the initial
	// centroids for kmeans algorithm
	// when kmeans_initialization_method is CUSTOM.
	KmeansInitializationColumn string `json:"kmeansInitializationColumn,omitempty"`

	// KmeansInitializationMethod: The method used to initialize the
	// centroids for kmeans algorithm.
	//
	// Possible values:
	//   "KMEANS_INITIALIZATION_METHOD_UNSPECIFIED"
	//   "RANDOM" - Initializes the centroids randomly.
	//   "CUSTOM" - Initializes the centroids using data specified
	// in
	// kmeans_initialization_column.
	//   "KMEANS_PLUS_PLUS" - Initializes with kmeans++.
	KmeansInitializationMethod string `json:"kmeansInitializationMethod,omitempty"`

	// L1Regularization: L1 regularization coefficient.
	L1Regularization float64 `json:"l1Regularization,omitempty"`

	// L2Regularization: L2 regularization coefficient.
	L2Regularization float64 `json:"l2Regularization,omitempty"`

	// LabelClassWeights: Weights associated with each label class, for
	// rebalancing the
	// training data. Only applicable for classification models.
	LabelClassWeights map[string]float64 `json:"labelClassWeights,omitempty"`

	// LearnRate: Learning rate in training. Used only for iterative
	// training algorithms.
	LearnRate float64 `json:"learnRate,omitempty"`

	// LearnRateStrategy: The strategy to determine learn rate for the
	// current iteration.
	//
	// Possible values:
	//   "LEARN_RATE_STRATEGY_UNSPECIFIED"
	//   "LINE_SEARCH" - Use line search to determine learning rate.
	//   "CONSTANT" - Use a constant learning rate.
	LearnRateStrategy string `json:"learnRateStrategy,omitempty"`

	// LossType: Type of loss function used during training run.
	//
	// Possible values:
	//   "LOSS_TYPE_UNSPECIFIED"
	//   "MEAN_SQUARED_LOSS" - Mean squared loss, used for linear
	// regression.
	//   "MEAN_LOG_LOSS" - Mean log loss, used for logistic regression.
	LossType string `json:"lossType,omitempty"`

	// MaxIterations: The maximum number of iterations in training. Used
	// only for iterative
	// training algorithms.
	MaxIterations int64 `json:"maxIterations,omitempty,string"`

	// MaxTreeDepth: Maximum depth of a tree for boosted tree models.
	MaxTreeDepth int64 `json:"maxTreeDepth,omitempty,string"`

	// MinRelativeProgress: When early_stop is true, stops training when
	// accuracy improvement is
	// less than 'min_relative_progress'. Used only for iterative
	// training
	// algorithms.
	MinRelativeProgress float64 `json:"minRelativeProgress,omitempty"`

	// MinSplitLoss: Minimum split loss for boosted tree models.
	MinSplitLoss float64 `json:"minSplitLoss,omitempty"`

	// ModelUri: [Beta] Google Cloud Storage URI from which the model was
	// imported. Only
	// applicable for imported models.
	ModelUri string `json:"modelUri,omitempty"`

	// NumClusters: Number of clusters for clustering models.
	NumClusters int64 `json:"numClusters,omitempty,string"`

	// NumFactors: Num factors specified for matrix factorization models.
	NumFactors int64 `json:"numFactors,omitempty,string"`

	// OptimizationStrategy: Optimization strategy for training linear
	// regression models.
	//
	// Possible values:
	//   "OPTIMIZATION_STRATEGY_UNSPECIFIED"
	//   "BATCH_GRADIENT_DESCENT" - Uses an iterative batch gradient descent
	// algorithm.
	//   "NORMAL_EQUATION" - Uses a normal equation to solve linear
	// regression problem.
	OptimizationStrategy string `json:"optimizationStrategy,omitempty"`

	// Subsample: Subsample fraction of the training data to grow tree to
	// prevent
	// overfitting for boosted tree models.
	Subsample float64 `json:"subsample,omitempty"`

	// UserColumn: User column specified for matrix factorization models.
	UserColumn string `json:"userColumn,omitempty"`

	// WalsAlpha: Hyperparameter for matrix factoration when implicit
	// feedback type is
	// specified.
	WalsAlpha float64 `json:"walsAlpha,omitempty"`

	// WarmStart: Whether to train a model from the last checkpoint.
	WarmStart bool `json:"warmStart,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BatchSize") 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. "BatchSize") 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 *TrainingOptions) MarshalJSON() ([]byte, error) {
	type NoMethod TrainingOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *TrainingOptions) UnmarshalJSON(data []byte) error {
	type NoMethod TrainingOptions
	var s1 struct {
		DataSplitEvalFraction gensupport.JSONFloat64 `json:"dataSplitEvalFraction"`
		Dropout               gensupport.JSONFloat64 `json:"dropout"`
		InitialLearnRate      gensupport.JSONFloat64 `json:"initialLearnRate"`
		L1Regularization      gensupport.JSONFloat64 `json:"l1Regularization"`
		L2Regularization      gensupport.JSONFloat64 `json:"l2Regularization"`
		LearnRate             gensupport.JSONFloat64 `json:"learnRate"`
		MinRelativeProgress   gensupport.JSONFloat64 `json:"minRelativeProgress"`
		MinSplitLoss          gensupport.JSONFloat64 `json:"minSplitLoss"`
		Subsample             gensupport.JSONFloat64 `json:"subsample"`
		WalsAlpha             gensupport.JSONFloat64 `json:"walsAlpha"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DataSplitEvalFraction = float64(s1.DataSplitEvalFraction)
	s.Dropout = float64(s1.Dropout)
	s.InitialLearnRate = float64(s1.InitialLearnRate)
	s.L1Regularization = float64(s1.L1Regularization)
	s.L2Regularization = float64(s1.L2Regularization)
	s.LearnRate = float64(s1.LearnRate)
	s.MinRelativeProgress = float64(s1.MinRelativeProgress)
	s.MinSplitLoss = float64(s1.MinSplitLoss)
	s.Subsample = float64(s1.Subsample)
	s.WalsAlpha = float64(s1.WalsAlpha)
	return nil
}

// TrainingRun: Information about a single training query run for the
// model.
type TrainingRun struct {
	// DataSplitResult: Data split result of the training run. Only set when
	// the input data is
	// actually split.
	DataSplitResult *DataSplitResult `json:"dataSplitResult,omitempty"`

	// EvaluationMetrics: The evaluation metrics over training/eval data
	// that were computed at the
	// end of training.
	EvaluationMetrics *EvaluationMetrics `json:"evaluationMetrics,omitempty"`

	// Results: Output of each iteration run, results.size() <=
	// max_iterations.
	Results []*IterationResult `json:"results,omitempty"`

	// StartTime: The start time of this training run.
	StartTime string `json:"startTime,omitempty"`

	// TrainingOptions: Options that were used for this training run,
	// includes
	// user specified and default options that were used.
	TrainingOptions *TrainingOptions `json:"trainingOptions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DataSplitResult") 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. "DataSplitResult") 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 *TrainingRun) MarshalJSON() ([]byte, error) {
	type NoMethod TrainingRun
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type UserDefinedFunctionResource struct {
	// InlineCode: [Pick one] An inline resource that contains code for a
	// user-defined function (UDF). Providing a inline code resource is
	// equivalent to providing a URI for a file containing the same code.
	InlineCode string `json:"inlineCode,omitempty"`

	// ResourceUri: [Pick one] A code resource to load from a Google Cloud
	// Storage URI (gs://bucket/path).
	ResourceUri string `json:"resourceUri,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InlineCode") 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. "InlineCode") 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 *UserDefinedFunctionResource) MarshalJSON() ([]byte, error) {
	type NoMethod UserDefinedFunctionResource
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type ViewDefinition struct {
	// Query: [Required] A query that BigQuery executes when the view is
	// referenced.
	Query string `json:"query,omitempty"`

	// UseLegacySql: Specifies whether to use BigQuery's legacy SQL for this
	// view. The default value is true. If set to false, the view will use
	// BigQuery's standard SQL:
	// https://cloud.google.com/bigquery/sql-reference/ Queries and views
	// that reference this view must use the same flag value.
	UseLegacySql bool `json:"useLegacySql,omitempty"`

	// UserDefinedFunctionResources: Describes user-defined function
	// resources used in the query.
	UserDefinedFunctionResources []*UserDefinedFunctionResource `json:"userDefinedFunctionResources,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Query") 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. "Query") 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 *ViewDefinition) MarshalJSON() ([]byte, error) {
	type NoMethod ViewDefinition
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "bigquery.datasets.delete":

type DatasetsDeleteCall struct {
	s          *Service
	projectId  string
	datasetId  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the dataset specified by the datasetId value. Before
// you can delete a dataset, you must delete all its tables, either
// manually or by specifying deleteContents. Immediately after deletion,
// you can create another dataset with the same name.
func (r *DatasetsService) Delete(projectId string, datasetId string) *DatasetsDeleteCall {
	c := &DatasetsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	return c
}

// DeleteContents sets the optional parameter "deleteContents": If True,
// delete all the tables in the dataset. If False and the dataset
// contains tables, the request will fail. Default is False
func (c *DatasetsDeleteCall) DeleteContents(deleteContents bool) *DatasetsDeleteCall {
	c.urlParams_.Set("deleteContents", fmt.Sprint(deleteContents))
	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 *DatasetsDeleteCall) Fields(s ...googleapi.Field) *DatasetsDeleteCall {
	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 *DatasetsDeleteCall) Context(ctx context.Context) *DatasetsDeleteCall {
	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 *DatasetsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DatasetsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/datasets/{datasetId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.datasets.delete" call.
func (c *DatasetsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes the dataset specified by the datasetId value. Before you can delete a dataset, you must delete all its tables, either manually or by specifying deleteContents. Immediately after deletion, you can create another dataset with the same name.",
	//   "httpMethod": "DELETE",
	//   "id": "bigquery.datasets.delete",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of dataset being deleted",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "deleteContents": {
	//       "description": "If True, delete all the tables in the dataset. If False and the dataset contains tables, the request will fail. Default is False",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the dataset being deleted",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.datasets.get":

type DatasetsGetCall struct {
	s            *Service
	projectId    string
	datasetId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns the dataset specified by datasetID.
func (r *DatasetsService) Get(projectId string, datasetId string) *DatasetsGetCall {
	c := &DatasetsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	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 *DatasetsGetCall) Fields(s ...googleapi.Field) *DatasetsGetCall {
	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 *DatasetsGetCall) IfNoneMatch(entityTag string) *DatasetsGetCall {
	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 *DatasetsGetCall) Context(ctx context.Context) *DatasetsGetCall {
	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 *DatasetsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DatasetsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/datasets/{datasetId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.datasets.get" call.
// Exactly one of *Dataset or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Dataset.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 *DatasetsGetCall) Do(opts ...googleapi.CallOption) (*Dataset, 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 := &Dataset{
		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 dataset specified by datasetID.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.datasets.get",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the requested dataset",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the requested dataset",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}",
	//   "response": {
	//     "$ref": "Dataset"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "bigquery.datasets.insert":

type DatasetsInsertCall struct {
	s          *Service
	projectId  string
	dataset    *Dataset
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a new empty dataset.
func (r *DatasetsService) Insert(projectId string, dataset *Dataset) *DatasetsInsertCall {
	c := &DatasetsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.dataset = dataset
	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 *DatasetsInsertCall) Fields(s ...googleapi.Field) *DatasetsInsertCall {
	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 *DatasetsInsertCall) Context(ctx context.Context) *DatasetsInsertCall {
	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 *DatasetsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DatasetsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.dataset)
	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, "projects/{projectId}/datasets")
	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{
		"projectId": c.projectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.datasets.insert" call.
// Exactly one of *Dataset or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Dataset.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 *DatasetsInsertCall) Do(opts ...googleapi.CallOption) (*Dataset, 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 := &Dataset{
		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 new empty dataset.",
	//   "httpMethod": "POST",
	//   "id": "bigquery.datasets.insert",
	//   "parameterOrder": [
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "projectId": {
	//       "description": "Project ID of the new dataset",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets",
	//   "request": {
	//     "$ref": "Dataset"
	//   },
	//   "response": {
	//     "$ref": "Dataset"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.datasets.list":

type DatasetsListCall struct {
	s            *Service
	projectId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all datasets in the specified project to which you have
// been granted the READER dataset role.
func (r *DatasetsService) List(projectId string) *DatasetsListCall {
	c := &DatasetsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	return c
}

// All sets the optional parameter "all": Whether to list all datasets,
// including hidden ones
func (c *DatasetsListCall) All(all bool) *DatasetsListCall {
	c.urlParams_.Set("all", fmt.Sprint(all))
	return c
}

// Filter sets the optional parameter "filter": An expression for
// filtering the results of the request by label. The syntax is
// "labels.<name>[:<value>]". Multiple filters can be ANDed together by
// connecting with a space. Example: "labels.department:receiving
// labels.active". See Filtering datasets using labels for details.
func (c *DatasetsListCall) Filter(filter string) *DatasetsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results to return
func (c *DatasetsListCall) MaxResults(maxResults int64) *DatasetsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous call, to request the next page of results
func (c *DatasetsListCall) PageToken(pageToken string) *DatasetsListCall {
	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 *DatasetsListCall) Fields(s ...googleapi.Field) *DatasetsListCall {
	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 *DatasetsListCall) IfNoneMatch(entityTag string) *DatasetsListCall {
	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 *DatasetsListCall) Context(ctx context.Context) *DatasetsListCall {
	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 *DatasetsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DatasetsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/datasets")
	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{
		"projectId": c.projectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.datasets.list" call.
// Exactly one of *DatasetList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DatasetList.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 *DatasetsListCall) Do(opts ...googleapi.CallOption) (*DatasetList, 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 := &DatasetList{
		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 all datasets in the specified project to which you have been granted the READER dataset role.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.datasets.list",
	//   "parameterOrder": [
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "all": {
	//       "description": "Whether to list all datasets, including hidden ones",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "filter": {
	//       "description": "An expression for filtering the results of the request by label. The syntax is \"labels.\u003cname\u003e[:\u003cvalue\u003e]\". Multiple filters can be ANDed together by connecting with a space. Example: \"labels.department:receiving labels.active\". See Filtering datasets using labels for details.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "The maximum number of results to return",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous call, to request the next page of results",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the datasets to be listed",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets",
	//   "response": {
	//     "$ref": "DatasetList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *DatasetsListCall) Pages(ctx context.Context, f func(*DatasetList) 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 "bigquery.datasets.patch":

type DatasetsPatchCall struct {
	s          *Service
	projectId  string
	datasetId  string
	dataset    *Dataset
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates information in an existing dataset. The update method
// replaces the entire dataset resource, whereas the patch method only
// replaces fields that are provided in the submitted dataset resource.
// This method supports patch semantics.
func (r *DatasetsService) Patch(projectId string, datasetId string, dataset *Dataset) *DatasetsPatchCall {
	c := &DatasetsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.dataset = dataset
	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 *DatasetsPatchCall) Fields(s ...googleapi.Field) *DatasetsPatchCall {
	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 *DatasetsPatchCall) Context(ctx context.Context) *DatasetsPatchCall {
	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 *DatasetsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DatasetsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.dataset)
	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, "projects/{projectId}/datasets/{datasetId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.datasets.patch" call.
// Exactly one of *Dataset or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Dataset.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 *DatasetsPatchCall) Do(opts ...googleapi.CallOption) (*Dataset, 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 := &Dataset{
		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 information in an existing dataset. The update method replaces the entire dataset resource, whereas the patch method only replaces fields that are provided in the submitted dataset resource. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "bigquery.datasets.patch",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the dataset being updated",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the dataset being updated",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}",
	//   "request": {
	//     "$ref": "Dataset"
	//   },
	//   "response": {
	//     "$ref": "Dataset"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.datasets.update":

type DatasetsUpdateCall struct {
	s          *Service
	projectId  string
	datasetId  string
	dataset    *Dataset
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates information in an existing dataset. The update method
// replaces the entire dataset resource, whereas the patch method only
// replaces fields that are provided in the submitted dataset resource.
func (r *DatasetsService) Update(projectId string, datasetId string, dataset *Dataset) *DatasetsUpdateCall {
	c := &DatasetsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.dataset = dataset
	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 *DatasetsUpdateCall) Fields(s ...googleapi.Field) *DatasetsUpdateCall {
	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 *DatasetsUpdateCall) Context(ctx context.Context) *DatasetsUpdateCall {
	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 *DatasetsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DatasetsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.dataset)
	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, "projects/{projectId}/datasets/{datasetId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.datasets.update" call.
// Exactly one of *Dataset or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Dataset.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 *DatasetsUpdateCall) Do(opts ...googleapi.CallOption) (*Dataset, 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 := &Dataset{
		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 information in an existing dataset. The update method replaces the entire dataset resource, whereas the patch method only replaces fields that are provided in the submitted dataset resource.",
	//   "httpMethod": "PUT",
	//   "id": "bigquery.datasets.update",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the dataset being updated",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the dataset being updated",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}",
	//   "request": {
	//     "$ref": "Dataset"
	//   },
	//   "response": {
	//     "$ref": "Dataset"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.jobs.cancel":

type JobsCancelCall struct {
	s          *Service
	projectId  string
	jobId      string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Cancel: Requests that a job be cancelled. This call will return
// immediately, and the client will need to poll for the job status to
// see if the cancel completed successfully. Cancelled jobs may still
// incur costs.
func (r *JobsService) Cancel(projectId string, jobId string) *JobsCancelCall {
	c := &JobsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.jobId = jobId
	return c
}

// Location sets the optional parameter "location": The geographic
// location of the job. Required except for US and EU. See details at
// https://cloud.google.com/bigquery/docs/locations#specifying_your_location.
func (c *JobsCancelCall) Location(location string) *JobsCancelCall {
	c.urlParams_.Set("location", location)
	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 *JobsCancelCall) Fields(s ...googleapi.Field) *JobsCancelCall {
	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 *JobsCancelCall) Context(ctx context.Context) *JobsCancelCall {
	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 *JobsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *JobsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/jobs/{jobId}/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{
		"projectId": c.projectId,
		"jobId":     c.jobId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.jobs.cancel" call.
// Exactly one of *JobCancelResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *JobCancelResponse.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 *JobsCancelCall) Do(opts ...googleapi.CallOption) (*JobCancelResponse, 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 := &JobCancelResponse{
		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": "Requests that a job be cancelled. This call will return immediately, and the client will need to poll for the job status to see if the cancel completed successfully. Cancelled jobs may still incur costs.",
	//   "httpMethod": "POST",
	//   "id": "bigquery.jobs.cancel",
	//   "parameterOrder": [
	//     "projectId",
	//     "jobId"
	//   ],
	//   "parameters": {
	//     "jobId": {
	//       "description": "[Required] Job ID of the job to cancel",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "location": {
	//       "description": "The geographic location of the job. Required except for US and EU. See details at https://cloud.google.com/bigquery/docs/locations#specifying_your_location.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "[Required] Project ID of the job to cancel",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/jobs/{jobId}/cancel",
	//   "response": {
	//     "$ref": "JobCancelResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.jobs.get":

type JobsGetCall struct {
	s            *Service
	projectId    string
	jobId        string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Returns information about a specific job. Job information is
// available for a six month period after creation. Requires that you're
// the person who ran the job, or have the Is Owner project role.
func (r *JobsService) Get(projectId string, jobId string) *JobsGetCall {
	c := &JobsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.jobId = jobId
	return c
}

// Location sets the optional parameter "location": The geographic
// location of the job. Required except for US and EU. See details at
// https://cloud.google.com/bigquery/docs/locations#specifying_your_location.
func (c *JobsGetCall) Location(location string) *JobsGetCall {
	c.urlParams_.Set("location", location)
	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 *JobsGetCall) Fields(s ...googleapi.Field) *JobsGetCall {
	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 *JobsGetCall) IfNoneMatch(entityTag string) *JobsGetCall {
	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 *JobsGetCall) Context(ctx context.Context) *JobsGetCall {
	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 *JobsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *JobsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/jobs/{jobId}")
	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{
		"projectId": c.projectId,
		"jobId":     c.jobId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.jobs.get" call.
// Exactly one of *Job or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either
// *Job.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 *JobsGetCall) Do(opts ...googleapi.CallOption) (*Job, 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 := &Job{
		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 information about a specific job. Job information is available for a six month period after creation. Requires that you're the person who ran the job, or have the Is Owner project role.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.jobs.get",
	//   "parameterOrder": [
	//     "projectId",
	//     "jobId"
	//   ],
	//   "parameters": {
	//     "jobId": {
	//       "description": "[Required] Job ID of the requested job",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "location": {
	//       "description": "The geographic location of the job. Required except for US and EU. See details at https://cloud.google.com/bigquery/docs/locations#specifying_your_location.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "[Required] Project ID of the requested job",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/jobs/{jobId}",
	//   "response": {
	//     "$ref": "Job"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "bigquery.jobs.getQueryResults":

type JobsGetQueryResultsCall struct {
	s            *Service
	projectId    string
	jobId        string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetQueryResults: Retrieves the results of a query job.
func (r *JobsService) GetQueryResults(projectId string, jobId string) *JobsGetQueryResultsCall {
	c := &JobsGetQueryResultsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.jobId = jobId
	return c
}

// Location sets the optional parameter "location": The geographic
// location where the job should run. Required except for US and EU. See
// details at
// https://cloud.google.com/bigquery/docs/locations#specifying_your_location.
func (c *JobsGetQueryResultsCall) Location(location string) *JobsGetQueryResultsCall {
	c.urlParams_.Set("location", location)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to read
func (c *JobsGetQueryResultsCall) MaxResults(maxResults int64) *JobsGetQueryResultsCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous call, to request the next page of results
func (c *JobsGetQueryResultsCall) PageToken(pageToken string) *JobsGetQueryResultsCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// StartIndex sets the optional parameter "startIndex": Zero-based index
// of the starting row
func (c *JobsGetQueryResultsCall) StartIndex(startIndex uint64) *JobsGetQueryResultsCall {
	c.urlParams_.Set("startIndex", fmt.Sprint(startIndex))
	return c
}

// TimeoutMs sets the optional parameter "timeoutMs": How long to wait
// for the query to complete, in milliseconds, before returning. Default
// is 10 seconds. If the timeout passes before the job completes, the
// 'jobComplete' field in the response will be false
func (c *JobsGetQueryResultsCall) TimeoutMs(timeoutMs int64) *JobsGetQueryResultsCall {
	c.urlParams_.Set("timeoutMs", fmt.Sprint(timeoutMs))
	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 *JobsGetQueryResultsCall) Fields(s ...googleapi.Field) *JobsGetQueryResultsCall {
	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 *JobsGetQueryResultsCall) IfNoneMatch(entityTag string) *JobsGetQueryResultsCall {
	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 *JobsGetQueryResultsCall) Context(ctx context.Context) *JobsGetQueryResultsCall {
	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 *JobsGetQueryResultsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *JobsGetQueryResultsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/queries/{jobId}")
	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{
		"projectId": c.projectId,
		"jobId":     c.jobId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.jobs.getQueryResults" call.
// Exactly one of *GetQueryResultsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GetQueryResultsResponse.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 *JobsGetQueryResultsCall) Do(opts ...googleapi.CallOption) (*GetQueryResultsResponse, 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 := &GetQueryResultsResponse{
		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 results of a query job.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.jobs.getQueryResults",
	//   "parameterOrder": [
	//     "projectId",
	//     "jobId"
	//   ],
	//   "parameters": {
	//     "jobId": {
	//       "description": "[Required] Job ID of the query job",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "location": {
	//       "description": "The geographic location where the job should run. Required except for US and EU. See details at https://cloud.google.com/bigquery/docs/locations#specifying_your_location.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to read",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous call, to request the next page of results",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "[Required] Project ID of the query job",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "startIndex": {
	//       "description": "Zero-based index of the starting row",
	//       "format": "uint64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timeoutMs": {
	//       "description": "How long to wait for the query to complete, in milliseconds, before returning. Default is 10 seconds. If the timeout passes before the job completes, the 'jobComplete' field in the response will be false",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "projects/{projectId}/queries/{jobId}",
	//   "response": {
	//     "$ref": "GetQueryResultsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *JobsGetQueryResultsCall) Pages(ctx context.Context, f func(*GetQueryResultsResponse) 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.PageToken == "" {
			return nil
		}
		c.PageToken(x.PageToken)
	}
}

// method id "bigquery.jobs.insert":

type JobsInsertCall struct {
	s          *Service
	projectId  string
	job        *Job
	urlParams_ gensupport.URLParams
	mediaInfo_ *gensupport.MediaInfo
	ctx_       context.Context
	header_    http.Header
}

// Insert: Starts a new asynchronous job. Requires the Can View project
// role.
func (r *JobsService) Insert(projectId string, job *Job) *JobsInsertCall {
	c := &JobsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.job = job
	return c
}

// Media specifies the media to upload in one or more chunks. The chunk
// size may be controlled by supplying a MediaOption generated by
// googleapi.ChunkSize. The chunk size defaults to
// googleapi.DefaultUploadChunkSize.The Content-Type header used in the
// upload request will be determined by sniffing the contents of r,
// unless a MediaOption generated by googleapi.ContentType is
// supplied.
// At most one of Media and ResumableMedia may be set.
func (c *JobsInsertCall) Media(r io.Reader, options ...googleapi.MediaOption) *JobsInsertCall {
	c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options)
	return c
}

// ResumableMedia specifies the media to upload in chunks and can be
// canceled with ctx.
//
// Deprecated: use Media instead.
//
// At most one of Media and ResumableMedia may be set. mediaType
// identifies the MIME media type of the upload, such as "image/png". If
// mediaType is "", it will be auto-detected. The provided ctx will
// supersede any context previously provided to the Context method.
func (c *JobsInsertCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *JobsInsertCall {
	c.ctx_ = ctx
	c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType)
	return c
}

// ProgressUpdater provides a callback function that will be called
// after every chunk. It should be a low-latency function in order to
// not slow down the upload operation. This should only be called when
// using ResumableMedia (as opposed to Media).
func (c *JobsInsertCall) ProgressUpdater(pu googleapi.ProgressUpdater) *JobsInsertCall {
	c.mediaInfo_.SetProgressUpdater(pu)
	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 *JobsInsertCall) Fields(s ...googleapi.Field) *JobsInsertCall {
	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.
// This context will supersede any context previously provided to the
// ResumableMedia method.
func (c *JobsInsertCall) Context(ctx context.Context) *JobsInsertCall {
	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 *JobsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *JobsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.job)
	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, "projects/{projectId}/jobs")
	if c.mediaInfo_ != nil {
		urls = googleapi.ResolveRelative(c.s.BasePath, "/upload/bigquery/v2/projects/{projectId}/jobs")
		c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())
	}
	if body == nil {
		body = new(bytes.Buffer)
		reqHeaders.Set("Content-Type", "application/json")
	}
	body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)
	defer cleanup()
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	req.GetBody = getBody
	googleapi.Expand(req.URL, map[string]string{
		"projectId": c.projectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.jobs.insert" call.
// Exactly one of *Job or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either
// *Job.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 *JobsInsertCall) Do(opts ...googleapi.CallOption) (*Job, 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
	}
	rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))
	if rx != nil {
		rx.Client = c.s.client
		rx.UserAgent = c.s.userAgent()
		ctx := c.ctx_
		if ctx == nil {
			ctx = context.TODO()
		}
		res, err = rx.Upload(ctx)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		if err := googleapi.CheckResponse(res); err != nil {
			return nil, err
		}
	}
	ret := &Job{
		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 a new asynchronous job. Requires the Can View project role.",
	//   "httpMethod": "POST",
	//   "id": "bigquery.jobs.insert",
	//   "mediaUpload": {
	//     "accept": [
	//       "*/*"
	//     ],
	//     "protocols": {
	//       "resumable": {
	//         "multipart": true,
	//         "path": "/resumable/upload/bigquery/v2/projects/{projectId}/jobs"
	//       },
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/bigquery/v2/projects/{projectId}/jobs"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "projectId": {
	//       "description": "Project ID of the project that will be billed for the job",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/jobs",
	//   "request": {
	//     "$ref": "Job"
	//   },
	//   "response": {
	//     "$ref": "Job"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/devstorage.full_control",
	//     "https://www.googleapis.com/auth/devstorage.read_only",
	//     "https://www.googleapis.com/auth/devstorage.read_write"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "bigquery.jobs.list":

type JobsListCall struct {
	s            *Service
	projectId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all jobs that you started in the specified project. Job
// information is available for a six month period after creation. The
// job list is sorted in reverse chronological order, by job creation
// time. Requires the Can View project role, or the Is Owner project
// role if you set the allUsers property.
func (r *JobsService) List(projectId string) *JobsListCall {
	c := &JobsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	return c
}

// AllUsers sets the optional parameter "allUsers": Whether to display
// jobs owned by all users in the project. Default false
func (c *JobsListCall) AllUsers(allUsers bool) *JobsListCall {
	c.urlParams_.Set("allUsers", fmt.Sprint(allUsers))
	return c
}

// MaxCreationTime sets the optional parameter "maxCreationTime": Max
// value for job creation time, in milliseconds since the POSIX epoch.
// If set, only jobs created before or at this timestamp are returned
func (c *JobsListCall) MaxCreationTime(maxCreationTime uint64) *JobsListCall {
	c.urlParams_.Set("maxCreationTime", fmt.Sprint(maxCreationTime))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return
func (c *JobsListCall) MaxResults(maxResults int64) *JobsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// MinCreationTime sets the optional parameter "minCreationTime": Min
// value for job creation time, in milliseconds since the POSIX epoch.
// If set, only jobs created after or at this timestamp are returned
func (c *JobsListCall) MinCreationTime(minCreationTime uint64) *JobsListCall {
	c.urlParams_.Set("minCreationTime", fmt.Sprint(minCreationTime))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous call, to request the next page of results
func (c *JobsListCall) PageToken(pageToken string) *JobsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ParentJobId sets the optional parameter "parentJobId": If set,
// retrieves only jobs whose parent is this job. Otherwise, retrieves
// only jobs which have no parent
func (c *JobsListCall) ParentJobId(parentJobId string) *JobsListCall {
	c.urlParams_.Set("parentJobId", parentJobId)
	return c
}

// Projection sets the optional parameter "projection": Restrict
// information returned to a set of selected fields
//
// Possible values:
//   "full" - Includes all job data
//   "minimal" - Does not include the job configuration
func (c *JobsListCall) Projection(projection string) *JobsListCall {
	c.urlParams_.Set("projection", projection)
	return c
}

// StateFilter sets the optional parameter "stateFilter": Filter for job
// state
//
// Possible values:
//   "done" - Finished jobs
//   "pending" - Pending jobs
//   "running" - Running jobs
func (c *JobsListCall) StateFilter(stateFilter ...string) *JobsListCall {
	c.urlParams_.SetMulti("stateFilter", append([]string{}, stateFilter...))
	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 *JobsListCall) Fields(s ...googleapi.Field) *JobsListCall {
	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 *JobsListCall) IfNoneMatch(entityTag string) *JobsListCall {
	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 *JobsListCall) Context(ctx context.Context) *JobsListCall {
	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 *JobsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *JobsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/jobs")
	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{
		"projectId": c.projectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.jobs.list" call.
// Exactly one of *JobList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *JobList.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 *JobsListCall) Do(opts ...googleapi.CallOption) (*JobList, 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 := &JobList{
		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 all jobs that you started in the specified project. Job information is available for a six month period after creation. The job list is sorted in reverse chronological order, by job creation time. Requires the Can View project role, or the Is Owner project role if you set the allUsers property.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.jobs.list",
	//   "parameterOrder": [
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "allUsers": {
	//       "description": "Whether to display jobs owned by all users in the project. Default false",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "maxCreationTime": {
	//       "description": "Max value for job creation time, in milliseconds since the POSIX epoch. If set, only jobs created before or at this timestamp are returned",
	//       "format": "uint64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "minCreationTime": {
	//       "description": "Min value for job creation time, in milliseconds since the POSIX epoch. If set, only jobs created after or at this timestamp are returned",
	//       "format": "uint64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous call, to request the next page of results",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parentJobId": {
	//       "description": "If set, retrieves only jobs whose parent is this job. Otherwise, retrieves only jobs which have no parent",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the jobs to list",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projection": {
	//       "description": "Restrict information returned to a set of selected fields",
	//       "enum": [
	//         "full",
	//         "minimal"
	//       ],
	//       "enumDescriptions": [
	//         "Includes all job data",
	//         "Does not include the job configuration"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "stateFilter": {
	//       "description": "Filter for job state",
	//       "enum": [
	//         "done",
	//         "pending",
	//         "running"
	//       ],
	//       "enumDescriptions": [
	//         "Finished jobs",
	//         "Pending jobs",
	//         "Running jobs"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/jobs",
	//   "response": {
	//     "$ref": "JobList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *JobsListCall) Pages(ctx context.Context, f func(*JobList) 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 "bigquery.jobs.query":

type JobsQueryCall struct {
	s            *Service
	projectId    string
	queryrequest *QueryRequest
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Query: Runs a BigQuery SQL query synchronously and returns query
// results if the query completes within a specified timeout.
func (r *JobsService) Query(projectId string, queryrequest *QueryRequest) *JobsQueryCall {
	c := &JobsQueryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.queryrequest = queryrequest
	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 *JobsQueryCall) Fields(s ...googleapi.Field) *JobsQueryCall {
	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 *JobsQueryCall) Context(ctx context.Context) *JobsQueryCall {
	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 *JobsQueryCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *JobsQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.queryrequest)
	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, "projects/{projectId}/queries")
	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{
		"projectId": c.projectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.jobs.query" call.
// Exactly one of *QueryResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *QueryResponse.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 *JobsQueryCall) Do(opts ...googleapi.CallOption) (*QueryResponse, 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 := &QueryResponse{
		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": "Runs a BigQuery SQL query synchronously and returns query results if the query completes within a specified timeout.",
	//   "httpMethod": "POST",
	//   "id": "bigquery.jobs.query",
	//   "parameterOrder": [
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "projectId": {
	//       "description": "Project ID of the project billed for the query",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/queries",
	//   "request": {
	//     "$ref": "QueryRequest"
	//   },
	//   "response": {
	//     "$ref": "QueryResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "bigquery.models.delete":

type ModelsDeleteCall struct {
	s          *Service
	projectId  string
	datasetId  string
	modelId    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the model specified by modelId from the dataset.
func (r *ModelsService) Delete(projectId string, datasetId string, modelId string) *ModelsDeleteCall {
	c := &ModelsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.modelId = modelId
	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 *ModelsDeleteCall) Fields(s ...googleapi.Field) *ModelsDeleteCall {
	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 *ModelsDeleteCall) Context(ctx context.Context) *ModelsDeleteCall {
	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 *ModelsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ModelsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{+projectId}/datasets/{+datasetId}/models/{+modelId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"modelId":   c.modelId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.models.delete" call.
func (c *ModelsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes the model specified by modelId from the dataset.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/models/{modelsId}",
	//   "httpMethod": "DELETE",
	//   "id": "bigquery.models.delete",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "modelId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the model to delete.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "modelId": {
	//       "description": "Required. Model ID of the model to delete.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the model to delete.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/models/{+modelId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.models.get":

type ModelsGetCall struct {
	s            *Service
	projectId    string
	datasetId    string
	modelId      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the specified model resource by model ID.
func (r *ModelsService) Get(projectId string, datasetId string, modelId string) *ModelsGetCall {
	c := &ModelsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.modelId = modelId
	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 *ModelsGetCall) Fields(s ...googleapi.Field) *ModelsGetCall {
	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 *ModelsGetCall) IfNoneMatch(entityTag string) *ModelsGetCall {
	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 *ModelsGetCall) Context(ctx context.Context) *ModelsGetCall {
	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 *ModelsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ModelsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{+projectId}/datasets/{+datasetId}/models/{+modelId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"modelId":   c.modelId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.models.get" call.
// Exactly one of *Model or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Model.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 *ModelsGetCall) Do(opts ...googleapi.CallOption) (*Model, 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 := &Model{
		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 specified model resource by model ID.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/models/{modelsId}",
	//   "httpMethod": "GET",
	//   "id": "bigquery.models.get",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "modelId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the requested model.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "modelId": {
	//       "description": "Required. Model ID of the requested model.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the requested model.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/models/{+modelId}",
	//   "response": {
	//     "$ref": "Model"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "bigquery.models.list":

type ModelsListCall struct {
	s            *Service
	projectId    string
	datasetId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all models in the specified dataset. Requires the READER
// dataset
// role.
func (r *ModelsService) List(projectId string, datasetId string) *ModelsListCall {
	c := &ModelsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results to return in a single response page.
// Leverage the page tokens to iterate through the entire collection.
func (c *ModelsListCall) MaxResults(maxResults int64) *ModelsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous call to request the next page of
// results
func (c *ModelsListCall) PageToken(pageToken string) *ModelsListCall {
	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 *ModelsListCall) Fields(s ...googleapi.Field) *ModelsListCall {
	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 *ModelsListCall) IfNoneMatch(entityTag string) *ModelsListCall {
	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 *ModelsListCall) Context(ctx context.Context) *ModelsListCall {
	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 *ModelsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ModelsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{+projectId}/datasets/{+datasetId}/models")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.models.list" call.
// Exactly one of *ListModelsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListModelsResponse.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 *ModelsListCall) Do(opts ...googleapi.CallOption) (*ListModelsResponse, 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 := &ListModelsResponse{
		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 all models in the specified dataset. Requires the READER dataset\nrole.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/models",
	//   "httpMethod": "GET",
	//   "id": "bigquery.models.list",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the models to list.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "The maximum number of results to return in a single response page.\nLeverage the page tokens to iterate through the entire collection.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous call to request the next page of\nresults",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the models to list.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/models",
	//   "response": {
	//     "$ref": "ListModelsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *ModelsListCall) Pages(ctx context.Context, f func(*ListModelsResponse) 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 "bigquery.models.patch":

type ModelsPatchCall struct {
	s          *Service
	projectId  string
	datasetId  string
	modelId    string
	model      *Model
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Patch specific fields in the specified model.
func (r *ModelsService) Patch(projectId string, datasetId string, modelId string, model *Model) *ModelsPatchCall {
	c := &ModelsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.modelId = modelId
	c.model = model
	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 *ModelsPatchCall) Fields(s ...googleapi.Field) *ModelsPatchCall {
	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 *ModelsPatchCall) Context(ctx context.Context) *ModelsPatchCall {
	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 *ModelsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ModelsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.model)
	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, "projects/{+projectId}/datasets/{+datasetId}/models/{+modelId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"modelId":   c.modelId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.models.patch" call.
// Exactly one of *Model or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Model.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 *ModelsPatchCall) Do(opts ...googleapi.CallOption) (*Model, 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 := &Model{
		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": "Patch specific fields in the specified model.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/models/{modelsId}",
	//   "httpMethod": "PATCH",
	//   "id": "bigquery.models.patch",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "modelId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the model to patch.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "modelId": {
	//       "description": "Required. Model ID of the model to patch.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the model to patch.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/models/{+modelId}",
	//   "request": {
	//     "$ref": "Model"
	//   },
	//   "response": {
	//     "$ref": "Model"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.projects.getServiceAccount":

type ProjectsGetServiceAccountCall struct {
	s            *Service
	projectId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetServiceAccount: Returns the email address of the service account
// for your project used for interactions with Google Cloud KMS.
func (r *ProjectsService) GetServiceAccount(projectId string) *ProjectsGetServiceAccountCall {
	c := &ProjectsGetServiceAccountCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	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 *ProjectsGetServiceAccountCall) Fields(s ...googleapi.Field) *ProjectsGetServiceAccountCall {
	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 *ProjectsGetServiceAccountCall) IfNoneMatch(entityTag string) *ProjectsGetServiceAccountCall {
	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 *ProjectsGetServiceAccountCall) Context(ctx context.Context) *ProjectsGetServiceAccountCall {
	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 *ProjectsGetServiceAccountCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetServiceAccountCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/serviceAccount")
	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{
		"projectId": c.projectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.projects.getServiceAccount" call.
// Exactly one of *GetServiceAccountResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GetServiceAccountResponse.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 *ProjectsGetServiceAccountCall) Do(opts ...googleapi.CallOption) (*GetServiceAccountResponse, 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 := &GetServiceAccountResponse{
		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 email address of the service account for your project used for interactions with Google Cloud KMS.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.projects.getServiceAccount",
	//   "parameterOrder": [
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "projectId": {
	//       "description": "Project ID for which the service account is requested.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/serviceAccount",
	//   "response": {
	//     "$ref": "GetServiceAccountResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "bigquery.projects.list":

type ProjectsListCall struct {
	s            *Service
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all projects to which you have been granted any project
// role.
func (r *ProjectsService) List() *ProjectsListCall {
	c := &ProjectsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return
func (c *ProjectsListCall) MaxResults(maxResults int64) *ProjectsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous call, to request the next page of results
func (c *ProjectsListCall) PageToken(pageToken string) *ProjectsListCall {
	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 *ProjectsListCall) Fields(s ...googleapi.Field) *ProjectsListCall {
	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 *ProjectsListCall) IfNoneMatch(entityTag string) *ProjectsListCall {
	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 *ProjectsListCall) Context(ctx context.Context) *ProjectsListCall {
	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 *ProjectsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects")
	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 "bigquery.projects.list" call.
// Exactly one of *ProjectList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ProjectList.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 *ProjectsListCall) Do(opts ...googleapi.CallOption) (*ProjectList, 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 := &ProjectList{
		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 all projects to which you have been granted any project role.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.projects.list",
	//   "parameters": {
	//     "maxResults": {
	//       "description": "Maximum number of results to return",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous call, to request the next page of results",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects",
	//   "response": {
	//     "$ref": "ProjectList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *ProjectsListCall) Pages(ctx context.Context, f func(*ProjectList) 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 "bigquery.routines.delete":

type RoutinesDeleteCall struct {
	s          *Service
	projectId  string
	datasetId  string
	routineId  string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the routine specified by routineId from the dataset.
func (r *RoutinesService) Delete(projectId string, datasetId string, routineId string) *RoutinesDeleteCall {
	c := &RoutinesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.routineId = routineId
	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 *RoutinesDeleteCall) Fields(s ...googleapi.Field) *RoutinesDeleteCall {
	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 *RoutinesDeleteCall) Context(ctx context.Context) *RoutinesDeleteCall {
	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 *RoutinesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutinesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{+projectId}/datasets/{+datasetId}/routines/{+routineId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"routineId": c.routineId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.routines.delete" call.
func (c *RoutinesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes the routine specified by routineId from the dataset.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/routines/{routinesId}",
	//   "httpMethod": "DELETE",
	//   "id": "bigquery.routines.delete",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "routineId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the routine to delete",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the routine to delete",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "routineId": {
	//       "description": "Required. Routine ID of the routine to delete",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/routines/{+routineId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.routines.get":

type RoutinesGetCall struct {
	s            *Service
	projectId    string
	datasetId    string
	routineId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the specified routine resource by routine ID.
func (r *RoutinesService) Get(projectId string, datasetId string, routineId string) *RoutinesGetCall {
	c := &RoutinesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.routineId = routineId
	return c
}

// ReadMask sets the optional parameter "readMask": If set, only the
// Routine fields in the field mask are returned in the
// response. If unset, all Routine fields are returned.
func (c *RoutinesGetCall) ReadMask(readMask string) *RoutinesGetCall {
	c.urlParams_.Set("readMask", readMask)
	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 *RoutinesGetCall) Fields(s ...googleapi.Field) *RoutinesGetCall {
	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 *RoutinesGetCall) IfNoneMatch(entityTag string) *RoutinesGetCall {
	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 *RoutinesGetCall) Context(ctx context.Context) *RoutinesGetCall {
	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 *RoutinesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutinesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{+projectId}/datasets/{+datasetId}/routines/{+routineId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"routineId": c.routineId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.routines.get" call.
// Exactly one of *Routine or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Routine.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 *RoutinesGetCall) Do(opts ...googleapi.CallOption) (*Routine, 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 := &Routine{
		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 specified routine resource by routine ID.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/routines/{routinesId}",
	//   "httpMethod": "GET",
	//   "id": "bigquery.routines.get",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "routineId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the requested routine",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the requested routine",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "If set, only the Routine fields in the field mask are returned in the\nresponse. If unset, all Routine fields are returned.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "routineId": {
	//       "description": "Required. Routine ID of the requested routine",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/routines/{+routineId}",
	//   "response": {
	//     "$ref": "Routine"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "bigquery.routines.insert":

type RoutinesInsertCall struct {
	s          *Service
	projectId  string
	datasetId  string
	routine    *Routine
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a new routine in the dataset.
func (r *RoutinesService) Insert(projectId string, datasetId string, routine *Routine) *RoutinesInsertCall {
	c := &RoutinesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.routine = routine
	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 *RoutinesInsertCall) Fields(s ...googleapi.Field) *RoutinesInsertCall {
	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 *RoutinesInsertCall) Context(ctx context.Context) *RoutinesInsertCall {
	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 *RoutinesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutinesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.routine)
	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, "projects/{+projectId}/datasets/{+datasetId}/routines")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.routines.insert" call.
// Exactly one of *Routine or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Routine.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 *RoutinesInsertCall) Do(opts ...googleapi.CallOption) (*Routine, 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 := &Routine{
		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 new routine in the dataset.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/routines",
	//   "httpMethod": "POST",
	//   "id": "bigquery.routines.insert",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the new routine",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the new routine",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/routines",
	//   "request": {
	//     "$ref": "Routine"
	//   },
	//   "response": {
	//     "$ref": "Routine"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.routines.list":

type RoutinesListCall struct {
	s            *Service
	projectId    string
	datasetId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all routines in the specified dataset. Requires the
// READER dataset
// role.
func (r *RoutinesService) List(projectId string, datasetId string) *RoutinesListCall {
	c := &RoutinesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	return c
}

// Filter sets the optional parameter "filter": If set, then only the
// Routines matching this filter are returned.
// The current supported form is either "routine_type:<RoutineType>"
// or
// "routineType:<RoutineType>", where <RoutineType> is a RoutineType
// enum.
// Example: "routineType:SCALAR_FUNCTION".
func (c *RoutinesListCall) Filter(filter string) *RoutinesListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maximum
// number of results to return in a single response page.
// Leverage the page tokens to iterate through the entire collection.
func (c *RoutinesListCall) MaxResults(maxResults int64) *RoutinesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous call, to request the next page of
// results
func (c *RoutinesListCall) PageToken(pageToken string) *RoutinesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReadMask sets the optional parameter "readMask": If set, then only
// the Routine fields in the field mask, as well as
// project_id, dataset_id and routine_id, are returned in the
// response.
// If unset, then the following Routine fields are returned:
// etag, project_id, dataset_id, routine_id, routine_type,
// creation_time,
// last_modified_time, and language.
func (c *RoutinesListCall) ReadMask(readMask string) *RoutinesListCall {
	c.urlParams_.Set("readMask", readMask)
	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 *RoutinesListCall) Fields(s ...googleapi.Field) *RoutinesListCall {
	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 *RoutinesListCall) IfNoneMatch(entityTag string) *RoutinesListCall {
	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 *RoutinesListCall) Context(ctx context.Context) *RoutinesListCall {
	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 *RoutinesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutinesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{+projectId}/datasets/{+datasetId}/routines")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.routines.list" call.
// Exactly one of *ListRoutinesResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListRoutinesResponse.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 *RoutinesListCall) Do(opts ...googleapi.CallOption) (*ListRoutinesResponse, 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 := &ListRoutinesResponse{
		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 all routines in the specified dataset. Requires the READER dataset\nrole.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/routines",
	//   "httpMethod": "GET",
	//   "id": "bigquery.routines.list",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the routines to list",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "filter": {
	//       "description": "If set, then only the Routines matching this filter are returned.\nThe current supported form is either \"routine_type:\u003cRoutineType\u003e\" or\n\"routineType:\u003cRoutineType\u003e\", where \u003cRoutineType\u003e is a RoutineType enum.\nExample: \"routineType:SCALAR_FUNCTION\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "The maximum number of results to return in a single response page.\nLeverage the page tokens to iterate through the entire collection.",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous call, to request the next page of\nresults",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the routines to list",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "readMask": {
	//       "description": "If set, then only the Routine fields in the field mask, as well as\nproject_id, dataset_id and routine_id, are returned in the response.\nIf unset, then the following Routine fields are returned:\netag, project_id, dataset_id, routine_id, routine_type, creation_time,\nlast_modified_time, and language.",
	//       "format": "google-fieldmask",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/routines",
	//   "response": {
	//     "$ref": "ListRoutinesResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *RoutinesListCall) Pages(ctx context.Context, f func(*ListRoutinesResponse) 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 "bigquery.routines.update":

type RoutinesUpdateCall struct {
	s          *Service
	projectId  string
	datasetId  string
	routineId  string
	routine    *Routine
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates information in an existing routine. The update method
// replaces the
// entire Routine resource.
func (r *RoutinesService) Update(projectId string, datasetId string, routineId string, routine *Routine) *RoutinesUpdateCall {
	c := &RoutinesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.routineId = routineId
	c.routine = routine
	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 *RoutinesUpdateCall) Fields(s ...googleapi.Field) *RoutinesUpdateCall {
	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 *RoutinesUpdateCall) Context(ctx context.Context) *RoutinesUpdateCall {
	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 *RoutinesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RoutinesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.routine)
	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, "projects/{+projectId}/datasets/{+datasetId}/routines/{+routineId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"routineId": c.routineId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.routines.update" call.
// Exactly one of *Routine or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Routine.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 *RoutinesUpdateCall) Do(opts ...googleapi.CallOption) (*Routine, 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 := &Routine{
		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 information in an existing routine. The update method replaces the\nentire Routine resource.",
	//   "flatPath": "projects/{projectsId}/datasets/{datasetsId}/routines/{routinesId}",
	//   "httpMethod": "PUT",
	//   "id": "bigquery.routines.update",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "routineId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Required. Dataset ID of the routine to update",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Required. Project ID of the routine to update",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "routineId": {
	//       "description": "Required. Routine ID of the routine to update",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{+projectId}/datasets/{+datasetId}/routines/{+routineId}",
	//   "request": {
	//     "$ref": "Routine"
	//   },
	//   "response": {
	//     "$ref": "Routine"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.tabledata.insertAll":

type TabledataInsertAllCall struct {
	s                         *Service
	projectId                 string
	datasetId                 string
	tableId                   string
	tabledatainsertallrequest *TableDataInsertAllRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// InsertAll: Streams data into BigQuery one record at a time without
// needing to run a load job. Requires the WRITER dataset role.
func (r *TabledataService) InsertAll(projectId string, datasetId string, tableId string, tabledatainsertallrequest *TableDataInsertAllRequest) *TabledataInsertAllCall {
	c := &TabledataInsertAllCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.tableId = tableId
	c.tabledatainsertallrequest = tabledatainsertallrequest
	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 *TabledataInsertAllCall) Fields(s ...googleapi.Field) *TabledataInsertAllCall {
	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 *TabledataInsertAllCall) Context(ctx context.Context) *TabledataInsertAllCall {
	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 *TabledataInsertAllCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TabledataInsertAllCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.tabledatainsertallrequest)
	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, "projects/{projectId}/datasets/{datasetId}/tables/{tableId}/insertAll")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"tableId":   c.tableId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.tabledata.insertAll" call.
// Exactly one of *TableDataInsertAllResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *TableDataInsertAllResponse.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 *TabledataInsertAllCall) Do(opts ...googleapi.CallOption) (*TableDataInsertAllResponse, 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 := &TableDataInsertAllResponse{
		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": "Streams data into BigQuery one record at a time without needing to run a load job. Requires the WRITER dataset role.",
	//   "httpMethod": "POST",
	//   "id": "bigquery.tabledata.insertAll",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "tableId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the destination table.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the destination table.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "tableId": {
	//       "description": "Table ID of the destination table.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}/insertAll",
	//   "request": {
	//     "$ref": "TableDataInsertAllRequest"
	//   },
	//   "response": {
	//     "$ref": "TableDataInsertAllResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.insertdata",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.tabledata.list":

type TabledataListCall struct {
	s            *Service
	projectId    string
	datasetId    string
	tableId      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves table data from a specified set of rows. Requires the
// READER dataset role.
func (r *TabledataService) List(projectId string, datasetId string, tableId string) *TabledataListCall {
	c := &TabledataListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.tableId = tableId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return
func (c *TabledataListCall) MaxResults(maxResults int64) *TabledataListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous call, identifying the result set
func (c *TabledataListCall) PageToken(pageToken string) *TabledataListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SelectedFields sets the optional parameter "selectedFields": List of
// fields to return (comma-separated). If unspecified, all fields are
// returned
func (c *TabledataListCall) SelectedFields(selectedFields string) *TabledataListCall {
	c.urlParams_.Set("selectedFields", selectedFields)
	return c
}

// StartIndex sets the optional parameter "startIndex": Zero-based index
// of the starting row to read
func (c *TabledataListCall) StartIndex(startIndex uint64) *TabledataListCall {
	c.urlParams_.Set("startIndex", fmt.Sprint(startIndex))
	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 *TabledataListCall) Fields(s ...googleapi.Field) *TabledataListCall {
	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 *TabledataListCall) IfNoneMatch(entityTag string) *TabledataListCall {
	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 *TabledataListCall) Context(ctx context.Context) *TabledataListCall {
	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 *TabledataListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TabledataListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/datasets/{datasetId}/tables/{tableId}/data")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"tableId":   c.tableId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.tabledata.list" call.
// Exactly one of *TableDataList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TableDataList.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 *TabledataListCall) Do(opts ...googleapi.CallOption) (*TableDataList, 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 := &TableDataList{
		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 table data from a specified set of rows. Requires the READER dataset role.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.tabledata.list",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "tableId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the table to read",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous call, identifying the result set",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the table to read",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "selectedFields": {
	//       "description": "List of fields to return (comma-separated). If unspecified, all fields are returned",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "startIndex": {
	//       "description": "Zero-based index of the starting row to read",
	//       "format": "uint64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "tableId": {
	//       "description": "Table ID of the table to read",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}/data",
	//   "response": {
	//     "$ref": "TableDataList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *TabledataListCall) Pages(ctx context.Context, f func(*TableDataList) 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.PageToken == "" {
			return nil
		}
		c.PageToken(x.PageToken)
	}
}

// method id "bigquery.tables.delete":

type TablesDeleteCall struct {
	s          *Service
	projectId  string
	datasetId  string
	tableId    string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes the table specified by tableId from the dataset. If
// the table contains data, all the data will be deleted.
func (r *TablesService) Delete(projectId string, datasetId string, tableId string) *TablesDeleteCall {
	c := &TablesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.tableId = tableId
	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 *TablesDeleteCall) Fields(s ...googleapi.Field) *TablesDeleteCall {
	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 *TablesDeleteCall) Context(ctx context.Context) *TablesDeleteCall {
	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 *TablesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TablesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/datasets/{datasetId}/tables/{tableId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"tableId":   c.tableId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.tables.delete" call.
func (c *TablesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes the table specified by tableId from the dataset. If the table contains data, all the data will be deleted.",
	//   "httpMethod": "DELETE",
	//   "id": "bigquery.tables.delete",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "tableId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the table to delete",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the table to delete",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "tableId": {
	//       "description": "Table ID of the table to delete",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.tables.get":

type TablesGetCall struct {
	s            *Service
	projectId    string
	datasetId    string
	tableId      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the specified table resource by table ID. This method does
// not return the data in the table, it only returns the table resource,
// which describes the structure of this table.
func (r *TablesService) Get(projectId string, datasetId string, tableId string) *TablesGetCall {
	c := &TablesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.tableId = tableId
	return c
}

// SelectedFields sets the optional parameter "selectedFields": List of
// fields to return (comma-separated). If unspecified, all fields are
// returned
func (c *TablesGetCall) SelectedFields(selectedFields string) *TablesGetCall {
	c.urlParams_.Set("selectedFields", selectedFields)
	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 *TablesGetCall) Fields(s ...googleapi.Field) *TablesGetCall {
	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 *TablesGetCall) IfNoneMatch(entityTag string) *TablesGetCall {
	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 *TablesGetCall) Context(ctx context.Context) *TablesGetCall {
	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 *TablesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TablesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/datasets/{datasetId}/tables/{tableId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"tableId":   c.tableId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.tables.get" call.
// Exactly one of *Table or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Table.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 *TablesGetCall) Do(opts ...googleapi.CallOption) (*Table, 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 := &Table{
		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 specified table resource by table ID. This method does not return the data in the table, it only returns the table resource, which describes the structure of this table.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.tables.get",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "tableId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the requested table",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the requested table",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "selectedFields": {
	//       "description": "List of fields to return (comma-separated). If unspecified, all fields are returned",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "tableId": {
	//       "description": "Table ID of the requested table",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}",
	//   "response": {
	//     "$ref": "Table"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "bigquery.tables.insert":

type TablesInsertCall struct {
	s          *Service
	projectId  string
	datasetId  string
	table      *Table
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Insert: Creates a new, empty table in the dataset.
func (r *TablesService) Insert(projectId string, datasetId string, table *Table) *TablesInsertCall {
	c := &TablesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.table = table
	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 *TablesInsertCall) Fields(s ...googleapi.Field) *TablesInsertCall {
	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 *TablesInsertCall) Context(ctx context.Context) *TablesInsertCall {
	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 *TablesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TablesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.table)
	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, "projects/{projectId}/datasets/{datasetId}/tables")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.tables.insert" call.
// Exactly one of *Table or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Table.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 *TablesInsertCall) Do(opts ...googleapi.CallOption) (*Table, 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 := &Table{
		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 new, empty table in the dataset.",
	//   "httpMethod": "POST",
	//   "id": "bigquery.tables.insert",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the new table",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the new table",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}/tables",
	//   "request": {
	//     "$ref": "Table"
	//   },
	//   "response": {
	//     "$ref": "Table"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.tables.list":

type TablesListCall struct {
	s            *Service
	projectId    string
	datasetId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all tables in the specified dataset. Requires the READER
// dataset role.
func (r *TablesService) List(projectId string, datasetId string) *TablesListCall {
	c := &TablesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return
func (c *TablesListCall) MaxResults(maxResults int64) *TablesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Page token,
// returned by a previous call, to request the next page of results
func (c *TablesListCall) PageToken(pageToken string) *TablesListCall {
	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 *TablesListCall) Fields(s ...googleapi.Field) *TablesListCall {
	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 *TablesListCall) IfNoneMatch(entityTag string) *TablesListCall {
	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 *TablesListCall) Context(ctx context.Context) *TablesListCall {
	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 *TablesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TablesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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, "projects/{projectId}/datasets/{datasetId}/tables")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.tables.list" call.
// Exactly one of *TableList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TableList.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 *TablesListCall) Do(opts ...googleapi.CallOption) (*TableList, 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 := &TableList{
		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 all tables in the specified dataset. Requires the READER dataset role.",
	//   "httpMethod": "GET",
	//   "id": "bigquery.tables.list",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the tables to list",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return",
	//       "format": "uint32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Page token, returned by a previous call, to request the next page of results",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the tables to list",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}/tables",
	//   "response": {
	//     "$ref": "TableList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/bigquery.readonly",
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// 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 *TablesListCall) Pages(ctx context.Context, f func(*TableList) 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 "bigquery.tables.patch":

type TablesPatchCall struct {
	s          *Service
	projectId  string
	datasetId  string
	tableId    string
	table      *Table
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates information in an existing table. The update method
// replaces the entire table resource, whereas the patch method only
// replaces fields that are provided in the submitted table resource.
// This method supports patch semantics.
func (r *TablesService) Patch(projectId string, datasetId string, tableId string, table *Table) *TablesPatchCall {
	c := &TablesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.tableId = tableId
	c.table = table
	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 *TablesPatchCall) Fields(s ...googleapi.Field) *TablesPatchCall {
	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 *TablesPatchCall) Context(ctx context.Context) *TablesPatchCall {
	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 *TablesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TablesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.table)
	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, "projects/{projectId}/datasets/{datasetId}/tables/{tableId}")
	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{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"tableId":   c.tableId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.tables.patch" call.
// Exactly one of *Table or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Table.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 *TablesPatchCall) Do(opts ...googleapi.CallOption) (*Table, 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 := &Table{
		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 information in an existing table. The update method replaces the entire table resource, whereas the patch method only replaces fields that are provided in the submitted table resource. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "bigquery.tables.patch",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "tableId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the table to update",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the table to update",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "tableId": {
	//       "description": "Table ID of the table to update",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}",
	//   "request": {
	//     "$ref": "Table"
	//   },
	//   "response": {
	//     "$ref": "Table"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "bigquery.tables.update":

type TablesUpdateCall struct {
	s          *Service
	projectId  string
	datasetId  string
	tableId    string
	table      *Table
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Update: Updates information in an existing table. The update method
// replaces the entire table resource, whereas the patch method only
// replaces fields that are provided in the submitted table resource.
func (r *TablesService) Update(projectId string, datasetId string, tableId string, table *Table) *TablesUpdateCall {
	c := &TablesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.datasetId = datasetId
	c.tableId = tableId
	c.table = table
	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 *TablesUpdateCall) Fields(s ...googleapi.Field) *TablesUpdateCall {
	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 *TablesUpdateCall) Context(ctx context.Context) *TablesUpdateCall {
	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 *TablesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TablesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200411")
	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.table)
	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, "projects/{projectId}/datasets/{datasetId}/tables/{tableId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"projectId": c.projectId,
		"datasetId": c.datasetId,
		"tableId":   c.tableId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "bigquery.tables.update" call.
// Exactly one of *Table or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Table.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 *TablesUpdateCall) Do(opts ...googleapi.CallOption) (*Table, 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 := &Table{
		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 information in an existing table. The update method replaces the entire table resource, whereas the patch method only replaces fields that are provided in the submitted table resource.",
	//   "httpMethod": "PUT",
	//   "id": "bigquery.tables.update",
	//   "parameterOrder": [
	//     "projectId",
	//     "datasetId",
	//     "tableId"
	//   ],
	//   "parameters": {
	//     "datasetId": {
	//       "description": "Dataset ID of the table to update",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "Project ID of the table to update",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "tableId": {
	//       "description": "Table ID of the table to update",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "projects/{projectId}/datasets/{datasetId}/tables/{tableId}",
	//   "request": {
	//     "$ref": "Table"
	//   },
	//   "response": {
	//     "$ref": "Table"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/bigquery",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
