// 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 Stackdriver Monitoring API.
//
// This package is DEPRECATED. Use package cloud.google.com/go/monitoring/apiv3 instead.
//
// 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"
	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

const apiId = "monitoring:v1"
const apiName = "monitoring"
const apiVersion = "v1"
const basePath = "https://monitoring.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...)
	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 Aggregating Time Series.
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.
	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: 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: 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: 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 which were dropped
// during aggregation, attached to google.api.Distribution.Exemplars in
// google.api.Distribution values during aggregation.These values are
// used in combination with the label values that remain on the
// aggregated Distribution timeseries to construct the full label set
// for the exemplar values. The resulting full label set may be used to
// identify the specific task/job/instance (for example) which may be
// contributing to a long-tail, while allowing the storage savings of
// only storing aggregated distribution values for a large group.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 pageToken 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 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: 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
// google.api.Distribution.Exemplars in google.api.Distribution values
// during aggregation.It contains the name of a span with format:
// projects/PROJECT_ID/traces/TRACE_ID/spans/SPAN_ID
type SpanContext struct {
	// SpanName: The resource name of the span in the following
	// format:
	// projects/[PROJECT_ID]/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: 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)
}

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

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

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

	// 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 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: 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/1.13.7 gdcl/20200203")
	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 \"projects/{project_id_or_number}\". The {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/1.13.7 gdcl/20200203")
	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 \"projects/{project_id_or_number}/dashboards/{dashboard_id}\".",
	//       "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/1.13.7 gdcl/20200203")
	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 \"dashboards/{dashboard_id}\" (for system dashboards) or \"projects/{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/1.13.7 gdcl/20200203")
	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. A project scope must be specified in the form of \"projects/{project_id_or_number}\".",
	//       "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/1.13.7 gdcl/20200203")
	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": "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"
	//   ]
	// }

}
