// 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 clouderrorreporting provides access to the Error Reporting API.
//
// For product documentation, see: https://cloud.google.com/error-reporting/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/clouderrorreporting/v1beta1"
//   ...
//   ctx := context.Background()
//   clouderrorreportingService, err := clouderrorreporting.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   clouderrorreportingService, err := clouderrorreporting.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, ...)
//   clouderrorreportingService, err := clouderrorreporting.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package clouderrorreporting // import "google.golang.org/api/clouderrorreporting/v1beta1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint

const apiId = "clouderrorreporting:v1beta1"
const apiName = "clouderrorreporting"
const apiVersion = "v1beta1"
const basePath = "https://clouderrorreporting.googleapis.com/"
const mtlsBasePath = "https://clouderrorreporting.mtls.googleapis.com/"

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

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

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

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

	Projects *ProjectsService
}

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

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Events = NewProjectsEventsService(s)
	rs.GroupStats = NewProjectsGroupStatsService(s)
	rs.Groups = NewProjectsGroupsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Events *ProjectsEventsService

	GroupStats *ProjectsGroupStatsService

	Groups *ProjectsGroupsService
}

func NewProjectsEventsService(s *Service) *ProjectsEventsService {
	rs := &ProjectsEventsService{s: s}
	return rs
}

type ProjectsEventsService struct {
	s *Service
}

func NewProjectsGroupStatsService(s *Service) *ProjectsGroupStatsService {
	rs := &ProjectsGroupStatsService{s: s}
	return rs
}

type ProjectsGroupStatsService struct {
	s *Service
}

func NewProjectsGroupsService(s *Service) *ProjectsGroupsService {
	rs := &ProjectsGroupsService{s: s}
	return rs
}

type ProjectsGroupsService struct {
	s *Service
}

