// 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"`

	// 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.
	Compression string `json:"compression,omitempty"`

	// DestinationFormat: [Optional] The exported file format. Possible
	// values include CSV, NEWLINE_DELIMITED_JSON and AVRO. The default
	// value is CSV. Tables with nested or repeated fields cannot be
	// exported as CSV.
	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 ','
	FieldDelimiter string `json:"fieldDelimiter,omitempty"`

	// PrintHeader: [Optional] Whether to print out a header row in the
	// results. Default is true.
	//
	// 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).
	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"`

	// 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"`

	// 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"`

	// 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"`

	// DdlTargetTable: The DDL target table. Present only for CREATE/DROP
	// TABLE/VIEW 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.
	//   "TENSORFLOW" - [Beta] An imported TensorFlow 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 {
	// 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. "DefaultDataset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DefaultDataset") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field 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)
}

// 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 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 {
	// 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"`

	// 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"`

	// 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"`

	// 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"`

	// 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"`

	// 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"`

	// 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"`

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

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

	// NullFields is a list of field names (e.g. "DataSplitColumn") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field 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"`
		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"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DataSplitEvalFraction = float64(s1.DataSplitEvalFraction)
	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)
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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/1.11.0 gdcl/20200221")
	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"
	//   ]
	// }

}
