// 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 monitoring provides access to the Cloud Monitoring API.
//
// For product documentation, see: https://cloud.google.com/monitoring/api/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/monitoring/v1"
//   ...
//   ctx := context.Background()
//   monitoringService, err := monitoring.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:
//
//   monitoringService, err := monitoring.NewService(ctx, option.WithScopes(monitoring.MonitoringWriteScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   monitoringService, err := monitoring.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, ...)
//   monitoringService, err := monitoring.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package monitoring // import "google.golang.org/api/monitoring/v1"

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 = "monitoring:v1"
const apiName = "monitoring"
const apiVersion = "v1"
const basePath = "https://monitoring.googleapis.com/"
const mtlsBasePath = "https://monitoring.mtls.googleapis.com/"

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

	// View and write monitoring data for all of your Google and third-party
	// Cloud and API projects
	MonitoringScope = "https://www.googleapis.com/auth/monitoring"

	// View monitoring data for all of your Google Cloud and third-party
	// projects
	MonitoringReadScope = "https://www.googleapis.com/auth/monitoring.read"

	// Publish metric data to your Google Cloud projects
	MonitoringWriteScope = "https://www.googleapis.com/auth/monitoring.write"
)

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

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

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

	Projects *ProjectsService
}

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

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

type ProjectsService struct {
	s *Service

	Dashboards *ProjectsDashboardsService
}

func NewProjectsDashboardsService(s *Service) *ProjectsDashboardsService {
	rs := &ProjectsDashboardsService{s: s}
	return rs
}

type ProjectsDashboardsService struct {
	s *Service
}