// DeleteEventsResponse: Response message for deleting error events.
type DeleteEventsResponse struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// ErrorContext: A description of the context in which an error
// occurred.
// This data should be provided by the application when reporting an
// error,
// unless the
// error report has been generated automatically from Google App Engine
// logs.
type ErrorContext struct {
	// HttpRequest: The HTTP request which was processed when the error
	// was
	// triggered.
	HttpRequest *HttpRequestContext `json:"httpRequest,omitempty"`

	// ReportLocation: The location in the source code where the decision
	// was made to
	// report the error, usually the place where it was logged.
	// For a logged exception this would be the source line where
	// the
	// exception is logged, usually close to the place where it was
	// caught.
	ReportLocation *SourceLocation `json:"reportLocation,omitempty"`

	// SourceReferences: Source code that was used to build the executable
	// which has
	// caused the given error message.
	SourceReferences []*SourceReference `json:"sourceReferences,omitempty"`

	// User: The user who caused or was affected by the crash.
	// This can be a user ID, an email address, or an arbitrary token
	// that
	// uniquely identifies the user.
	// When sending an error report, leave this field empty if the user was
	// not
	// logged in. In this case the
	// Error Reporting system will use other data, such as remote IP
	// address, to
	// distinguish affected users. See `affected_users_count`
	// in
	// `ErrorGroupStats`.
	User string `json:"user,omitempty"`

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

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

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

// ErrorEvent: An error event which is returned by the Error Reporting
// system.
type ErrorEvent struct {
	// Context: Data about the context in which the error occurred.
	Context *ErrorContext `json:"context,omitempty"`

	// EventTime: Time when the event occurred as provided in the error
	// report.
	// If the report did not contain a timestamp, the time the error was
	// received
	// by the Error Reporting system is used.
	EventTime string `json:"eventTime,omitempty"`

	// Message: The stack trace that was reported or logged by the service.
	Message string `json:"message,omitempty"`

	// ServiceContext: The `ServiceContext` for which this error was
	// reported.
	ServiceContext *ServiceContext `json:"serviceContext,omitempty"`

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

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

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

// ErrorGroup: Description of a group of similar error events.
type ErrorGroup struct {
	// GroupId: Group IDs are unique for a given project. If the same kind
	// of error
	// occurs in different service contexts, it will receive the same group
	// ID.
	GroupId string `json:"groupId,omitempty"`

	// Name: The group resource name.
	// Example: <code>projects/my-project-123/groups/CNSgkpnppqKCUw</code>
	Name string `json:"name,omitempty"`

	// TrackingIssues: Associated tracking issues.
	TrackingIssues []*TrackingIssue `json:"trackingIssues,omitempty"`

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

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

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

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

// ErrorGroupStats: Data extracted for a specific group based on certain
// filter criteria,
// such as a given time period and/or service filter.
type ErrorGroupStats struct {
	// AffectedServices: Service contexts with a non-zero error count for
	// the given filter
	// criteria. This list can be truncated if multiple services are
	// affected.
	// Refer to `num_affected_services` for the total count.
	AffectedServices []*ServiceContext `json:"affectedServices,omitempty"`

	// AffectedUsersCount: Approximate number of affected users in the given
	// group that
	// match the filter criteria.
	// Users are distinguished by data in the `ErrorContext` of
	// the
	// individual error events, such as their login name or their remote
	// IP address in case of HTTP requests.
	// The number of affected users can be zero even if the number of
	// errors is non-zero if no data was provided from which the
	// affected user could be deduced.
	// Users are counted based on data in the request
	// context that was provided in the error report. If more users
	// are
	// implicitly affected, such as due to a crash of the whole
	// service,
	// this is not reflected here.
	AffectedUsersCount int64 `json:"affectedUsersCount,omitempty,string"`

	// Count: Approximate total number of events in the given group that
	// match
	// the filter criteria.
	Count int64 `json:"count,omitempty,string"`

	// FirstSeenTime: Approximate first occurrence that was ever seen for
	// this group
	// and which matches the given filter criteria, ignoring the
	// time_range that was specified in the request.
	FirstSeenTime string `json:"firstSeenTime,omitempty"`

	// Group: Group data that is independent of the filter criteria.
	Group *ErrorGroup `json:"group,omitempty"`

	// LastSeenTime: Approximate last occurrence that was ever seen for this
	// group and
	// which matches the given filter criteria, ignoring the time_range
	// that was specified in the request.
	LastSeenTime string `json:"lastSeenTime,omitempty"`

	// NumAffectedServices: The total number of services with a non-zero
	// error count for the given
	// filter criteria.
	NumAffectedServices int64 `json:"numAffectedServices,omitempty"`

	// Representative: An arbitrary event that is chosen as representative
	// for the whole group.
	// The representative event is intended to be used as a quick preview
	// for
	// the whole group. Events in the group are usually sufficiently
	// similar
	// to each other such that showing an arbitrary representative
	// provides
	// insight into the characteristics of the group as a whole.
	Representative *ErrorEvent `json:"representative,omitempty"`

	// TimedCounts: Approximate number of occurrences over time.
	// Timed counts returned by ListGroups are guaranteed to be:
	//
	// - Inside the requested time interval
	// - Non-overlapping, and
	// - Ordered by ascending time.
	TimedCounts []*TimedCount `json:"timedCounts,omitempty"`

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

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

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

// HttpRequestContext: HTTP request data that is related to a reported
// error.
// This data should be provided by the application when reporting an
// error,
// unless the
// error report has been generated automatically from Google App Engine
// logs.
type HttpRequestContext struct {
	// Method: The type of HTTP request, such as `GET`, `POST`, etc.
	Method string `json:"method,omitempty"`

	// Referrer: The referrer information that is provided with the request.
	Referrer string `json:"referrer,omitempty"`

	// RemoteIp: The IP address from which the request originated.
	// This can be IPv4, IPv6, or a token which is derived from the
	// IP address, depending on the data that has been provided
	// in the error report.
	RemoteIp string `json:"remoteIp,omitempty"`

	// ResponseStatusCode: The HTTP response status code for the request.
	ResponseStatusCode int64 `json:"responseStatusCode,omitempty"`

	// Url: The URL of the request.
	Url string `json:"url,omitempty"`

	// UserAgent: The user agent information that is provided with the
	// request.
	UserAgent string `json:"userAgent,omitempty"`

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

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

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

// ListEventsResponse: Contains a set of requested error events.
type ListEventsResponse struct {
	// ErrorEvents: The error events which match the given request.
	ErrorEvents []*ErrorEvent `json:"errorEvents,omitempty"`

	// NextPageToken: If non-empty, more results are available.
	// Pass this token, along with the same query parameters as the
	// first
	// request, to view the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TimeRangeBegin: The timestamp specifies the start time to which the
	// request was restricted.
	TimeRangeBegin string `json:"timeRangeBegin,omitempty"`

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

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

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

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

// ListGroupStatsResponse: Contains a set of requested error group
// stats.
type ListGroupStatsResponse struct {
	// ErrorGroupStats: The error group stats which match the given request.
	ErrorGroupStats []*ErrorGroupStats `json:"errorGroupStats,omitempty"`

	// NextPageToken: If non-empty, more results are available.
	// Pass this token, along with the same query parameters as the
	// first
	// request, to view the next page of results.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TimeRangeBegin: The timestamp specifies the start time to which the
	// request was restricted.
	// The start time is set based on the requested time range. It may be
	// adjusted
	// to a later time if a project has exceeded the storage quota and older
	// data
	// has been deleted.
	TimeRangeBegin string `json:"timeRangeBegin,omitempty"`

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

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

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

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

// ReportErrorEventResponse: Response for reporting an individual error
// event.
// Data may be added to this message in the future.
type ReportErrorEventResponse struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// ReportedErrorEvent: An error event which is reported to the Error
// Reporting system.
type ReportedErrorEvent struct {
	// Context: Optional. A description of the context in which the error
	// occurred.
	Context *ErrorContext `json:"context,omitempty"`

	// EventTime: Optional. Time when the event occurred.
	// If not provided, the time when the event was received by the
	// Error Reporting system will be used.
	EventTime string `json:"eventTime,omitempty"`

	// Message: Required. The error message.
	// If no `context.reportLocation` is provided, the message must contain
	// a
	// header (typically consisting of the exception type name and an
	// error
	// message) and an exception stack trace in one of the supported
	// programming
	// languages and formats.
	// Supported languages are Java, Python, JavaScript, Ruby, C#, PHP, and
	// Go.
	// Supported stack trace formats are:
	//
	// * **Java**: Must be the return value
	// of
	// [`Throwable.printStackTrace()`](https://docs.oracle.com/javase/7/do
	// cs/api/java/lang/Throwable.html#printStackTrace%28%29).
	// * **Python**: Must be the return value
	// of
	// [`traceback.format_exc()`](https://docs.python.org/2/library/traceb
	// ack.html#traceback.format_exc).
	// * **JavaScript**: Must be the value
	// of
	// [`error.stack`](https://github.com/v8/v8/wiki/Stack-Trace-API) as
	// returned
	// by V8.
	// * **Ruby**: Must contain frames returned
	// by
	// [`Exception.backtrace`](https://ruby-doc.org/core-2.2.0/Exception.h
	// tml#method-i-backtrace).
	// * **C#**: Must be the return value
	// of
	// [`Exception.ToString()`](https://msdn.microsoft.com/en-us/library/s
	// ystem.exception.tostring.aspx).
	// * **PHP**: Must start with `PHP (Notice|Parse error|Fatal
	// error|Warning)`
	// and contain the result
	// of
	// [`(string)$exception`](http://php.net/manual/en/exception.tostring.
	// php).
	// * **Go**: Must be the return value
	// of
	// [`runtime.Stack()`](https://golang.org/pkg/runtime/debug/#Stack).
	Message string `json:"message,omitempty"`

	// ServiceContext: Required. The service context in which this error has
	// occurred.
	ServiceContext *ServiceContext `json:"serviceContext,omitempty"`

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

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

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

// ServiceContext: Describes a running service that sends errors.
// Its version changes over time and multiple versions can run in
// parallel.
type ServiceContext struct {
	// ResourceType: Type of the MonitoredResource. List of possible
	// values:
	// https://cloud.google.com/monitoring/api/resources
	//
	// Value is set automatically for incoming errors and must not be set
	// when
	// reporting errors.
	ResourceType string `json:"resourceType,omitempty"`

	// Service: An identifier of the service, such as the name of
	// the
	// executable, job, or Google App Engine service name. This field is
	// expected
	// to have a low number of values that are relatively stable over time,
	// as
	// opposed to `version`, which can be changed whenever new code is
	// deployed.
	//
	// Contains the service name for error reports extracted from Google
	// App Engine logs or `default` if the App Engine default service is
	// used.
	Service string `json:"service,omitempty"`

	// Version: Represents the source code version that the developer
	// provided,
	// which could represent a version label or a Git SHA-1 hash, for
	// example.
	// For App Engine standard environment, the version is set to the
	// version of
	// the app.
	Version string `json:"version,omitempty"`

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

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

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

// SourceLocation: Indicates a location in the source code of the
// service for which errors are
// reported. `functionName` must be provided by the application when
// reporting
// an error, unless the error report contains a `message` with a
// supported
// exception stack trace. All fields are optional for the later case.
type SourceLocation struct {
	// FilePath: The source code filename, which can include a truncated
	// relative
	// path, or a full path from a production machine.
	FilePath string `json:"filePath,omitempty"`

	// FunctionName: Human-readable name of a function or method.
	// The value can include optional context like the class or package
	// name.
	// For example, `my.package.MyClass.method` in case of Java.
	FunctionName string `json:"functionName,omitempty"`

	// LineNumber: 1-based. 0 indicates that the line number is unknown.
	LineNumber int64 `json:"lineNumber,omitempty"`

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

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

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

// SourceReference: A reference to a particular snapshot of the source
// tree used to build and
// deploy an application.
type SourceReference struct {
	// Repository: Optional. A URI string identifying the
	// repository.
	// Example: "https://github.com/GoogleCloudPlatform/kubernetes.git"
	Repository string `json:"repository,omitempty"`

	// RevisionId: The canonical and persistent identifier of the deployed
	// revision.
	// Example (git): "0035781c50ec7aa23385dc841529ce8a4b70db1b"
	RevisionId string `json:"revisionId,omitempty"`

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

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

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

// TimedCount: The number of errors in a given time period.
// All numbers are approximate since the error events are sampled
// before counting them.
type TimedCount struct {
	// Count: Approximate number of occurrences in the given time period.
	Count int64 `json:"count,omitempty,string"`

	// EndTime: End of the time period to which `count` refers (excluded).
	EndTime string `json:"endTime,omitempty"`

	// StartTime: Start of the time period to which `count` refers
	// (included).
	StartTime string `json:"startTime,omitempty"`

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

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

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

// TrackingIssue: Information related to tracking the progress on
// resolving the error.
type TrackingIssue struct {
	// Url: A URL pointing to a related entry in an issue tracking
	// system.
	// Example: `https://github.com/user/project/issues/4`
	Url string `json:"url,omitempty"`

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

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

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

// method id "clouderrorreporting.projects.deleteEvents":

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

// DeleteEvents: Deletes all error events of a given project.
func (r *ProjectsService) DeleteEvents(projectName string) *ProjectsDeleteEventsCall {
	c := &ProjectsDeleteEventsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectName = projectName
	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 *ProjectsDeleteEventsCall) Fields(s ...googleapi.Field) *ProjectsDeleteEventsCall {
	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 *ProjectsDeleteEventsCall) Context(ctx context.Context) *ProjectsDeleteEventsCall {
	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 *ProjectsDeleteEventsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "clouderrorreporting.projects.deleteEvents" call.
// Exactly one of *DeleteEventsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DeleteEventsResponse.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 *ProjectsDeleteEventsCall) Do(opts ...googleapi.CallOption) (*DeleteEventsResponse, 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 := &DeleteEventsResponse{
		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 all error events of a given project.",
	//   "flatPath": "v1beta1/projects/{projectsId}/events",
	//   "httpMethod": "DELETE",
	//   "id": "clouderrorreporting.projects.deleteEvents",
	//   "parameterOrder": [
	//     "projectName"
	//   ],
	//   "parameters": {
	//     "projectName": {
	//       "description": "Required. The resource name of the Google Cloud Platform project. Written\nas `projects/{projectID}`, where `{projectID}` is the\n[Google Cloud Platform project\nID](https://support.google.com/cloud/answer/6158840).\n\nExample: `projects/my-project-123`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+projectName}/events",
	//   "response": {
	//     "$ref": "DeleteEventsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "clouderrorreporting.projects.events.list":

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

// List: Lists the specified events.
func (r *ProjectsEventsService) List(projectName string) *ProjectsEventsListCall {
	c := &ProjectsEventsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectName = projectName
	return c
}

// GroupId sets the optional parameter "groupId": Required. The group
// for which events shall be returned.
func (c *ProjectsEventsListCall) GroupId(groupId string) *ProjectsEventsListCall {
	c.urlParams_.Set("groupId", groupId)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results to return per response.
func (c *ProjectsEventsListCall) PageSize(pageSize int64) *ProjectsEventsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A
// `next_page_token` provided by a previous response.
func (c *ProjectsEventsListCall) PageToken(pageToken string) *ProjectsEventsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ServiceFilterResourceType sets the optional parameter
// "serviceFilter.resourceType": The exact value to match
// against
// [`ServiceContext.resource_type`](/error-reporting/reference/re
// st/v1beta1/ServiceContext#FIELDS.resource_type).
func (c *ProjectsEventsListCall) ServiceFilterResourceType(serviceFilterResourceType string) *ProjectsEventsListCall {
	c.urlParams_.Set("serviceFilter.resourceType", serviceFilterResourceType)
	return c
}

// ServiceFilterService sets the optional parameter
// "serviceFilter.service": The exact value to match
// against
// [`ServiceContext.service`](/error-reporting/reference/rest/v1b
// eta1/ServiceContext#FIELDS.service).
func (c *ProjectsEventsListCall) ServiceFilterService(serviceFilterService string) *ProjectsEventsListCall {
	c.urlParams_.Set("serviceFilter.service", serviceFilterService)
	return c
}

// ServiceFilterVersion sets the optional parameter
// "serviceFilter.version": The exact value to match
// against
// [`ServiceContext.version`](/error-reporting/reference/rest/v1b
// eta1/ServiceContext#FIELDS.version).
func (c *ProjectsEventsListCall) ServiceFilterVersion(serviceFilterVersion string) *ProjectsEventsListCall {
	c.urlParams_.Set("serviceFilter.version", serviceFilterVersion)
	return c
}

// TimeRangePeriod sets the optional parameter "timeRange.period":
// Restricts the query to the specified time range.
//
// Possible values:
//   "PERIOD_UNSPECIFIED"
//   "PERIOD_1_HOUR"
//   "PERIOD_6_HOURS"
//   "PERIOD_1_DAY"
//   "PERIOD_1_WEEK"
//   "PERIOD_30_DAYS"
func (c *ProjectsEventsListCall) TimeRangePeriod(timeRangePeriod string) *ProjectsEventsListCall {
	c.urlParams_.Set("timeRange.period", timeRangePeriod)
	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 *ProjectsEventsListCall) Fields(s ...googleapi.Field) *ProjectsEventsListCall {
	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 *ProjectsEventsListCall) IfNoneMatch(entityTag string) *ProjectsEventsListCall {
	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 *ProjectsEventsListCall) Context(ctx context.Context) *ProjectsEventsListCall {
	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 *ProjectsEventsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "clouderrorreporting.projects.events.list" call.
// Exactly one of *ListEventsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListEventsResponse.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 *ProjectsEventsListCall) Do(opts ...googleapi.CallOption) (*ListEventsResponse, 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 := &ListEventsResponse{
		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 specified events.",
	//   "flatPath": "v1beta1/projects/{projectsId}/events",
	//   "httpMethod": "GET",
	//   "id": "clouderrorreporting.projects.events.list",
	//   "parameterOrder": [
	//     "projectName"
	//   ],
	//   "parameters": {
	//     "groupId": {
	//       "description": "Required. The group for which events shall be returned.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The maximum number of results to return per response.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. A `next_page_token` provided by a previous response.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectName": {
	//       "description": "Required. The resource name of the Google Cloud Platform project. Written\nas `projects/{projectID}`, where `{projectID}` is the\n[Google Cloud Platform project\nID](https://support.google.com/cloud/answer/6158840).\n\nExample: `projects/my-project-123`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "serviceFilter.resourceType": {
	//       "description": "Optional. The exact value to match against\n[`ServiceContext.resource_type`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.resource_type).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "serviceFilter.service": {
	//       "description": "Optional. The exact value to match against\n[`ServiceContext.service`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.service).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "serviceFilter.version": {
	//       "description": "Optional. The exact value to match against\n[`ServiceContext.version`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.version).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timeRange.period": {
	//       "description": "Restricts the query to the specified time range.",
	//       "enum": [
	//         "PERIOD_UNSPECIFIED",
	//         "PERIOD_1_HOUR",
	//         "PERIOD_6_HOURS",
	//         "PERIOD_1_DAY",
	//         "PERIOD_1_WEEK",
	//         "PERIOD_30_DAYS"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+projectName}/events",
	//   "response": {
	//     "$ref": "ListEventsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsEventsListCall) Pages(ctx context.Context, f func(*ListEventsResponse) 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 "clouderrorreporting.projects.events.report":

type ProjectsEventsReportCall struct {
	s                  *Service
	projectName        string
	reportederrorevent *ReportedErrorEvent
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Report: Report an individual error event.
//
// This endpoint accepts **either** an OAuth token,
// **or** an [API
// key](https://support.google.com/cloud/answer/6158862)
// for authentication. To use an API key, append it to the URL as the
// value of
// a `key` parameter. For
// example:
//
// `POST
// https://clouderrorreporting.googleapis.com/v1beta1/{pr
// ojectName}/events:report?key=123ABC456`
func (r *ProjectsEventsService) Report(projectName string, reportederrorevent *ReportedErrorEvent) *ProjectsEventsReportCall {
	c := &ProjectsEventsReportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectName = projectName
	c.reportederrorevent = reportederrorevent
	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 *ProjectsEventsReportCall) Fields(s ...googleapi.Field) *ProjectsEventsReportCall {
	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 *ProjectsEventsReportCall) Context(ctx context.Context) *ProjectsEventsReportCall {
	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 *ProjectsEventsReportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsEventsReportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200708")
	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.reportederrorevent)
	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, "v1beta1/{+projectName}/events:report")
	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{
		"projectName": c.projectName,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "clouderrorreporting.projects.events.report" call.
// Exactly one of *ReportErrorEventResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ReportErrorEventResponse.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 *ProjectsEventsReportCall) Do(opts ...googleapi.CallOption) (*ReportErrorEventResponse, 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 := &ReportErrorEventResponse{
		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": "Report an individual error event.\n\nThis endpoint accepts **either** an OAuth token,\n**or** an [API key](https://support.google.com/cloud/answer/6158862)\nfor authentication. To use an API key, append it to the URL as the value of\na `key` parameter. For example:\n\n`POST\nhttps://clouderrorreporting.googleapis.com/v1beta1/{projectName}/events:report?key=123ABC456`",
	//   "flatPath": "v1beta1/projects/{projectsId}/events:report",
	//   "httpMethod": "POST",
	//   "id": "clouderrorreporting.projects.events.report",
	//   "parameterOrder": [
	//     "projectName"
	//   ],
	//   "parameters": {
	//     "projectName": {
	//       "description": "Required. The resource name of the Google Cloud Platform project. Written\nas `projects/{projectId}`, where `{projectId}` is the\n[Google Cloud Platform project\nID](https://support.google.com/cloud/answer/6158840).\n\nExample: // `projects/my-project-123`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+projectName}/events:report",
	//   "request": {
	//     "$ref": "ReportedErrorEvent"
	//   },
	//   "response": {
	//     "$ref": "ReportErrorEventResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "clouderrorreporting.projects.groupStats.list":

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

// List: Lists the specified groups.
func (r *ProjectsGroupStatsService) List(projectName string) *ProjectsGroupStatsListCall {
	c := &ProjectsGroupStatsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectName = projectName
	return c
}

// Alignment sets the optional parameter "alignment": The alignment of
// the timed counts to be returned.
// Default is `ALIGNMENT_EQUAL_AT_END`.
//
// Possible values:
//   "ERROR_COUNT_ALIGNMENT_UNSPECIFIED"
//   "ALIGNMENT_EQUAL_ROUNDED"
//   "ALIGNMENT_EQUAL_AT_END"
func (c *ProjectsGroupStatsListCall) Alignment(alignment string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("alignment", alignment)
	return c
}

// AlignmentTime sets the optional parameter "alignmentTime": Time where
// the timed counts shall be aligned if rounded
// alignment is chosen. Default is 00:00 UTC.
func (c *ProjectsGroupStatsListCall) AlignmentTime(alignmentTime string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("alignmentTime", alignmentTime)
	return c
}

// GroupId sets the optional parameter "groupId": List all
// <code>ErrorGroupStats</code> with these IDs.
func (c *ProjectsGroupStatsListCall) GroupId(groupId ...string) *ProjectsGroupStatsListCall {
	c.urlParams_.SetMulti("groupId", append([]string{}, groupId...))
	return c
}

// Order sets the optional parameter "order": The sort order in which
// the results are returned.
// Default is `COUNT_DESC`.
//
// Possible values:
//   "GROUP_ORDER_UNSPECIFIED"
//   "COUNT_DESC"
//   "LAST_SEEN_DESC"
//   "CREATED_DESC"
//   "AFFECTED_USERS_DESC"
func (c *ProjectsGroupStatsListCall) Order(order string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("order", order)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of results to return per response.
// Default is 20.
func (c *ProjectsGroupStatsListCall) PageSize(pageSize int64) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A
// `next_page_token` provided by a previous response. To view
// additional results, pass this token along with the identical
// query
// parameters as the first request.
func (c *ProjectsGroupStatsListCall) PageToken(pageToken string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ServiceFilterResourceType sets the optional parameter
// "serviceFilter.resourceType": The exact value to match
// against
// [`ServiceContext.resource_type`](/error-reporting/reference/re
// st/v1beta1/ServiceContext#FIELDS.resource_type).
func (c *ProjectsGroupStatsListCall) ServiceFilterResourceType(serviceFilterResourceType string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("serviceFilter.resourceType", serviceFilterResourceType)
	return c
}

// ServiceFilterService sets the optional parameter
// "serviceFilter.service": The exact value to match
// against
// [`ServiceContext.service`](/error-reporting/reference/rest/v1b
// eta1/ServiceContext#FIELDS.service).
func (c *ProjectsGroupStatsListCall) ServiceFilterService(serviceFilterService string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("serviceFilter.service", serviceFilterService)
	return c
}

// ServiceFilterVersion sets the optional parameter
// "serviceFilter.version": The exact value to match
// against
// [`ServiceContext.version`](/error-reporting/reference/rest/v1b
// eta1/ServiceContext#FIELDS.version).
func (c *ProjectsGroupStatsListCall) ServiceFilterVersion(serviceFilterVersion string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("serviceFilter.version", serviceFilterVersion)
	return c
}

// TimeRangePeriod sets the optional parameter "timeRange.period":
// Restricts the query to the specified time range.
//
// Possible values:
//   "PERIOD_UNSPECIFIED"
//   "PERIOD_1_HOUR"
//   "PERIOD_6_HOURS"
//   "PERIOD_1_DAY"
//   "PERIOD_1_WEEK"
//   "PERIOD_30_DAYS"
func (c *ProjectsGroupStatsListCall) TimeRangePeriod(timeRangePeriod string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("timeRange.period", timeRangePeriod)
	return c
}

// TimedCountDuration sets the optional parameter "timedCountDuration":
// The preferred duration for a single returned `TimedCount`.
// If not set, no timed counts are returned.
func (c *ProjectsGroupStatsListCall) TimedCountDuration(timedCountDuration string) *ProjectsGroupStatsListCall {
	c.urlParams_.Set("timedCountDuration", timedCountDuration)
	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 *ProjectsGroupStatsListCall) Fields(s ...googleapi.Field) *ProjectsGroupStatsListCall {
	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 *ProjectsGroupStatsListCall) IfNoneMatch(entityTag string) *ProjectsGroupStatsListCall {
	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 *ProjectsGroupStatsListCall) Context(ctx context.Context) *ProjectsGroupStatsListCall {
	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 *ProjectsGroupStatsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "clouderrorreporting.projects.groupStats.list" call.
// Exactly one of *ListGroupStatsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListGroupStatsResponse.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 *ProjectsGroupStatsListCall) Do(opts ...googleapi.CallOption) (*ListGroupStatsResponse, 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 := &ListGroupStatsResponse{
		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 specified groups.",
	//   "flatPath": "v1beta1/projects/{projectsId}/groupStats",
	//   "httpMethod": "GET",
	//   "id": "clouderrorreporting.projects.groupStats.list",
	//   "parameterOrder": [
	//     "projectName"
	//   ],
	//   "parameters": {
	//     "alignment": {
	//       "description": "Optional. The alignment of the timed counts to be returned.\nDefault is `ALIGNMENT_EQUAL_AT_END`.",
	//       "enum": [
	//         "ERROR_COUNT_ALIGNMENT_UNSPECIFIED",
	//         "ALIGNMENT_EQUAL_ROUNDED",
	//         "ALIGNMENT_EQUAL_AT_END"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "alignmentTime": {
	//       "description": "Optional. Time where the timed counts shall be aligned if rounded\nalignment is chosen. Default is 00:00 UTC.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "groupId": {
	//       "description": "Optional. List all \u003ccode\u003eErrorGroupStats\u003c/code\u003e with these IDs.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "order": {
	//       "description": "Optional. The sort order in which the results are returned.\nDefault is `COUNT_DESC`.",
	//       "enum": [
	//         "GROUP_ORDER_UNSPECIFIED",
	//         "COUNT_DESC",
	//         "LAST_SEEN_DESC",
	//         "CREATED_DESC",
	//         "AFFECTED_USERS_DESC"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The maximum number of results to return per response.\nDefault is 20.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. A `next_page_token` provided by a previous response. To view\nadditional results, pass this token along with the identical query\nparameters as the first request.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectName": {
	//       "description": "Required. The resource name of the Google Cloud Platform project. Written\nas `projects/{projectID}`, where `{projectID}` is the\n[Google Cloud Platform project\nID](https://support.google.com/cloud/answer/6158840).\n\nExample: `projects/my-project-123`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "serviceFilter.resourceType": {
	//       "description": "Optional. The exact value to match against\n[`ServiceContext.resource_type`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.resource_type).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "serviceFilter.service": {
	//       "description": "Optional. The exact value to match against\n[`ServiceContext.service`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.service).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "serviceFilter.version": {
	//       "description": "Optional. The exact value to match against\n[`ServiceContext.version`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.version).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timeRange.period": {
	//       "description": "Restricts the query to the specified time range.",
	//       "enum": [
	//         "PERIOD_UNSPECIFIED",
	//         "PERIOD_1_HOUR",
	//         "PERIOD_6_HOURS",
	//         "PERIOD_1_DAY",
	//         "PERIOD_1_WEEK",
	//         "PERIOD_30_DAYS"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timedCountDuration": {
	//       "description": "Optional. The preferred duration for a single returned `TimedCount`.\nIf not set, no timed counts are returned.",
	//       "format": "google-duration",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+projectName}/groupStats",
	//   "response": {
	//     "$ref": "ListGroupStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsGroupStatsListCall) Pages(ctx context.Context, f func(*ListGroupStatsResponse) 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 "clouderrorreporting.projects.groups.get":

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

// Get: Get the specified group.
func (r *ProjectsGroupsService) Get(groupName string) *ProjectsGroupsGetCall {
	c := &ProjectsGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.groupName = groupName
	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 *ProjectsGroupsGetCall) Fields(s ...googleapi.Field) *ProjectsGroupsGetCall {
	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 *ProjectsGroupsGetCall) IfNoneMatch(entityTag string) *ProjectsGroupsGetCall {
	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 *ProjectsGroupsGetCall) Context(ctx context.Context) *ProjectsGroupsGetCall {
	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 *ProjectsGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "clouderrorreporting.projects.groups.get" call.
// Exactly one of *ErrorGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ErrorGroup.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 *ProjectsGroupsGetCall) Do(opts ...googleapi.CallOption) (*ErrorGroup, 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 := &ErrorGroup{
		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": "Get the specified group.",
	//   "flatPath": "v1beta1/projects/{projectsId}/groups/{groupsId}",
	//   "httpMethod": "GET",
	//   "id": "clouderrorreporting.projects.groups.get",
	//   "parameterOrder": [
	//     "groupName"
	//   ],
	//   "parameters": {
	//     "groupName": {
	//       "description": "Required. The group resource name. Written as\n`projects/{projectID}/groups/{group_name}`. Call\n[`groupStats.list`](https://cloud.google.com/error-reporting/reference/rest/v1beta1/projects.groupStats/list)\nto return a list of groups belonging to this project.\n\nExample: `projects/my-project-123/groups/my-group`",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/groups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+groupName}",
	//   "response": {
	//     "$ref": "ErrorGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "clouderrorreporting.projects.groups.update":

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

// Update: Replace the data for the specified group.
// Fails if the group does not exist.
func (r *ProjectsGroupsService) Update(name string, errorgroup *ErrorGroup) *ProjectsGroupsUpdateCall {
	c := &ProjectsGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.errorgroup = errorgroup
	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 *ProjectsGroupsUpdateCall) Fields(s ...googleapi.Field) *ProjectsGroupsUpdateCall {
	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 *ProjectsGroupsUpdateCall) Context(ctx context.Context) *ProjectsGroupsUpdateCall {
	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 *ProjectsGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "clouderrorreporting.projects.groups.update" call.
// Exactly one of *ErrorGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ErrorGroup.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 *ProjectsGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*ErrorGroup, 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 := &ErrorGroup{
		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": "Replace the data for the specified group.\nFails if the group does not exist.",
	//   "flatPath": "v1beta1/projects/{projectsId}/groups/{groupsId}",
	//   "httpMethod": "PUT",
	//   "id": "clouderrorreporting.projects.groups.update",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The group resource name.\nExample: \u003ccode\u003eprojects/my-project-123/groups/CNSgkpnppqKCUw\u003c/code\u003e",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+/groups/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "request": {
	//     "$ref": "ErrorGroup"
	//   },
	//   "response": {
	//     "$ref": "ErrorGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
