// Copyright 2022 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"
	internal "google.golang.org/api/internal"
	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 (
	// See, edit, configure, and delete your Google Cloud data and see the
	// email address for your Google Account.
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := internaloption.WithDefaultScopes(
		"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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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:
	// projects/my-project-123/groups/CNSgkpnppqKCUw
	Name string `json:"name,omitempty"`

	// ResolutionStatus: Error group's resolution status. An unspecified
	// resolution status will be interpreted as OPEN
	//
	// Possible values:
	//   "RESOLUTION_STATUS_UNSPECIFIED" - Status is unknown. When left
	// unspecified in requests, it is treated like OPEN.
	//   "OPEN" - The error group is not being addressed. This is the
	// default for new groups. It is also used for errors re-occurring after
	// marked RESOLVED.
	//   "ACKNOWLEDGED" - Error Group manually acknowledged, it can have an
	// issue link attached.
	//   "RESOLVED" - Error Group manually resolved, more events for this
	// group are not expected to occur.
	//   "MUTED" - The error group is muted and excluded by default on group
	// stats requests.
	ResolutionStatus string `json:"resolutionStatus,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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 is
	// used. If provided, the time must not exceed the logs retention period
	// (https://cloud.google.com/logging/quotas#logs_retention_periods) in
	// the past, or be more than 24 hours in the future. If an invalid time
	// is provided, then an error is returned.
	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/docs/api/java/lang/Throwable.html#printStackTrace%28%29).
	// * **Python**: Must be the return value of `traceback.format_exc()`
	// (https://docs.python.org/2/library/traceback.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.html#method-i-backtrace).
	// * **C#**: Must be the return value of `Exception.ToString()`
	// (https://msdn.microsoft.com/en-us/library/system.exception.tostring.aspx).
	// * **PHP**: Must be prefixed with "PHP (Notice|Parse error|Fatal
	// error|Warning): " and contain the result of `(string)$exception`
	// (https://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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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 or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or 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.
//
// - projectName: The resource name of the Google Cloud Platform
//   project. Written as `projects/{projectID}`, where `{projectID}` is
//   the Google Cloud Platform project ID
//   (https://support.google.com/cloud/answer/6158840). Example:
//   `projects/my-project-123`.
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/"+internal.Version)
	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 as `projects/{projectID}`, where `{projectID}` is the [Google Cloud Platform project ID](https://support.google.com/cloud/answer/6158840). Example: `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.
//
// - projectName: The resource name of the Google Cloud Platform
//   project. Written as `projects/{projectID}`, where `{projectID}` is
//   the Google Cloud Platform project ID
//   (https://support.google.com/cloud/answer/6158840). Example:
//   `projects/my-project-123`.
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/rest/v1beta1/ServiceContext#FIELDS.resourc
// e_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/v1beta1/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/v1beta1/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" - Do not use.
//   "PERIOD_1_HOUR" - Retrieve data for the last hour. Recommended
// minimum timed count duration: 1 min.
//   "PERIOD_6_HOURS" - Retrieve data for the last 6 hours. Recommended
// minimum timed count duration: 10 min.
//   "PERIOD_1_DAY" - Retrieve data for the last day. Recommended
// minimum timed count duration: 1 hour.
//   "PERIOD_1_WEEK" - Retrieve data for the last week. Recommended
// minimum timed count duration: 6 hours.
//   "PERIOD_30_DAYS" - Retrieve data for the last 30 days. Recommended
// minimum timed count duration: 1 day.
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/"+internal.Version)
	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 as `projects/{projectID}`, where `{projectID}` is the [Google Cloud Platform project ID](https://support.google.com/cloud/answer/6158840). Example: `projects/my-project-123`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "serviceFilter.resourceType": {
	//       "description": "Optional. The exact value to match against [`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 [`ServiceContext.service`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.service).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "serviceFilter.version": {
	//       "description": "Optional. The exact value to match against [`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"
	//       ],
	//       "enumDescriptions": [
	//         "Do not use.",
	//         "Retrieve data for the last hour. Recommended minimum timed count duration: 1 min.",
	//         "Retrieve data for the last 6 hours. Recommended minimum timed count duration: 10 min.",
	//         "Retrieve data for the last day. Recommended minimum timed count duration: 1 hour.",
	//         "Retrieve data for the last week. Recommended minimum timed count duration: 6 hours.",
	//         "Retrieve data for the last 30 days. Recommended minimum timed count duration: 1 day."
	//       ],
	//       "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 and record the event to a
// log. 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/{projectName}/events:report?key=123ABC456`
// **Note:** [Error Reporting]
// (https://cloud.google.com/error-reporting) is a global service built
// on Cloud Logging and doesn't analyze logs stored in regional log
// buckets or logs routed to other Google Cloud projects. For more
// information, see [Using Error Reporting with regionalized logs]
// (https://cloud.google.com/error-reporting/docs/regionalization).
//
// - projectName: The resource name of the Google Cloud Platform
//   project. Written as `projects/{projectId}`, where `{projectId}` is
//   the Google Cloud Platform project ID
//   (https://support.google.com/cloud/answer/6158840). Example: //
//   `projects/my-project-123`.
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/"+internal.Version)
	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 and record the event to a log. 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/{projectName}/events:report?key=123ABC456` **Note:** [Error Reporting] (https://cloud.google.com/error-reporting) is a global service built on Cloud Logging and doesn't analyze logs stored in regional log buckets or logs routed to other Google Cloud projects. For more information, see [Using Error Reporting with regionalized logs] (https://cloud.google.com/error-reporting/docs/regionalization).",
	//   "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 as `projects/{projectId}`, where `{projectId}` is the [Google Cloud Platform project ID](https://support.google.com/cloud/answer/6158840). Example: // `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.
//
// - projectName: The resource name of the Google Cloud Platform
//   project. Written as `projects/{projectID}` or
//   `projects/{projectNumber}`, where `{projectID}` and
//   `{projectNumber}` can be found in the Google Cloud Console
//   (https://support.google.com/cloud/answer/6158840). Examples:
//   `projects/my-project-123`, `projects/5551234`.
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" - No alignment specified.
//   "ALIGNMENT_EQUAL_ROUNDED" - The time periods shall be consecutive,
// have width equal to the requested duration, and be aligned at the
// alignment_time provided in the request. The alignment_time does not
// have to be inside the query period but even if it is outside, only
// time periods are returned which overlap with the query period. A
// rounded alignment will typically result in a different size of the
// first or the last time period.
//   "ALIGNMENT_EQUAL_AT_END" - The time periods shall be consecutive,
// have width equal to the requested duration, and be aligned at the end
// of the requested time period. This can result in a different size of
// the first time period.
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
// ErrorGroupStats 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" - No group order specified.
//   "COUNT_DESC" - Total count of errors in the given time window in
// descending order.
//   "LAST_SEEN_DESC" - Timestamp when the group was last seen in the
// given time window in descending order.
//   "CREATED_DESC" - Timestamp when the group was created in descending
// order.
//   "AFFECTED_USERS_DESC" - Number of affected users in the given time
// window in descending order.
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/rest/v1beta1/ServiceContext#FIELDS.resourc
// e_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/v1beta1/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/v1beta1/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" - Do not use.
//   "PERIOD_1_HOUR" - Retrieve data for the last hour. Recommended
// minimum timed count duration: 1 min.
//   "PERIOD_6_HOURS" - Retrieve data for the last 6 hours. Recommended
// minimum timed count duration: 10 min.
//   "PERIOD_1_DAY" - Retrieve data for the last day. Recommended
// minimum timed count duration: 1 hour.
//   "PERIOD_1_WEEK" - Retrieve data for the last week. Recommended
// minimum timed count duration: 6 hours.
//   "PERIOD_30_DAYS" - Retrieve data for the last 30 days. Recommended
// minimum timed count duration: 1 day.
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/"+internal.Version)
	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. Default is `ALIGNMENT_EQUAL_AT_END`.",
	//       "enum": [
	//         "ERROR_COUNT_ALIGNMENT_UNSPECIFIED",
	//         "ALIGNMENT_EQUAL_ROUNDED",
	//         "ALIGNMENT_EQUAL_AT_END"
	//       ],
	//       "enumDescriptions": [
	//         "No alignment specified.",
	//         "The time periods shall be consecutive, have width equal to the requested duration, and be aligned at the alignment_time provided in the request. The alignment_time does not have to be inside the query period but even if it is outside, only time periods are returned which overlap with the query period. A rounded alignment will typically result in a different size of the first or the last time period.",
	//         "The time periods shall be consecutive, have width equal to the requested duration, and be aligned at the end of the requested time period. This can result in a different size of the first time period."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "alignmentTime": {
	//       "description": "Optional. Time where the timed counts shall be aligned if rounded alignment is chosen. Default is 00:00 UTC.",
	//       "format": "google-datetime",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "groupId": {
	//       "description": "Optional. List all ErrorGroupStats with these IDs.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "order": {
	//       "description": "Optional. The sort order in which the results are returned. Default is `COUNT_DESC`.",
	//       "enum": [
	//         "GROUP_ORDER_UNSPECIFIED",
	//         "COUNT_DESC",
	//         "LAST_SEEN_DESC",
	//         "CREATED_DESC",
	//         "AFFECTED_USERS_DESC"
	//       ],
	//       "enumDescriptions": [
	//         "No group order specified.",
	//         "Total count of errors in the given time window in descending order.",
	//         "Timestamp when the group was last seen in the given time window in descending order.",
	//         "Timestamp when the group was created in descending order.",
	//         "Number of affected users in the given time window in descending order."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "Optional. The maximum number of results to return per response. Default is 20.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. 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.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "projectName": {
	//       "description": "Required. The resource name of the Google Cloud Platform project. Written as `projects/{projectID}` or `projects/{projectNumber}`, where `{projectID}` and `{projectNumber}` can be found in the [Google Cloud Console](https://support.google.com/cloud/answer/6158840). Examples: `projects/my-project-123`, `projects/5551234`.",
	//       "location": "path",
	//       "pattern": "^projects/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "serviceFilter.resourceType": {
	//       "description": "Optional. The exact value to match against [`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 [`ServiceContext.service`](/error-reporting/reference/rest/v1beta1/ServiceContext#FIELDS.service).",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "serviceFilter.version": {
	//       "description": "Optional. The exact value to match against [`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"
	//       ],
	//       "enumDescriptions": [
	//         "Do not use.",
	//         "Retrieve data for the last hour. Recommended minimum timed count duration: 1 min.",
	//         "Retrieve data for the last 6 hours. Recommended minimum timed count duration: 10 min.",
	//         "Retrieve data for the last day. Recommended minimum timed count duration: 1 hour.",
	//         "Retrieve data for the last week. Recommended minimum timed count duration: 6 hours.",
	//         "Retrieve data for the last 30 days. Recommended minimum timed count duration: 1 day."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "timedCountDuration": {
	//       "description": "Optional. The preferred duration for a single returned TimedCount. If 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.
//
// - groupName: The group resource name. Written as
//   `projects/{projectID}/groups/{group_name}`. Call groupStats.list to
//   return a list of groups belonging to this project. Example:
//   `projects/my-project-123/groups/my-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/"+internal.Version)
	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 `projects/{projectID}/groups/{group_name}`. Call groupStats.list to return a list of groups belonging to this project. Example: `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.
//
// - name: The group resource name. Example:
//   projects/my-project-123/groups/CNSgkpnppqKCUw.
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/"+internal.Version)
	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. Fails 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. Example: projects/my-project-123/groups/CNSgkpnppqKCUw",
	//       "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"
	//   ]
	// }

}