// Aggregation: Describes how to combine multiple time series to provide
// a different view of the data. Aggregation of time series is done in
// two steps. First, each time series in the set is aligned to the same
// time interval boundaries, then the set of time series is optionally
// reduced in number.Alignment consists of applying the
// per_series_aligner operation to each time series after its data has
// been divided into regular alignment_period time intervals. This
// process takes all of the data points in an alignment period, applies
// a mathematical transformation such as averaging, minimum, maximum,
// delta, etc., and converts them into a single data point per
// period.Reduction is when the aligned and transformed time series can
// optionally be combined, reducing the number of time series through
// similar mathematical transformations. Reduction involves applying a
// cross_series_reducer to all the time series, optionally sorting the
// time series into subsets with group_by_fields, and applying the
// reducer to each subset.The raw time series data can contain a huge
// amount of information from multiple sources. Alignment and reduction
// transforms this mass of data into a more manageable and
// representative collection of data, for example "the 95% latency
// across the average of all tasks in a cluster". This representative
// data can be more easily graphed and comprehended, and the individual
// time series data is still available for later drilldown. For more
// details, see Filtering and aggregation
// (https://cloud.google.com/monitoring/api/v3/aggregation).
type Aggregation struct {
	// AlignmentPeriod: The alignment_period specifies a time interval, in
	// seconds, that is used to divide the data in all the time series into
	// consistent blocks of time. This will be done before the per-series
	// aligner can be applied to the data.The value must be at least 60
	// seconds. If a per-series aligner other than ALIGN_NONE is specified,
	// this field is required or an error is returned. If no per-series
	// aligner is specified, or the aligner ALIGN_NONE is specified, then
	// this field is ignored.The maximum value of the alignment_period is 2
	// years, or 104 weeks.
	AlignmentPeriod string `json:"alignmentPeriod,omitempty"`

	// CrossSeriesReducer: The reduction operation to be used to combine
	// time series into a single time series, where the value of each data
	// point in the resulting series is a function of all the already
	// aligned values in the input time series.Not all reducer operations
	// can be applied to all time series. The valid choices depend on the
	// metric_kind and the value_type of the original time series. Reduction
	// can yield a time series with a different metric_kind or value_type
	// than the input time series.Time series data must first be aligned
	// (see per_series_aligner) in order to perform cross-time series
	// reduction. If cross_series_reducer is specified, then
	// per_series_aligner must be specified, and must not be ALIGN_NONE. An
	// alignment_period must also be specified; otherwise, an error is
	// returned.
	//
	// Possible values:
	//   "REDUCE_NONE" - No cross-time series reduction. The output of the
	// Aligner is returned.
	//   "REDUCE_MEAN" - Reduce by computing the mean value across time
	// series for each alignment period. This reducer is valid for DELTA and
	// GAUGE metrics with numeric or distribution values. The value_type of
	// the output is DOUBLE.
	//   "REDUCE_MIN" - Reduce by computing the minimum value across time
	// series for each alignment period. This reducer is valid for DELTA and
	// GAUGE metrics with numeric values. The value_type of the output is
	// the same as the value_type of the input.
	//   "REDUCE_MAX" - Reduce by computing the maximum value across time
	// series for each alignment period. This reducer is valid for DELTA and
	// GAUGE metrics with numeric values. The value_type of the output is
	// the same as the value_type of the input.
	//   "REDUCE_SUM" - Reduce by computing the sum across time series for
	// each alignment period. This reducer is valid for DELTA and GAUGE
	// metrics with numeric and distribution values. The value_type of the
	// output is the same as the value_type of the input.
	//   "REDUCE_STDDEV" - Reduce by computing the standard deviation across
	// time series for each alignment period. This reducer is valid for
	// DELTA and GAUGE metrics with numeric or distribution values. The
	// value_type of the output is DOUBLE.
	//   "REDUCE_COUNT" - Reduce by computing the number of data points
	// across time series for each alignment period. This reducer is valid
	// for DELTA and GAUGE metrics of numeric, Boolean, distribution, and
	// string value_type. The value_type of the output is INT64.
	//   "REDUCE_COUNT_TRUE" - Reduce by computing the number of True-valued
	// data points across time series for each alignment period. This
	// reducer is valid for DELTA and GAUGE metrics of Boolean value_type.
	// The value_type of the output is INT64.
	//   "REDUCE_COUNT_FALSE" - Reduce by computing the number of
	// False-valued data points across time series for each alignment
	// period. This reducer is valid for DELTA and GAUGE metrics of Boolean
	// value_type. The value_type of the output is INT64.
	//   "REDUCE_FRACTION_TRUE" - Reduce by computing the ratio of the
	// number of True-valued data points to the total number of data points
	// for each alignment period. This reducer is valid for DELTA and GAUGE
	// metrics of Boolean value_type. The output value is in the range 0.0,
	// 1.0 and has value_type DOUBLE.
	//   "REDUCE_PERCENTILE_99" - Reduce by computing the 99th percentile
	// (https://en.wikipedia.org/wiki/Percentile) of data points across time
	// series for each alignment period. This reducer is valid for GAUGE and
	// DELTA metrics of numeric and distribution type. The value of the
	// output is DOUBLE.
	//   "REDUCE_PERCENTILE_95" - Reduce by computing the 95th percentile
	// (https://en.wikipedia.org/wiki/Percentile) of data points across time
	// series for each alignment period. This reducer is valid for GAUGE and
	// DELTA metrics of numeric and distribution type. The value of the
	// output is DOUBLE.
	//   "REDUCE_PERCENTILE_50" - Reduce by computing the 50th percentile
	// (https://en.wikipedia.org/wiki/Percentile) of data points across time
	// series for each alignment period. This reducer is valid for GAUGE and
	// DELTA metrics of numeric and distribution type. The value of the
	// output is DOUBLE.
	//   "REDUCE_PERCENTILE_05" - Reduce by computing the 5th percentile
	// (https://en.wikipedia.org/wiki/Percentile) of data points across time
	// series for each alignment period. This reducer is valid for GAUGE and
	// DELTA metrics of numeric and distribution type. The value of the
	// output is DOUBLE.
	CrossSeriesReducer string `json:"crossSeriesReducer,omitempty"`

	// GroupByFields: The set of fields to preserve when
	// cross_series_reducer is specified. The group_by_fields determine how
	// the time series are partitioned into subsets prior to applying the
	// aggregation operation. Each subset contains time series that have the
	// same value for each of the grouping fields. Each individual time
	// series is a member of exactly one subset. The cross_series_reducer is
	// applied to each subset of time series. It is not possible to reduce
	// across different resource types, so this field implicitly contains
	// resource.type. Fields not specified in group_by_fields are aggregated
	// away. If group_by_fields is not specified and all the time series
	// have the same resource type, then the time series are aggregated into
	// a single output time series. If cross_series_reducer is not defined,
	// this field is ignored.
	GroupByFields []string `json:"groupByFields,omitempty"`

	// PerSeriesAligner: An Aligner describes how to bring the data points
	// in a single time series into temporal alignment. Except for
	// ALIGN_NONE, all alignments cause all the data points in an
	// alignment_period to be mathematically grouped together, resulting in
	// a single data point for each alignment_period with end timestamp at
	// the end of the period.Not all alignment operations may be applied to
	// all time series. The valid choices depend on the metric_kind and
	// value_type of the original time series. Alignment can change the
	// metric_kind or the value_type of the time series.Time series data
	// must be aligned in order to perform cross-time series reduction. If
	// cross_series_reducer is specified, then per_series_aligner must be
	// specified and not equal to ALIGN_NONE and alignment_period must be
	// specified; otherwise, an error is returned.
	//
	// Possible values:
	//   "ALIGN_NONE" - No alignment. Raw data is returned. Not valid if
	// cross-series reduction is requested. The value_type of the result is
	// the same as the value_type of the input.
	//   "ALIGN_DELTA" - Align and convert to DELTA. The output is delta =
	// y1 - y0.This alignment is valid for CUMULATIVE and DELTA metrics. If
	// the selected alignment period results in periods with no data, then
	// the aligned value for such a period is created by interpolation. The
	// value_type of the aligned result is the same as the value_type of the
	// input.
	//   "ALIGN_RATE" - Align and convert to a rate. The result is computed
	// as rate = (y1 - y0)/(t1 - t0), or "delta over time". Think of this
	// aligner as providing the slope of the line that passes through the
	// value at the start and at the end of the alignment_period.This
	// aligner is valid for CUMULATIVE and DELTA metrics with numeric
	// values. If the selected alignment period results in periods with no
	// data, then the aligned value for such a period is created by
	// interpolation. The output is a GAUGE metric with value_type
	// DOUBLE.If, by "rate", you mean "percentage change", see the
	// ALIGN_PERCENT_CHANGE aligner instead.
	//   "ALIGN_INTERPOLATE" - Align by interpolating between adjacent
	// points around the alignment period boundary. This aligner is valid
	// for GAUGE metrics with numeric values. The value_type of the aligned
	// result is the same as the value_type of the input.
	//   "ALIGN_NEXT_OLDER" - Align by moving the most recent data point
	// before the end of the alignment period to the boundary at the end of
	// the alignment period. This aligner is valid for GAUGE metrics. The
	// value_type of the aligned result is the same as the value_type of the
	// input.
	//   "ALIGN_MIN" - Align the time series by returning the minimum value
	// in each alignment period. This aligner is valid for GAUGE and DELTA
	// metrics with numeric values. The value_type of the aligned result is
	// the same as the value_type of the input.
	//   "ALIGN_MAX" - Align the time series by returning the maximum value
	// in each alignment period. This aligner is valid for GAUGE and DELTA
	// metrics with numeric values. The value_type of the aligned result is
	// the same as the value_type of the input.
	//   "ALIGN_MEAN" - Align the time series by returning the mean value in
	// each alignment period. This aligner is valid for GAUGE and DELTA
	// metrics with numeric values. The value_type of the aligned result is
	// DOUBLE.
	//   "ALIGN_COUNT" - Align the time series by returning the number of
	// values in each alignment period. This aligner is valid for GAUGE and
	// DELTA metrics with numeric or Boolean values. The value_type of the
	// aligned result is INT64.
	//   "ALIGN_SUM" - Align the time series by returning the sum of the
	// values in each alignment period. This aligner is valid for GAUGE and
	// DELTA metrics with numeric and distribution values. The value_type of
	// the aligned result is the same as the value_type of the input.
	//   "ALIGN_STDDEV" - Align the time series by returning the standard
	// deviation of the values in each alignment period. This aligner is
	// valid for GAUGE and DELTA metrics with numeric values. The value_type
	// of the output is DOUBLE.
	//   "ALIGN_COUNT_TRUE" - Align the time series by returning the number
	// of True values in each alignment period. This aligner is valid for
	// GAUGE metrics with Boolean values. The value_type of the output is
	// INT64.
	//   "ALIGN_COUNT_FALSE" - Align the time series by returning the number
	// of False values in each alignment period. This aligner is valid for
	// GAUGE metrics with Boolean values. The value_type of the output is
	// INT64.
	//   "ALIGN_FRACTION_TRUE" - Align the time series by returning the
	// ratio of the number of True values to the total number of values in
	// each alignment period. This aligner is valid for GAUGE metrics with
	// Boolean values. The output value is in the range 0.0, 1.0 and has
	// value_type DOUBLE.
	//   "ALIGN_PERCENTILE_99" - Align the time series by using percentile
	// aggregation (https://en.wikipedia.org/wiki/Percentile). The resulting
	// data point in each alignment period is the 99th percentile of all
	// data points in the period. This aligner is valid for GAUGE and DELTA
	// metrics with distribution values. The output is a GAUGE metric with
	// value_type DOUBLE.
	//   "ALIGN_PERCENTILE_95" - Align the time series by using percentile
	// aggregation (https://en.wikipedia.org/wiki/Percentile). The resulting
	// data point in each alignment period is the 95th percentile of all
	// data points in the period. This aligner is valid for GAUGE and DELTA
	// metrics with distribution values. The output is a GAUGE metric with
	// value_type DOUBLE.
	//   "ALIGN_PERCENTILE_50" - Align the time series by using percentile
	// aggregation (https://en.wikipedia.org/wiki/Percentile). The resulting
	// data point in each alignment period is the 50th percentile of all
	// data points in the period. This aligner is valid for GAUGE and DELTA
	// metrics with distribution values. The output is a GAUGE metric with
	// value_type DOUBLE.
	//   "ALIGN_PERCENTILE_05" - Align the time series by using percentile
	// aggregation (https://en.wikipedia.org/wiki/Percentile). The resulting
	// data point in each alignment period is the 5th percentile of all data
	// points in the period. This aligner is valid for GAUGE and DELTA
	// metrics with distribution values. The output is a GAUGE metric with
	// value_type DOUBLE.
	//   "ALIGN_PERCENT_CHANGE" - Align and convert to a percentage change.
	// This aligner is valid for GAUGE and DELTA metrics with numeric
	// values. This alignment returns ((current - previous)/previous) * 100,
	// where the value of previous is determined based on the
	// alignment_period.If the values of current and previous are both 0,
	// then the returned value is 0. If only previous is 0, the returned
	// value is infinity.A 10-minute moving mean is computed at each point
	// of the alignment period prior to the above calculation to smooth the
	// metric and prevent false positives from very short-lived spikes. The
	// moving mean is only applicable for data whose values are >= 0. Any
	// values < 0 are treated as a missing datapoint, and are ignored. While
	// DELTA metrics are accepted by this alignment, special care should be
	// taken that the values for the metric will always be positive. The
	// output is a GAUGE metric with value_type DOUBLE.
	PerSeriesAligner string `json:"perSeriesAligner,omitempty"`

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

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

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

// Axis: A chart axis.
type Axis struct {
	// Label: The label of the axis.
	Label string `json:"label,omitempty"`

	// Scale: The axis scale. By default, a linear scale is used.
	//
	// Possible values:
	//   "SCALE_UNSPECIFIED" - Scale is unspecified. The view will default
	// to LINEAR.
	//   "LINEAR" - Linear scale.
	//   "LOG10" - Logarithmic scale (base 10).
	Scale string `json:"scale,omitempty"`

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

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

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

// ChartOptions: Options to control visual rendering of a chart.
type ChartOptions struct {
	// Mode: The chart mode.
	//
	// Possible values:
	//   "MODE_UNSPECIFIED" - Mode is unspecified. The view will default to
	// COLOR.
	//   "COLOR" - The chart distinguishes data series using different
	// color. Line colors may get reused when there are many lines in the
	// chart.
	//   "X_RAY" - The chart uses the Stackdriver x-ray mode, in which each
	// data set is plotted using the same semi-transparent color.
	//   "STATS" - The chart displays statistics such as average, median,
	// 95th percentile, and more.
	Mode string `json:"mode,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 *ChartOptions) MarshalJSON() ([]byte, error) {
	type NoMethod ChartOptions
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Column: Defines the layout properties and content for a column.
type Column struct {
	// Weight: The relative weight of this column. The column weight is used
	// to adjust the width of columns on the screen (relative to peers).
	// Greater the weight, greater the width of the column on the screen. If
	// omitted, a value of 1 is used while rendering.
	Weight int64 `json:"weight,omitempty,string"`

	// Widgets: The display widgets arranged vertically in this column.
	Widgets []*Widget `json:"widgets,omitempty"`

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

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

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

// ColumnLayout: A simplified layout that divides the available space
// into vertical columns and arranges a set of widgets vertically in
// each column.
type ColumnLayout struct {
	// Columns: The columns of content to display.
	Columns []*Column `json:"columns,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 *ColumnLayout) MarshalJSON() ([]byte, error) {
	type NoMethod ColumnLayout
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Dashboard: A Google Stackdriver dashboard. Dashboards define the
// content and layout of pages in the Stackdriver web application.
type Dashboard struct {
	// ColumnLayout: The content is divided into equally spaced columns and
	// the widgets are arranged vertically.
	ColumnLayout *ColumnLayout `json:"columnLayout,omitempty"`

	// DisplayName: Required. The mutable, human-readable name.
	DisplayName string `json:"displayName,omitempty"`

	// Etag: etag is used for optimistic concurrency control as a way to
	// help prevent simultaneous updates of a policy from overwriting each
	// other. An etag is returned in the response to GetDashboard, and users
	// are expected to put that etag in the request to UpdateDashboard to
	// ensure that their change will be applied to the same version of the
	// Dashboard configuration. The field should not be passed during
	// dashboard creation.
	Etag string `json:"etag,omitempty"`

	// GridLayout: Content is arranged with a basic layout that re-flows a
	// simple list of informational elements like widgets or tiles.
	GridLayout *GridLayout `json:"gridLayout,omitempty"`

	// Name: Immutable. The resource name of the dashboard.
	Name string `json:"name,omitempty"`

	// RowLayout: The content is divided into equally spaced rows and the
	// widgets are arranged horizontally.
	RowLayout *RowLayout `json:"rowLayout,omitempty"`

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

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

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

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

// DataSet: Groups a time series query definition with charting options.
type DataSet struct {
	// LegendTemplate: A template string for naming TimeSeries in the
	// resulting data set. This should be a string with interpolations of
	// the form ${label_name}, which will resolve to the label's value.
	LegendTemplate string `json:"legendTemplate,omitempty"`

	// MinAlignmentPeriod: Optional. The lower bound on data point frequency
	// for this data set, implemented by specifying the minimum alignment
	// period to use in a time series query For example, if the data is
	// published once every 10 minutes, the min_alignment_period should be
	// at least 10 minutes. It would not make sense to fetch and align data
	// at one minute intervals.
	MinAlignmentPeriod string `json:"minAlignmentPeriod,omitempty"`

	// PlotType: How this data should be plotted on the chart.
	//
	// Possible values:
	//   "PLOT_TYPE_UNSPECIFIED" - Plot type is unspecified. The view will
	// default to LINE.
	//   "LINE" - The data is plotted as a set of lines (one line per
	// series).
	//   "STACKED_AREA" - The data is plotted as a set of filled areas (one
	// area per series), with the areas stacked vertically (the base of each
	// area is the top of its predecessor, and the base of the first area is
	// the X axis). Since the areas do not overlap, each is filled with a
	// different opaque color.
	//   "STACKED_BAR" - The data is plotted as a set of rectangular boxes
	// (one box per series), with the boxes stacked vertically (the base of
	// each box is the top of its predecessor, and the base of the first box
	// is the X axis). Since the boxes do not overlap, each is filled with a
	// different opaque color.
	//   "HEATMAP" - The data is plotted as a heatmap. The series being
	// plotted must have a DISTRIBUTION value type. The value of each bucket
	// in the distribution is displayed as a color. This type is not
	// currently available in the Stackdriver Monitoring application.
	PlotType string `json:"plotType,omitempty"`

	// TimeSeriesQuery: Required. Fields for querying time series data from
	// the Stackdriver metrics API.
	TimeSeriesQuery *TimeSeriesQuery `json:"timeSeriesQuery,omitempty"`

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

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

// DroppedLabels: A set of (label, value) pairs that were removed from a
// Distribution time series during aggregation and then added as an
// attachment to a Distribution.Exemplar.The full label set for the
// exemplars is constructed by using the dropped pairs in combination
// with the label values that remain on the aggregated Distribution time
// series. The constructed full label set can be used to identify the
// specific entity, such as the instance or job, which might be
// contributing to a long-tail. However, with dropped labels, the
// storage requirements are reduced because only the aggregated
// distribution values for a large group of time series are stored.Note
// that there are no guarantees on ordering of the labels from
// exemplar-to-exemplar and from distribution-to-distribution in the
// same stream, and there may be duplicates. It is up to clients to
// resolve any ambiguities.
type DroppedLabels struct {
	// Label: Map from label to its value, for all labels dropped in any
	// aggregation.
	Label map[string]string `json:"label,omitempty"`

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

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

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

// Empty: A generic empty message that you can re-use to avoid defining
// duplicated empty messages in your APIs. A typical example is to use
// it as the request or the response type of an API method. For
// instance:
// service Foo {
//   rpc Bar(google.protobuf.Empty) returns
// (google.protobuf.Empty);
// }
// The JSON representation for Empty is empty JSON object {}.
type Empty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// Field: A single field of a message type.
type Field struct {
	// Cardinality: The field cardinality.
	//
	// Possible values:
	//   "CARDINALITY_UNKNOWN" - For fields with unknown cardinality.
	//   "CARDINALITY_OPTIONAL" - For optional fields.
	//   "CARDINALITY_REQUIRED" - For required fields. Proto2 syntax only.
	//   "CARDINALITY_REPEATED" - For repeated fields.
	Cardinality string `json:"cardinality,omitempty"`

	// DefaultValue: The string value of the default value of this field.
	// Proto2 syntax only.
	DefaultValue string `json:"defaultValue,omitempty"`

	// JsonName: The field JSON name.
	JsonName string `json:"jsonName,omitempty"`

	// Kind: The field type.
	//
	// Possible values:
	//   "TYPE_UNKNOWN" - Field type unknown.
	//   "TYPE_DOUBLE" - Field type double.
	//   "TYPE_FLOAT" - Field type float.
	//   "TYPE_INT64" - Field type int64.
	//   "TYPE_UINT64" - Field type uint64.
	//   "TYPE_INT32" - Field type int32.
	//   "TYPE_FIXED64" - Field type fixed64.
	//   "TYPE_FIXED32" - Field type fixed32.
	//   "TYPE_BOOL" - Field type bool.
	//   "TYPE_STRING" - Field type string.
	//   "TYPE_GROUP" - Field type group. Proto2 syntax only, and
	// deprecated.
	//   "TYPE_MESSAGE" - Field type message.
	//   "TYPE_BYTES" - Field type bytes.
	//   "TYPE_UINT32" - Field type uint32.
	//   "TYPE_ENUM" - Field type enum.
	//   "TYPE_SFIXED32" - Field type sfixed32.
	//   "TYPE_SFIXED64" - Field type sfixed64.
	//   "TYPE_SINT32" - Field type sint32.
	//   "TYPE_SINT64" - Field type sint64.
	Kind string `json:"kind,omitempty"`

	// Name: The field name.
	Name string `json:"name,omitempty"`

	// Number: The field number.
	Number int64 `json:"number,omitempty"`

	// OneofIndex: The index of the field type in Type.oneofs, for message
	// or enumeration types. The first type has index 1; zero means the type
	// is not in the list.
	OneofIndex int64 `json:"oneofIndex,omitempty"`

	// Options: The protocol buffer options.
	Options []*Option `json:"options,omitempty"`

	// Packed: Whether to use alternative packed wire representation.
	Packed bool `json:"packed,omitempty"`

	// TypeUrl: The field type URL, without the scheme, for message or
	// enumeration types. Example:
	// "type.googleapis.com/google.protobuf.Timestamp".
	TypeUrl string `json:"typeUrl,omitempty"`

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

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

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

// GaugeView: A gauge chart shows where the current value sits within a
// pre-defined range. The upper and lower bounds should define the
// possible range of values for the scorecard's query (inclusive).
type GaugeView struct {
	// LowerBound: The lower bound for this gauge chart. The value of the
	// chart should always be greater than or equal to this.
	LowerBound float64 `json:"lowerBound,omitempty"`

	// UpperBound: The upper bound for this gauge chart. The value of the
	// chart should always be less than or equal to this.
	UpperBound float64 `json:"upperBound,omitempty"`

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

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

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

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

// GridLayout: A basic layout divides the available space into vertical
// columns of equal width and arranges a list of widgets using a
// row-first strategy.
type GridLayout struct {
	// Columns: The number of columns into which the view's width is
	// divided. If omitted or set to zero, a system default will be used
	// while rendering.
	Columns int64 `json:"columns,omitempty,string"`

	// Widgets: The informational elements that are arranged into the
	// columns row-first.
	Widgets []*Widget `json:"widgets,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 *GridLayout) MarshalJSON() ([]byte, error) {
	type NoMethod GridLayout
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListDashboardsResponse: The ListDashboards request.
type ListDashboardsResponse struct {
	// Dashboards: The list of requested dashboards.
	Dashboards []*Dashboard `json:"dashboards,omitempty"`

	// NextPageToken: If there are more results than have been returned,
	// then this field is set to a non-empty value. To see the additional
	// results, use that value as page_token in the next call to this
	// method.
	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. "Dashboards") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

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

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

// Option: A protocol buffer option, which can be attached to a message,
// field, enumeration, etc.
type Option struct {
	// Name: The option's name. For protobuf built-in options (options
	// defined in descriptor.proto), this is the short name. For example,
	// "map_entry". For custom options, it should be the fully-qualified
	// name. For example, "google.api.http".
	Name string `json:"name,omitempty"`

	// Value: The option's value packed in an Any message. If the value is a
	// primitive, the corresponding wrapper type defined in
	// google/protobuf/wrappers.proto should be used. If the value is an
	// enum, it should be stored as an int32 value using the
	// google.protobuf.Int32Value type.
	Value googleapi.RawMessage `json:"value,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 *Option) MarshalJSON() ([]byte, error) {
	type NoMethod Option
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PickTimeSeriesFilter: Describes a ranking-based time series filter.
// Each input time series is ranked with an aligner. The filter will
// allow up to num_time_series time series to pass through it, selecting
// them based on the relative ranking.For example, if ranking_method is
// METHOD_MEAN,direction is BOTTOM, and num_time_series is 3, then the 3
// times series with the lowest mean values will pass through the
// filter.
type PickTimeSeriesFilter struct {
	// Direction: How to use the ranking to select time series that pass
	// through the filter.
	//
	// Possible values:
	//   "DIRECTION_UNSPECIFIED" - Not allowed. You must specify a different
	// Direction if you specify a PickTimeSeriesFilter.
	//   "TOP" - Pass the highest num_time_series ranking inputs.
	//   "BOTTOM" - Pass the lowest num_time_series ranking inputs.
	Direction string `json:"direction,omitempty"`

	// NumTimeSeries: How many time series to allow to pass through the
	// filter.
	NumTimeSeries int64 `json:"numTimeSeries,omitempty"`

	// RankingMethod: ranking_method is applied to each time series
	// independently to produce the value which will be used to compare the
	// time series to other time series.
	//
	// Possible values:
	//   "METHOD_UNSPECIFIED" - Not allowed. You must specify a different
	// Method if you specify a PickTimeSeriesFilter.
	//   "METHOD_MEAN" - Select the mean of all values.
	//   "METHOD_MAX" - Select the maximum value.
	//   "METHOD_MIN" - Select the minimum value.
	//   "METHOD_SUM" - Compute the sum of all values.
	//   "METHOD_LATEST" - Select the most recent value.
	RankingMethod string `json:"rankingMethod,omitempty"`

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

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

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

// RatioPart: Describes a query to build the numerator or denominator of
// a TimeSeriesFilterRatio.
type RatioPart struct {
	// Aggregation: By default, the raw time series data is returned. Use
	// this field to combine multiple time series for different views of the
	// data.
	Aggregation *Aggregation `json:"aggregation,omitempty"`

	// Filter: Required. The monitoring filter
	// (https://cloud.google.com/monitoring/api/v3/filters) that identifies
	// the metric types, resources, and projects to query.
	Filter string `json:"filter,omitempty"`

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

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

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

// Row: Defines the layout properties and content for a row.
type Row struct {
	// Weight: The relative weight of this row. The row weight is used to
	// adjust the height of rows on the screen (relative to peers). Greater
	// the weight, greater the height of the row on the screen. If omitted,
	// a value of 1 is used while rendering.
	Weight int64 `json:"weight,omitempty,string"`

	// Widgets: The display widgets arranged horizontally in this row.
	Widgets []*Widget `json:"widgets,omitempty"`

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

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

// RowLayout: A simplified layout that divides the available space into
// rows and arranges a set of widgets horizontally in each row.
type RowLayout struct {
	// Rows: The rows of content to display.
	Rows []*Row `json:"rows,omitempty"`

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

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

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

// Scorecard: A widget showing the latest value of a metric, and how
// this value relates to one or more thresholds.
type Scorecard struct {
	// GaugeView: Will cause the scorecard to show a gauge chart.
	GaugeView *GaugeView `json:"gaugeView,omitempty"`

	// SparkChartView: Will cause the scorecard to show a spark chart.
	SparkChartView *SparkChartView `json:"sparkChartView,omitempty"`

	// Thresholds: The thresholds used to determine the state of the
	// scorecard given the time series' current value. For an actual value
	// x, the scorecard is in a danger state if x is less than or equal to a
	// danger threshold that triggers below, or greater than or equal to a
	// danger threshold that triggers above. Similarly, if x is above/below
	// a warning threshold that triggers above/below, then the scorecard is
	// in a warning state - unless x also puts it in a danger state. (Danger
	// trumps warning.)As an example, consider a scorecard with the
	// following four thresholds: {  value: 90,  category: 'DANGER',
	// trigger: 'ABOVE', }, {  value: 70,  category: 'WARNING',  trigger:
	// 'ABOVE', }, {  value: 10,  category: 'DANGER',  trigger: 'BELOW', },
	// {  value: 20,  category: 'WARNING',  trigger: 'BELOW', }Then: values
	// less than or equal to 10 would put the scorecard in a DANGER state,
	// values greater than 10 but less than or equal to 20 a WARNING state,
	// values strictly between 20 and 70 an OK state, values greater than or
	// equal to 70 but less than 90 a WARNING state, and values greater than
	// or equal to 90 a DANGER state.
	Thresholds []*Threshold `json:"thresholds,omitempty"`

	// TimeSeriesQuery: Required. Fields for querying time series data from
	// the Stackdriver metrics API.
	TimeSeriesQuery *TimeSeriesQuery `json:"timeSeriesQuery,omitempty"`

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

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

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

// SourceContext: SourceContext represents information about the source
// of a protobuf element, like the file in which it is defined.
type SourceContext struct {
	// FileName: The path-qualified name of the .proto file that contained
	// the associated protobuf element. For example:
	// "google/protobuf/source_context.proto".
	FileName string `json:"fileName,omitempty"`

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

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

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

// SpanContext: The context of a span, attached to Exemplars in
// Distribution values during aggregation.It contains the name of a span
// with
// format:
// projects/[PROJECT_ID_OR_NUMBER]/traces/[TRACE_ID]/spans/[SPAN_
// ID]
//
type SpanContext struct {
	// SpanName: The resource name of the span. The format
	// is:
	// projects/[PROJECT_ID_OR_NUMBER]/traces/[TRACE_ID]/spans/[SPAN_ID]
	//
	// [TRACE_ID] is a unique identifier for a trace within a project; it is
	// a 32-character hexadecimal encoding of a 16-byte array.[SPAN_ID] is a
	// unique identifier for a span within a trace; it is a 16-character
	// hexadecimal encoding of an 8-byte array.
	SpanName string `json:"spanName,omitempty"`

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

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

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

// SparkChartView: A sparkChart is a small chart suitable for inclusion
// in a table-cell or inline in text. This message contains the
// configuration for a sparkChart to show up on a Scorecard, showing
// recent trends of the scorecard's timeseries.
type SparkChartView struct {
	// MinAlignmentPeriod: The lower bound on data point frequency in the
	// chart implemented by specifying the minimum alignment period to use
	// in a time series query. For example, if the data is published once
	// every 10 minutes it would not make sense to fetch and align data at
	// one minute intervals. This field is optional and exists only as a
	// hint.
	MinAlignmentPeriod string `json:"minAlignmentPeriod,omitempty"`

	// SparkChartType: Required. The type of sparkchart to show in this
	// chartView.
	//
	// Possible values:
	//   "SPARK_CHART_TYPE_UNSPECIFIED" - Not allowed in well-formed
	// requests.
	//   "SPARK_LINE" - The sparkline will be rendered as a small line
	// chart.
	//   "SPARK_BAR" - The sparkbar will be rendered as a small bar chart.
	SparkChartType string `json:"sparkChartType,omitempty"`

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

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

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

// StatisticalTimeSeriesFilter: A filter that ranks streams based on
// their statistical relation to other streams in a request. Note: This
// field is deprecated and completely ignored by the API.
type StatisticalTimeSeriesFilter struct {
	// NumTimeSeries: How many time series to output.
	NumTimeSeries int64 `json:"numTimeSeries,omitempty"`

	// RankingMethod: rankingMethod is applied to a set of time series, and
	// then the produced value for each individual time series is used to
	// compare a given time series to others. These are methods that cannot
	// be applied stream-by-stream, but rather require the full context of a
	// request to evaluate time series.
	//
	// Possible values:
	//   "METHOD_UNSPECIFIED" - Not allowed in well-formed requests.
	//   "METHOD_CLUSTER_OUTLIER" - Compute the outlier score of each
	// stream.
	RankingMethod string `json:"rankingMethod,omitempty"`

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

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

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

// Text: A widget that displays textual content.
type Text struct {
	// Content: The text content to be displayed.
	Content string `json:"content,omitempty"`

	// Format: How the text content is formatted.
	//
	// Possible values:
	//   "FORMAT_UNSPECIFIED" - Format is unspecified. Defaults to MARKDOWN.
	//   "MARKDOWN" - The text contains Markdown formatting.
	//   "RAW" - The text contains no special formatting.
	Format string `json:"format,omitempty"`

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

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

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

// Threshold: Defines a threshold for categorizing time series values.
type Threshold struct {
	// Color: The state color for this threshold. Color is not allowed in a
	// XyChart.
	//
	// Possible values:
	//   "COLOR_UNSPECIFIED" - Color is unspecified. Not allowed in
	// well-formed requests.
	//   "YELLOW" - Crossing the threshold is "concerning" behavior.
	//   "RED" - Crossing the threshold is "emergency" behavior.
	Color string `json:"color,omitempty"`

	// Direction: The direction for the current threshold. Direction is not
	// allowed in a XyChart.
	//
	// Possible values:
	//   "DIRECTION_UNSPECIFIED" - Not allowed in well-formed requests.
	//   "ABOVE" - The threshold will be considered crossed if the actual
	// value is above the threshold value.
	//   "BELOW" - The threshold will be considered crossed if the actual
	// value is below the threshold value.
	Direction string `json:"direction,omitempty"`

	// Label: A label for the threshold.
	Label string `json:"label,omitempty"`

	// Value: The value of the threshold. The value should be defined in the
	// native scale of the metric.
	Value float64 `json:"value,omitempty"`

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

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

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

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

// TimeSeriesFilter: A filter that defines a subset of time series data
// that is displayed in a widget. Time series data is fetched using the
// ListTimeSeries
// (https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.timeS
// eries/list) method.
type TimeSeriesFilter struct {
	// Aggregation: By default, the raw time series data is returned. Use
	// this field to combine multiple time series for different views of the
	// data.
	Aggregation *Aggregation `json:"aggregation,omitempty"`

	// Filter: Required. The monitoring filter
	// (https://cloud.google.com/monitoring/api/v3/filters) that identifies
	// the metric types, resources, and projects to query.
	Filter string `json:"filter,omitempty"`

	// PickTimeSeriesFilter: Ranking based time series filter.
	PickTimeSeriesFilter *PickTimeSeriesFilter `json:"pickTimeSeriesFilter,omitempty"`

	// SecondaryAggregation: Apply a second aggregation after aggregation is
	// applied.
	SecondaryAggregation *Aggregation `json:"secondaryAggregation,omitempty"`

	// StatisticalTimeSeriesFilter: Statistics based time series filter.
	// Note: This field is deprecated and completely ignored by the API.
	StatisticalTimeSeriesFilter *StatisticalTimeSeriesFilter `json:"statisticalTimeSeriesFilter,omitempty"`

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

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

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

// TimeSeriesFilterRatio: A pair of time series filters that define a
// ratio computation. The output time series is the pair-wise division
// of each aligned element from the numerator and denominator time
// series.
type TimeSeriesFilterRatio struct {
	// Denominator: The denominator of the ratio.
	Denominator *RatioPart `json:"denominator,omitempty"`

	// Numerator: The numerator of the ratio.
	Numerator *RatioPart `json:"numerator,omitempty"`

	// PickTimeSeriesFilter: Ranking based time series filter.
	PickTimeSeriesFilter *PickTimeSeriesFilter `json:"pickTimeSeriesFilter,omitempty"`

	// SecondaryAggregation: Apply a second aggregation after the ratio is
	// computed.
	SecondaryAggregation *Aggregation `json:"secondaryAggregation,omitempty"`

	// StatisticalTimeSeriesFilter: Statistics based time series filter.
	// Note: This field is deprecated and completely ignored by the API.
	StatisticalTimeSeriesFilter *StatisticalTimeSeriesFilter `json:"statisticalTimeSeriesFilter,omitempty"`

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

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

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

// TimeSeriesQuery: TimeSeriesQuery collects the set of supported
// methods for querying time series data from the Stackdriver metrics
// API.
type TimeSeriesQuery struct {
	// TimeSeriesFilter: Filter parameters to fetch time series.
	TimeSeriesFilter *TimeSeriesFilter `json:"timeSeriesFilter,omitempty"`

	// TimeSeriesFilterRatio: Parameters to fetch a ratio between two time
	// series filters.
	TimeSeriesFilterRatio *TimeSeriesFilterRatio `json:"timeSeriesFilterRatio,omitempty"`

	// TimeSeriesQueryLanguage: A query used to fetch time series.
	TimeSeriesQueryLanguage string `json:"timeSeriesQueryLanguage,omitempty"`

	// UnitOverride: The unit of data contained in fetched time series. If
	// non-empty, this unit will override any unit that accompanies fetched
	// data. The format is the same as the unit
	// (https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.metri
	// cDescriptors) field in MetricDescriptor.
	UnitOverride string `json:"unitOverride,omitempty"`

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

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

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

// Type: A protocol buffer message type.
type Type struct {
	// Fields: The list of fields.
	Fields []*Field `json:"fields,omitempty"`

	// Name: The fully qualified message name.
	Name string `json:"name,omitempty"`

	// Oneofs: The list of types appearing in oneof definitions in this
	// type.
	Oneofs []string `json:"oneofs,omitempty"`

	// Options: The protocol buffer options.
	Options []*Option `json:"options,omitempty"`

	// SourceContext: The source context.
	SourceContext *SourceContext `json:"sourceContext,omitempty"`

	// Syntax: The source syntax.
	//
	// Possible values:
	//   "SYNTAX_PROTO2" - Syntax proto2.
	//   "SYNTAX_PROTO3" - Syntax proto3.
	Syntax string `json:"syntax,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 *Type) MarshalJSON() ([]byte, error) {
	type NoMethod Type
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Widget: Widget contains a single dashboard component and
// configuration of how to present the component in the dashboard.
type Widget struct {
	// Blank: A blank space.
	Blank *Empty `json:"blank,omitempty"`

	// Scorecard: A scorecard summarizing time series data.
	Scorecard *Scorecard `json:"scorecard,omitempty"`

	// Text: A raw string or markdown displaying textual content.
	Text *Text `json:"text,omitempty"`

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

	// XyChart: A chart of time series data.
	XyChart *XyChart `json:"xyChart,omitempty"`

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

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

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

// XyChart: A chart that displays data on a 2D (X and Y axes) plane.
type XyChart struct {
	// ChartOptions: Display options for the chart.
	ChartOptions *ChartOptions `json:"chartOptions,omitempty"`

	// DataSets: Required. The data displayed in this chart.
	DataSets []*DataSet `json:"dataSets,omitempty"`

	// Thresholds: Threshold lines drawn horizontally across the chart.
	Thresholds []*Threshold `json:"thresholds,omitempty"`

	// TimeshiftDuration: The duration used to display a comparison chart. A
	// comparison chart simultaneously shows values from two similar-length
	// time periods (e.g., week-over-week metrics). The duration must be
	// positive, and it can only be applied to charts with data sets of LINE
	// plot type.
	TimeshiftDuration string `json:"timeshiftDuration,omitempty"`

	// XAxis: The properties applied to the X axis.
	XAxis *Axis `json:"xAxis,omitempty"`

	// YAxis: The properties applied to the Y axis.
	YAxis *Axis `json:"yAxis,omitempty"`

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

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

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

// method id "monitoring.projects.dashboards.create":

type ProjectsDashboardsCreateCall struct {
	s          *Service
	parent     string
	dashboard  *Dashboard
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a new custom dashboard.This method requires the
// monitoring.dashboards.create permission on the specified project. For
// more information, see Google Cloud IAM
// (https://cloud.google.com/iam).
func (r *ProjectsDashboardsService) Create(parent string, dashboard *Dashboard) *ProjectsDashboardsCreateCall {
	c := &ProjectsDashboardsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.dashboard = dashboard
	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 *ProjectsDashboardsCreateCall) Fields(s ...googleapi.Field) *ProjectsDashboardsCreateCall {
	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 *ProjectsDashboardsCreateCall) Context(ctx context.Context) *ProjectsDashboardsCreateCall {
	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 *ProjectsDashboardsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDashboardsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200728")
	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.dashboard)
	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, "v1/{+parent}/dashboards")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "monitoring.projects.dashboards.create" call.
// Exactly one of *Dashboard or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Dashboard.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 *ProjectsDashboardsCreateCall) Do(opts ...googleapi.CallOption) (*Dashboard, 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 := &Dashboard{
		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 custom dashboard.This method requires the monitoring.dashboards.create permission on the specified project. For more information, see Google Cloud IAM (https://cloud.google.com/iam).",
	//   "flatPath": "v1/projects/{projectsId}/dashboards",
	//   "httpMethod": "POST",
	//   "id": "monitoring.projects.dashboards.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The project on which to execute the request. The format is:\nprojects/[PROJECT_ID_OR_NUMBER]\nThe [PROJECT_ID_OR_NUMBER] must match the dashboard resource name.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/dashboards",
	//   "request": {
	//     "$ref": "Dashboard"
	//   },
	//   "response": {
	//     "$ref": "Dashboard"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/monitoring",
	//     "https://www.googleapis.com/auth/monitoring.write"
	//   ]
	// }

}

// method id "monitoring.projects.dashboards.delete":

type ProjectsDashboardsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing custom dashboard.This method requires the
// monitoring.dashboards.delete permission on the specified dashboard.
// For more information, see Google Cloud IAM
// (https://cloud.google.com/iam).
func (r *ProjectsDashboardsService) Delete(name string) *ProjectsDashboardsDeleteCall {
	c := &ProjectsDashboardsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsDashboardsDeleteCall) Fields(s ...googleapi.Field) *ProjectsDashboardsDeleteCall {
	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 *ProjectsDashboardsDeleteCall) Context(ctx context.Context) *ProjectsDashboardsDeleteCall {
	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 *ProjectsDashboardsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDashboardsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200728")
	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, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "monitoring.projects.dashboards.delete" call.
// Exactly one of *Empty or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Empty.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 *ProjectsDashboardsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, 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 := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Deletes an existing custom dashboard.This method requires the monitoring.dashboards.delete permission on the specified dashboard. For more information, see Google Cloud IAM (https://cloud.google.com/iam).",
	//   "flatPath": "v1/projects/{projectsId}/dashboards/{dashboardsId}",
	//   "httpMethod": "DELETE",
	//   "id": "monitoring.projects.dashboards.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the Dashboard. The format is:\nprojects/[PROJECT_ID_OR_NUMBER]/dashboards/[DASHBOARD_ID]\n",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/dashboards/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Empty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/monitoring",
	//     "https://www.googleapis.com/auth/monitoring.write"
	//   ]
	// }

}

// method id "monitoring.projects.dashboards.get":

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

// Get: Fetches a specific dashboard.This method requires the
// monitoring.dashboards.get permission on the specified dashboard. For
// more information, see Google Cloud IAM
// (https://cloud.google.com/iam).
func (r *ProjectsDashboardsService) Get(name string) *ProjectsDashboardsGetCall {
	c := &ProjectsDashboardsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsDashboardsGetCall) Fields(s ...googleapi.Field) *ProjectsDashboardsGetCall {
	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 *ProjectsDashboardsGetCall) IfNoneMatch(entityTag string) *ProjectsDashboardsGetCall {
	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 *ProjectsDashboardsGetCall) Context(ctx context.Context) *ProjectsDashboardsGetCall {
	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 *ProjectsDashboardsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "monitoring.projects.dashboards.get" call.
// Exactly one of *Dashboard or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Dashboard.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 *ProjectsDashboardsGetCall) Do(opts ...googleapi.CallOption) (*Dashboard, 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 := &Dashboard{
		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": "Fetches a specific dashboard.This method requires the monitoring.dashboards.get permission on the specified dashboard. For more information, see Google Cloud IAM (https://cloud.google.com/iam).",
	//   "flatPath": "v1/projects/{projectsId}/dashboards/{dashboardsId}",
	//   "httpMethod": "GET",
	//   "id": "monitoring.projects.dashboards.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the Dashboard. The format is one of:\ndashboards/[DASHBOARD_ID] (for system dashboards)\nprojects/[PROJECT_ID_OR_NUMBER]/dashboards/[DASHBOARD_ID]  (for custom dashboards).",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/dashboards/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "Dashboard"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/monitoring",
	//     "https://www.googleapis.com/auth/monitoring.read"
	//   ]
	// }

}

// method id "monitoring.projects.dashboards.list":

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

// List: Lists the existing dashboards.This method requires the
// monitoring.dashboards.list permission on the specified project. For
// more information, see Google Cloud IAM
// (https://cloud.google.com/iam).
func (r *ProjectsDashboardsService) List(parent string) *ProjectsDashboardsListCall {
	c := &ProjectsDashboardsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": A positive number
// that is the maximum number of results to return. If unspecified, a
// default of 1000 is used.
func (c *ProjectsDashboardsListCall) PageSize(pageSize int64) *ProjectsDashboardsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": If this field is
// not empty then it must contain the nextPageToken value returned by a
// previous call to this method. Using this field causes the method to
// return additional results from the previous method call.
func (c *ProjectsDashboardsListCall) PageToken(pageToken string) *ProjectsDashboardsListCall {
	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 *ProjectsDashboardsListCall) Fields(s ...googleapi.Field) *ProjectsDashboardsListCall {
	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 *ProjectsDashboardsListCall) IfNoneMatch(entityTag string) *ProjectsDashboardsListCall {
	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 *ProjectsDashboardsListCall) Context(ctx context.Context) *ProjectsDashboardsListCall {
	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 *ProjectsDashboardsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDashboardsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200728")
	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, "v1/{+parent}/dashboards")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "monitoring.projects.dashboards.list" call.
// Exactly one of *ListDashboardsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListDashboardsResponse.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 *ProjectsDashboardsListCall) Do(opts ...googleapi.CallOption) (*ListDashboardsResponse, 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 := &ListDashboardsResponse{
		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 the existing dashboards.This method requires the monitoring.dashboards.list permission on the specified project. For more information, see Google Cloud IAM (https://cloud.google.com/iam).",
	//   "flatPath": "v1/projects/{projectsId}/dashboards",
	//   "httpMethod": "GET",
	//   "id": "monitoring.projects.dashboards.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "A positive number that is the maximum number of results to return. If unspecified, a default of 1000 is used.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "If this field is not empty then it must contain the nextPageToken value returned by a previous call to this method. Using this field causes the method to return additional results from the previous method call.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. The scope of the dashboards to list. The format is:\nprojects/[PROJECT_ID_OR_NUMBER]\n",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/dashboards",
	//   "response": {
	//     "$ref": "ListDashboardsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/monitoring",
	//     "https://www.googleapis.com/auth/monitoring.read"
	//   ]
	// }

}

// 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 *ProjectsDashboardsListCall) Pages(ctx context.Context, f func(*ListDashboardsResponse) 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 "monitoring.projects.dashboards.patch":

type ProjectsDashboardsPatchCall struct {
	s          *Service
	name       string
	dashboard  *Dashboard
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Replaces an existing custom dashboard with a new
// definition.This method requires the monitoring.dashboards.update
// permission on the specified dashboard. For more information, see
// Google Cloud IAM (https://cloud.google.com/iam).
func (r *ProjectsDashboardsService) Patch(name string, dashboard *Dashboard) *ProjectsDashboardsPatchCall {
	c := &ProjectsDashboardsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.dashboard = dashboard
	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 *ProjectsDashboardsPatchCall) Fields(s ...googleapi.Field) *ProjectsDashboardsPatchCall {
	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 *ProjectsDashboardsPatchCall) Context(ctx context.Context) *ProjectsDashboardsPatchCall {
	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 *ProjectsDashboardsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsDashboardsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200728")
	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.dashboard)
	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, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "monitoring.projects.dashboards.patch" call.
// Exactly one of *Dashboard or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Dashboard.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 *ProjectsDashboardsPatchCall) Do(opts ...googleapi.CallOption) (*Dashboard, 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 := &Dashboard{
		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": "Replaces an existing custom dashboard with a new definition.This method requires the monitoring.dashboards.update permission on the specified dashboard. For more information, see Google Cloud IAM (https://cloud.google.com/iam).",
	//   "flatPath": "v1/projects/{projectsId}/dashboards/{dashboardsId}",
	//   "httpMethod": "PATCH",
	//   "id": "monitoring.projects.dashboards.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Immutable. The resource name of the dashboard.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/dashboards/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "request": {
	//     "$ref": "Dashboard"
	//   },
	//   "response": {
	//     "$ref": "Dashboard"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/monitoring",
	//     "https://www.googleapis.com/auth/monitoring.write"
	//   ]
	// }

}
