// 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 analyticsdata provides access to the Google Analytics Data API.
//
// For product documentation, see: https://developers.google.com/analytics/trusted-testing/analytics-data/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/analyticsdata/v1alpha"
//   ...
//   ctx := context.Background()
//   analyticsdataService, err := analyticsdata.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   analyticsdataService, err := analyticsdata.NewService(ctx, option.WithScopes(analyticsdata.AnalyticsReadonlyScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   analyticsdataService, err := analyticsdata.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, ...)
//   analyticsdataService, err := analyticsdata.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package analyticsdata // import "google.golang.org/api/analyticsdata/v1alpha"

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

// OAuth2 scopes used by this API.
const (
	// View and manage your Google Analytics data
	AnalyticsScope = "https://www.googleapis.com/auth/analytics"

	// View your Google Analytics data
	AnalyticsReadonlyScope = "https://www.googleapis.com/auth/analytics.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/analytics",
		"https://www.googleapis.com/auth/analytics.readonly",
	)
	// 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.Properties = NewPropertiesService(s)
	s.V1alpha = NewV1alphaService(s)
	return s, nil
}

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

	Properties *PropertiesService

	V1alpha *V1alphaService
}

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

func NewPropertiesService(s *Service) *PropertiesService {
	rs := &PropertiesService{s: s}
	return rs
}

type PropertiesService struct {
	s *Service
}

func NewV1alphaService(s *Service) *V1alphaService {
	rs := &V1alphaService{s: s}
	return rs
}

type V1alphaService struct {
	s *Service
}

// BatchRunPivotReportsRequest: The batch request containing multiple
// pivot report requests.
type BatchRunPivotReportsRequest struct {
	// Entity: A property whose events are tracked. This entity must be
	// specified for the batch. The entity within RunPivotReportRequest may
	// either be unspecified or consistent with this entity.
	Entity *Entity `json:"entity,omitempty"`

	// Requests: Individual requests. Each request has a separate pivot
	// report response. Each batch request is allowed up to 5 requests.
	Requests []*RunPivotReportRequest `json:"requests,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Entity") 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. "Entity") 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 *BatchRunPivotReportsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod BatchRunPivotReportsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BatchRunPivotReportsResponse: The batch response containing multiple
// pivot reports.
type BatchRunPivotReportsResponse struct {
	// PivotReports: Individual responses. Each response has a separate
	// pivot report request.
	PivotReports []*RunPivotReportResponse `json:"pivotReports,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "PivotReports") 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. "PivotReports") 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 *BatchRunPivotReportsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BatchRunPivotReportsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BatchRunReportsRequest: The batch request containing multiple report
// requests.
type BatchRunReportsRequest struct {
	// Entity: A property whose events are tracked. This entity must be
	// specified for the batch. The entity within RunReportRequest may
	// either be unspecified or consistent with this entity.
	Entity *Entity `json:"entity,omitempty"`

	// Requests: Individual requests. Each request has a separate report
	// response. Each batch request is allowed up to 5 requests.
	Requests []*RunReportRequest `json:"requests,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Entity") 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. "Entity") 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 *BatchRunReportsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod BatchRunReportsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BatchRunReportsResponse: The batch response containing multiple
// reports.
type BatchRunReportsResponse struct {
	// Reports: Individual responses. Each response has a separate report
	// request.
	Reports []*RunReportResponse `json:"reports,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Reports") 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. "Reports") 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 *BatchRunReportsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BatchRunReportsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BetweenFilter: To express that the result needs to be between two
// numbers (inclusive).
type BetweenFilter struct {
	// FromValue: Begins with this number.
	FromValue *NumericValue `json:"fromValue,omitempty"`

	// ToValue: Ends with this number.
	ToValue *NumericValue `json:"toValue,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FromValue") 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. "FromValue") 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 *BetweenFilter) MarshalJSON() ([]byte, error) {
	type NoMethod BetweenFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CaseExpression: Used to convert a dimension value to a single case.
type CaseExpression struct {
	// DimensionName: Name of a dimension. The name must refer back to a
	// name in dimensions field of the request.
	DimensionName string `json:"dimensionName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionName") 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. "DimensionName") 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 *CaseExpression) MarshalJSON() ([]byte, error) {
	type NoMethod CaseExpression
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Cohort: Defines a cohort. A cohort is a group of users who share a
// common characteristic. For example, all users with the same
// acquisition date belong to the same cohort.
type Cohort struct {
	// DateRange: The cohort selects users whose first visit date is between
	// start date and end date defined in the `dateRange`. In a cohort
	// request, this `dateRange` is required and the `dateRanges` in the
	// `RunReportRequest` or `RunPivotReportRequest` must be unspecified.
	// The date range should be aligned with the cohort's granularity. If
	// CohortsRange uses daily granularity, the date range can be aligned to
	// any day. If CohortsRange uses weekly granularity, the date range
	// should be aligned to the week boundary, starting at Sunday and ending
	// Saturday. If CohortsRange uses monthly granularity, the date range
	// should be aligned to the month, starting at the first and ending on
	// the last day of the month.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Dimension: The dimension used by cohort. Only supports
	// `firstTouchDate` for retention report.
	Dimension string `json:"dimension,omitempty"`

	// Name: Assigns a name to this cohort. The dimension `cohort` is valued
	// to this name in a report response. If set, cannot begin with
	// `cohort_` or `RESERVED_`. If not set, cohorts are named by their zero
	// based index `cohort_0`, `cohort_1`, etc.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DateRange") 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. "DateRange") 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 *Cohort) MarshalJSON() ([]byte, error) {
	type NoMethod Cohort
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CohortReportSettings: Settings of a cohort report.
type CohortReportSettings struct {
	// Accumulate: If true, accumulates the result from first visit day to
	// the end day. Not supported in `RunReportRequest`.
	Accumulate bool `json:"accumulate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Accumulate") 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. "Accumulate") 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 *CohortReportSettings) MarshalJSON() ([]byte, error) {
	type NoMethod CohortReportSettings
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CohortSpec: Specification for a cohort report.
type CohortSpec struct {
	// CohortReportSettings: Settings of a cohort report.
	CohortReportSettings *CohortReportSettings `json:"cohortReportSettings,omitempty"`

	// Cohorts: The definition for the cohorts.
	Cohorts []*Cohort `json:"cohorts,omitempty"`

	// CohortsRange: The data ranges of cohorts.
	CohortsRange *CohortsRange `json:"cohortsRange,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "CohortReportSettings") 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. "CohortReportSettings") 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 *CohortSpec) MarshalJSON() ([]byte, error) {
	type NoMethod CohortSpec
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CohortsRange: Describes date range for a cohort report.
type CohortsRange struct {
	// EndOffset: For daily cohorts, this will be the end day offset. For
	// weekly cohorts, this will be the week offset.
	EndOffset int64 `json:"endOffset,omitempty"`

	// Granularity: Reporting date range for each cohort is calculated based
	// on these three fields.
	//
	// Possible values:
	//   "GRANULARITY_UNSPECIFIED" - Unspecified.
	//   "DAILY" - Daily
	//   "WEEKLY" - Weekly
	//   "MONTHLY" - Monthly
	Granularity string `json:"granularity,omitempty"`

	// StartOffset: For daily cohorts, this will be the start day offset.
	// For weekly cohorts, this will be the week offset.
	StartOffset int64 `json:"startOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndOffset") 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. "EndOffset") 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 *CohortsRange) MarshalJSON() ([]byte, error) {
	type NoMethod CohortsRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ConcatenateExpression: Used to combine dimension values to a single
// dimension.
type ConcatenateExpression struct {
	// Delimiter: The delimiter placed between dimension names. Delimiters
	// are often single characters such as "|" or "," but can be longer
	// strings. If a dimension value contains the delimiter, both will be
	// present in response with no distinction. For example if dimension 1
	// value = "US,FR", dimension 2 value = "JP", and delimiter = ",", then
	// the response will contain "US,FR,JP".
	Delimiter string `json:"delimiter,omitempty"`

	// DimensionNames: Names of dimensions. The names must refer back to
	// names in the dimensions field of the request.
	DimensionNames []string `json:"dimensionNames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Delimiter") 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. "Delimiter") 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 *ConcatenateExpression) MarshalJSON() ([]byte, error) {
	type NoMethod ConcatenateExpression
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DateRange: A contiguous set of days: startDate, startDate + 1, ...,
// endDate. Requests are allowed up to 4 date ranges, and the union of
// the ranges can cover up to 1 year.
type DateRange struct {
	// EndDate: The inclusive end date for the query in the format
	// `YYYY-MM-DD`. Cannot be before `start_date`. The format `NdaysAgo`,
	// `yesterday`, or `today` is also accepted, and in that case, the date
	// is inferred based on the property's reporting time zone.
	EndDate string `json:"endDate,omitempty"`

	// Name: Assigns a name to this date range. The dimension `dateRange` is
	// valued to this name in a report response. If set, cannot begin with
	// `date_range_` or `RESERVED_`. If not set, date ranges are named by
	// their zero based index in the request: `date_range_0`,
	// `date_range_1`, etc.
	Name string `json:"name,omitempty"`

	// StartDate: The inclusive start date for the query in the format
	// `YYYY-MM-DD`. Cannot be after `end_date`. The format `NdaysAgo`,
	// `yesterday`, or `today` is also accepted, and in that case, the date
	// is inferred based on the property's reporting time zone.
	StartDate string `json:"startDate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndDate") 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. "EndDate") 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 *DateRange) MarshalJSON() ([]byte, error) {
	type NoMethod DateRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Dimension: Dimensions are attributes of your data. For example, the
// dimension City indicates the city, for example, "Paris" or "New
// York", from which an event originates. Requests are allowed up to 8
// dimensions.
type Dimension struct {
	// DimensionExpression: One dimension can be the result of an expression
	// of multiple dimensions. For example, dimension "country, city":
	// concatenate(country, ", ", city).
	DimensionExpression *DimensionExpression `json:"dimensionExpression,omitempty"`

	// Name: The name of the dimension.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionExpression")
	// 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. "DimensionExpression") 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 *Dimension) MarshalJSON() ([]byte, error) {
	type NoMethod Dimension
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DimensionExpression: Used to express a dimension which is the result
// of a formula of multiple dimensions. Example usages: 1)
// lower_case(dimension) 2) concatenate(dimension1, symbol, dimension2).
type DimensionExpression struct {
	// Concatenate: Used to combine dimension values to a single dimension.
	// For example, dimension "country, city": concatenate(country, ", ",
	// city).
	Concatenate *ConcatenateExpression `json:"concatenate,omitempty"`

	// LowerCase: Used to convert a dimension value to lower case.
	LowerCase *CaseExpression `json:"lowerCase,omitempty"`

	// UpperCase: Used to convert a dimension value to upper case.
	UpperCase *CaseExpression `json:"upperCase,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Concatenate") 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. "Concatenate") 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 *DimensionExpression) MarshalJSON() ([]byte, error) {
	type NoMethod DimensionExpression
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DimensionHeader: Describes a dimension column in the report.
// Dimensions requested in a report produce column entries within rows
// and DimensionHeaders. However, dimensions used exclusively within
// filters or expressions do not produce columns in a report;
// correspondingly, those dimensions do not produce headers.
type DimensionHeader struct {
	// Name: The dimension's name.
	Name string `json:"name,omitempty"`

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

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

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

// DimensionMetadata: Explains a dimension.
type DimensionMetadata struct {
	// ApiName: This dimension's name. Useable in [Dimension](#Dimension)'s
	// `name`. For example, `eventName`.
	ApiName string `json:"apiName,omitempty"`

	// DeprecatedApiNames: Still usable but deprecated names for this
	// dimension. If populated, this dimension is available by either
	// `apiName` or one of `deprecatedApiNames` for a period of time. After
	// the deprecation period, the dimension will be available only by
	// `apiName`.
	DeprecatedApiNames []string `json:"deprecatedApiNames,omitempty"`

	// Description: Description of how this dimension is used and
	// calculated.
	Description string `json:"description,omitempty"`

	// UiName: This dimension's name within the Google Analytics user
	// interface. For example, `Event name`.
	UiName string `json:"uiName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApiName") 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. "ApiName") 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 *DimensionMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod DimensionMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DimensionOrderBy: Sorts by dimension values.
type DimensionOrderBy struct {
	// DimensionName: A dimension name in the request to order by.
	DimensionName string `json:"dimensionName,omitempty"`

	// OrderType: Controls the rule for dimension value ordering.
	//
	// Possible values:
	//   "ORDER_TYPE_UNSPECIFIED" - Unspecified.
	//   "ALPHANUMERIC" - Alphanumeric sort by Unicode code point. For
	// example, "2" < "A" < "X" < "b" < "z".
	//   "CASE_INSENSITIVE_ALPHANUMERIC" - Case insensitive alphanumeric
	// sort by lower case Unicode code point. For example, "2" < "A" < "b" <
	// "X" < "z".
	//   "NUMERIC" - Dimension values are converted to numbers before
	// sorting. For example in NUMERIC sort, "25" < "100", and in
	// `ALPHANUMERIC` sort, "100" < "25". Non-numeric dimension values all
	// have equal ordering value below all numeric values.
	OrderType string `json:"orderType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionName") 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. "DimensionName") 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 *DimensionOrderBy) MarshalJSON() ([]byte, error) {
	type NoMethod DimensionOrderBy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DimensionValue: The value of a dimension.
type DimensionValue struct {
	// Value: Value as a string if the dimension type is a string.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Value") 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. "Value") 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 *DimensionValue) MarshalJSON() ([]byte, error) {
	type NoMethod DimensionValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Entity: The unique identifier of the property whose events are
// tracked.
type Entity struct {
	// PropertyId: A Google Analytics GA4 property id.
	PropertyId string `json:"propertyId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PropertyId") 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. "PropertyId") 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 *Entity) MarshalJSON() ([]byte, error) {
	type NoMethod Entity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Filter: An expression to filter dimension or metric values.
type Filter struct {
	// BetweenFilter: A filter for two values.
	BetweenFilter *BetweenFilter `json:"betweenFilter,omitempty"`

	// FieldName: The dimension name or metric name. Must be a name defined
	// in dimensions or metrics.
	FieldName string `json:"fieldName,omitempty"`

	// InListFilter: A filter for in list values.
	InListFilter *InListFilter `json:"inListFilter,omitempty"`

	// NullFilter: A filter for null values.
	NullFilter bool `json:"nullFilter,omitempty"`

	// NumericFilter: A filter for numeric or date values.
	NumericFilter *NumericFilter `json:"numericFilter,omitempty"`

	// StringFilter: Strings related filter.
	StringFilter *StringFilter `json:"stringFilter,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BetweenFilter") 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. "BetweenFilter") 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 *Filter) MarshalJSON() ([]byte, error) {
	type NoMethod Filter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FilterExpression: To express dimension or metric filters. The fields
// in the same FilterExpression need to be either all dimensions or all
// metrics.
type FilterExpression struct {
	// AndGroup: The FilterExpressions in and_group have an AND
	// relationship.
	AndGroup *FilterExpressionList `json:"andGroup,omitempty"`

	// Filter: A primitive filter. All fields in filter in same
	// FilterExpression needs to be either all dimensions or metrics.
	Filter *Filter `json:"filter,omitempty"`

	// NotExpression: The FilterExpression is NOT of not_expression.
	NotExpression *FilterExpression `json:"notExpression,omitempty"`

	// OrGroup: The FilterExpressions in or_group have an OR relationship.
	OrGroup *FilterExpressionList `json:"orGroup,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AndGroup") 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. "AndGroup") 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 *FilterExpression) MarshalJSON() ([]byte, error) {
	type NoMethod FilterExpression
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FilterExpressionList: A list of filter expressions.
type FilterExpressionList struct {
	// Expressions: A list of filter expressions.
	Expressions []*FilterExpression `json:"expressions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Expressions") 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. "Expressions") 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 *FilterExpressionList) MarshalJSON() ([]byte, error) {
	type NoMethod FilterExpressionList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InListFilter: The result needs to be in a list of string values.
type InListFilter struct {
	// CaseSensitive: If true, the string value is case sensitive.
	CaseSensitive bool `json:"caseSensitive,omitempty"`

	// Values: The list of string values. Must be non-empty.
	Values []string `json:"values,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CaseSensitive") 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. "CaseSensitive") 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 *InListFilter) MarshalJSON() ([]byte, error) {
	type NoMethod InListFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Metadata: The dimensions and metrics currently accepted in reporting
// methods.
type Metadata struct {
	// Dimensions: The dimension descriptions.
	Dimensions []*DimensionMetadata `json:"dimensions,omitempty"`

	// Metrics: The metric descriptions.
	Metrics []*MetricMetadata `json:"metrics,omitempty"`

	// Name: Resource name of this metadata.
	Name string `json:"name,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Dimensions") 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. "Dimensions") 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 *Metadata) MarshalJSON() ([]byte, error) {
	type NoMethod Metadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Metric: The quantitative measurements of a report. For example, the
// metric eventCount is the total number of events. Requests are allowed
// up to 10 metrics.
type Metric struct {
	// Expression: A mathematical expression for derived metrics. For
	// example, the metric Event count per user is eventCount/totalUsers.
	Expression string `json:"expression,omitempty"`

	// Invisible: Indicates if a metric is invisible. If a metric is
	// invisible, the metric is not in the response, but can be used in
	// filters, order_bys or being referred to in a metric expression.
	Invisible bool `json:"invisible,omitempty"`

	// Name: The name of the metric.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Expression") 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. "Expression") 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 *Metric) MarshalJSON() ([]byte, error) {
	type NoMethod Metric
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MetricHeader: Describes a metric column in the report. Visible
// metrics requested in a report produce column entries within rows and
// MetricHeaders. However, metrics used exclusively within filters or
// expressions do not produce columns in a report; correspondingly,
// those metrics do not produce headers.
type MetricHeader struct {
	// Name: The metric's name.
	Name string `json:"name,omitempty"`

	// Type: The metric's data type.
	//
	// Possible values:
	//   "METRIC_TYPE_UNSPECIFIED" - Unspecified type.
	//   "TYPE_INTEGER" - Integer type.
	//   "TYPE_FLOAT" - Floating point type.
	//   "TYPE_SECONDS" - A duration of seconds; a special floating point
	// type.
	//   "TYPE_MILLISECONDS" - A duration in milliseconds; a special
	// floating point type.
	//   "TYPE_MINUTES" - A duration in minutes; a special floating point
	// type.
	//   "TYPE_HOURS" - A duration in hours; a special floating point type.
	//   "TYPE_STANDARD" - A custom metric of standard type; a special
	// floating point type.
	//   "TYPE_CURRENCY" - An amount of money; a special floating point
	// type.
	//   "TYPE_FEET" - A length in feet; a special floating point type.
	//   "TYPE_MILES" - A length in miles; a special floating point type.
	//   "TYPE_METERS" - A length in meters; a special floating point type.
	//   "TYPE_KILOMETERS" - A length in kilometers; a special floating
	// point type.
	Type string `json:"type,omitempty"`

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

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

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

// MetricMetadata: Explains a metric.
type MetricMetadata struct {
	// ApiName: A metric name. Useable in [Metric](#Metric)'s `name`. For
	// example, `eventCount`.
	ApiName string `json:"apiName,omitempty"`

	// DeprecatedApiNames: Still usable but deprecated names for this
	// metric. If populated, this metric is available by either `apiName` or
	// one of `deprecatedApiNames` for a period of time. After the
	// deprecation period, the metric will be available only by `apiName`.
	DeprecatedApiNames []string `json:"deprecatedApiNames,omitempty"`

	// Description: Description of how this metric is used and calculated.
	Description string `json:"description,omitempty"`

	// Expression: The mathematical expression for this derived metric. Can
	// be used in [Metric](#Metric)'s `expression` field for equivalent
	// reports. Most metrics are not expressions, and for non-expressions,
	// this field is empty.
	Expression string `json:"expression,omitempty"`

	// Type: The type of this metric.
	//
	// Possible values:
	//   "METRIC_TYPE_UNSPECIFIED" - Unspecified type.
	//   "TYPE_INTEGER" - Integer type.
	//   "TYPE_FLOAT" - Floating point type.
	//   "TYPE_SECONDS" - A duration of seconds; a special floating point
	// type.
	//   "TYPE_MILLISECONDS" - A duration in milliseconds; a special
	// floating point type.
	//   "TYPE_MINUTES" - A duration in minutes; a special floating point
	// type.
	//   "TYPE_HOURS" - A duration in hours; a special floating point type.
	//   "TYPE_STANDARD" - A custom metric of standard type; a special
	// floating point type.
	//   "TYPE_CURRENCY" - An amount of money; a special floating point
	// type.
	//   "TYPE_FEET" - A length in feet; a special floating point type.
	//   "TYPE_MILES" - A length in miles; a special floating point type.
	//   "TYPE_METERS" - A length in meters; a special floating point type.
	//   "TYPE_KILOMETERS" - A length in kilometers; a special floating
	// point type.
	Type string `json:"type,omitempty"`

	// UiName: This metric's name within the Google Analytics user
	// interface. For example, `Event count`.
	UiName string `json:"uiName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApiName") 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. "ApiName") 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 *MetricMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod MetricMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MetricOrderBy: Sorts by metric values.
type MetricOrderBy struct {
	// MetricName: A metric name in the request to order by.
	MetricName string `json:"metricName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MetricName") 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. "MetricName") 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 *MetricOrderBy) MarshalJSON() ([]byte, error) {
	type NoMethod MetricOrderBy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MetricValue: The value of a metric.
type MetricValue struct {
	// Value: Measurement value. See MetricHeader for type.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Value") 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. "Value") 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 *MetricValue) MarshalJSON() ([]byte, error) {
	type NoMethod MetricValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NumericFilter: Filters for numeric or date values.
type NumericFilter struct {
	// Operation: The operation type for this filter.
	//
	// Possible values:
	//   "OPERATION_UNSPECIFIED" - Unspecified.
	//   "EQUAL" - Equal
	//   "LESS_THAN" - Less than
	//   "LESS_THAN_OR_EQUAL" - Less than or equal
	//   "GREATER_THAN" - Greater than
	//   "GREATER_THAN_OR_EQUAL" - Greater than or equal
	Operation string `json:"operation,omitempty"`

	// Value: A numeric value or a date value.
	Value *NumericValue `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Operation") 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. "Operation") 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 *NumericFilter) MarshalJSON() ([]byte, error) {
	type NoMethod NumericFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NumericValue: To represent a number.
type NumericValue struct {
	// DoubleValue: Double value
	DoubleValue float64 `json:"doubleValue,omitempty"`

	// Int64Value: Integer value
	Int64Value int64 `json:"int64Value,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "DoubleValue") 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. "DoubleValue") 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 *NumericValue) MarshalJSON() ([]byte, error) {
	type NoMethod NumericValue
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// OrderBy: The sort options.
type OrderBy struct {
	// Desc: If true, sorts by descending order.
	Desc bool `json:"desc,omitempty"`

	// Dimension: Sorts results by a dimension's values.
	Dimension *DimensionOrderBy `json:"dimension,omitempty"`

	// Metric: Sorts results by a metric's values.
	Metric *MetricOrderBy `json:"metric,omitempty"`

	// Pivot: Sorts results by a metric's values within a pivot column
	// group.
	Pivot *PivotOrderBy `json:"pivot,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Desc") 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. "Desc") 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 *OrderBy) MarshalJSON() ([]byte, error) {
	type NoMethod OrderBy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Pivot: Describes the visible dimension columns and rows in the report
// response.
type Pivot struct {
	// FieldNames: Dimension names for visible columns in the report
	// response. Including "dateRange" produces a date range column; for
	// each row in the response, dimension values in the date range column
	// will indicate the corresponding date range from the request.
	FieldNames []string `json:"fieldNames,omitempty"`

	// Limit: The number of rows to return in this pivot. If unspecified, 10
	// rows are returned. If -1, all rows are returned.
	Limit int64 `json:"limit,omitempty,string"`

	// MetricAggregations: Aggregate the metrics by dimensions in this pivot
	// using the specified metric_aggregations.
	//
	// Possible values:
	//   "METRIC_AGGREGATION_UNSPECIFIED" - Unspecified operator.
	//   "TOTAL" - SUM operator.
	//   "MINIMUM" - Minimum operator.
	//   "MAXIMUM" - Maximum operator.
	//   "COUNT" - Count operator.
	MetricAggregations []string `json:"metricAggregations,omitempty"`

	// Offset: The row count of the start row. The first row is counted as
	// row 0.
	Offset int64 `json:"offset,omitempty,string"`

	// OrderBys: Specifies how dimensions are ordered in the pivot. In the
	// first Pivot, the OrderBys determine Row and PivotDimensionHeader
	// ordering; in subsequent Pivots, the OrderBys determine only
	// PivotDimensionHeader ordering. Dimensions specified in these OrderBys
	// must be a subset of Pivot.field_names.
	OrderBys []*OrderBy `json:"orderBys,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FieldNames") 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. "FieldNames") 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 *Pivot) MarshalJSON() ([]byte, error) {
	type NoMethod Pivot
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PivotDimensionHeader: Summarizes dimension values from a row for this
// pivot.
type PivotDimensionHeader struct {
	// DimensionValues: Values of multiple dimensions in a pivot.
	DimensionValues []*DimensionValue `json:"dimensionValues,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionValues") 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. "DimensionValues") 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 *PivotDimensionHeader) MarshalJSON() ([]byte, error) {
	type NoMethod PivotDimensionHeader
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PivotHeader: Dimensions' values in a single pivot.
type PivotHeader struct {
	// PivotDimensionHeaders: The size is the same as the cardinality of the
	// corresponding dimension combinations.
	PivotDimensionHeaders []*PivotDimensionHeader `json:"pivotDimensionHeaders,omitempty"`

	// RowCount: The cardinality of the pivot as if offset = 0 and limit =
	// -1. The total number of rows for this pivot's fields regardless of
	// how the parameters offset and limit are specified in the request.
	RowCount int64 `json:"rowCount,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PivotDimensionHeaders") 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. "PivotDimensionHeaders") 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 *PivotHeader) MarshalJSON() ([]byte, error) {
	type NoMethod PivotHeader
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PivotOrderBy: Sorts by a pivot column group.
type PivotOrderBy struct {
	// MetricName: In the response to order by, order rows by this column.
	// Must be a metric name from the request.
	MetricName string `json:"metricName,omitempty"`

	// PivotSelections: Used to select a dimension name and value pivot. If
	// multiple pivot selections are given, the sort occurs on rows where
	// all pivot selection dimension name and value pairs match the row's
	// dimension name and value pair.
	PivotSelections []*PivotSelection `json:"pivotSelections,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MetricName") 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. "MetricName") 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 *PivotOrderBy) MarshalJSON() ([]byte, error) {
	type NoMethod PivotOrderBy
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PivotSelection: A pair of dimension names and values. Rows with this
// dimension pivot pair are ordered by the metric's value. For example
// if pivots = {{"browser", "Chrome"}} and metric_name = "Sessions",
// then the rows will be sorted based on Sessions in Chrome.
// ---------|----------|----------------|----------|---------------- |
// Chrome | Chrome | Safari | Safari
// ---------|----------|----------------|----------|----------------
// Country | Sessions | Pages/Sessions | Sessions | Pages/Sessions
// ---------|----------|----------------|----------|---------------- US
// | 2 | 2 | 3 | 1
// ---------|----------|----------------|----------|----------------
// Canada | 3 | 1 | 4 | 1
// ---------|----------|----------------|----------|----------------
type PivotSelection struct {
	// DimensionName: Must be a dimension name from the request.
	DimensionName string `json:"dimensionName,omitempty"`

	// DimensionValue: Order by only when the named dimension is this value.
	DimensionValue string `json:"dimensionValue,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionName") 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. "DimensionName") 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 *PivotSelection) MarshalJSON() ([]byte, error) {
	type NoMethod PivotSelection
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PropertyQuota: Current state of all quotas for this Analytics
// Property. If any quota for a property is exhausted, all requests to
// that property will return Resource Exhausted errors.
type PropertyQuota struct {
	// ConcurrentRequests: Analytics Properties can send up to 10 concurrent
	// requests.
	ConcurrentRequests *QuotaStatus `json:"concurrentRequests,omitempty"`

	// ServerErrorsPerProjectPerHour: Analytics Properties and cloud project
	// pairs can have up to 10 server errors per hour.
	ServerErrorsPerProjectPerHour *QuotaStatus `json:"serverErrorsPerProjectPerHour,omitempty"`

	// TokensPerDay: Analytics Properties can use up to 25,000 tokens per
	// day. Most requests consume fewer than 10 tokens.
	TokensPerDay *QuotaStatus `json:"tokensPerDay,omitempty"`

	// TokensPerHour: Analytics Properties can use up to 5,000 tokens per
	// day. An API request consumes a single number of tokens, and that
	// number is deducted from both the hourly and daily quotas.
	TokensPerHour *QuotaStatus `json:"tokensPerHour,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ConcurrentRequests")
	// 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. "ConcurrentRequests") 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 *PropertyQuota) MarshalJSON() ([]byte, error) {
	type NoMethod PropertyQuota
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// QuotaStatus: Current state for a particular quota group.
type QuotaStatus struct {
	// Consumed: Quota consumed by this request.
	Consumed int64 `json:"consumed,omitempty"`

	// Remaining: Quota remaining after this request.
	Remaining int64 `json:"remaining,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Consumed") 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. "Consumed") 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 *QuotaStatus) MarshalJSON() ([]byte, error) {
	type NoMethod QuotaStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResponseMetaData: Response's metadata carrying additional information
// about the report content.
type ResponseMetaData struct {
	// DataLossFromOtherRow: If true, indicates some buckets of dimension
	// combinations are rolled into "(other)" row. This can happen for high
	// cardinality reports.
	DataLossFromOtherRow bool `json:"dataLossFromOtherRow,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "DataLossFromOtherRow") 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. "DataLossFromOtherRow") 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 *ResponseMetaData) MarshalJSON() ([]byte, error) {
	type NoMethod ResponseMetaData
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Row: Report data for each row. For example if RunReportRequest
// contains: ```none dimensions { name: "eventName" } dimensions { name:
// "countryId" } metrics { name: "eventCount" } ``` One row with
// 'in_app_purchase' as the eventName, 'us' as the countryId, and 15 as
// the eventCount, would be: ```none dimension_values { name:
// 'in_app_purchase' name: 'us' } metric_values { int64_value: 15 } ```
type Row struct {
	// DimensionValues: List of requested dimension values. In a
	// PivotReport, dimension_values are only listed for dimensions included
	// in a pivot.
	DimensionValues []*DimensionValue `json:"dimensionValues,omitempty"`

	// MetricValues: List of requested visible metric values.
	MetricValues []*MetricValue `json:"metricValues,omitempty"`

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

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

// RunPivotReportRequest: The request to generate a pivot report.
type RunPivotReportRequest struct {
	// CohortSpec: Cohort group associated with this request. If there is a
	// cohort group in the request the 'cohort' dimension must be present.
	CohortSpec *CohortSpec `json:"cohortSpec,omitempty"`

	// CurrencyCode: A currency code in ISO4217 format, such as "AED",
	// "USD", "JPY". If the field is empty, the report uses the entity's
	// default currency.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// DateRanges: The date range to retrieve event data for the report. If
	// multiple date ranges are specified, event data from each date range
	// is used in the report. A special dimension with field name
	// "dateRange" can be included in a Pivot's field names; if included,
	// the report compares between date ranges. In a cohort request, this
	// `dateRanges` must be unspecified.
	DateRanges []*DateRange `json:"dateRanges,omitempty"`

	// DimensionFilter: The filter clause of dimensions. Dimensions must be
	// requested to be used in this filter. Metrics cannot be used in this
	// filter.
	DimensionFilter *FilterExpression `json:"dimensionFilter,omitempty"`

	// Dimensions: The dimensions requested. All defined dimensions must be
	// used by one of the following: dimension_expression, dimension_filter,
	// pivots, order_bys.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Entity: A property whose events are tracked. Within a batch request,
	// this entity should either be unspecified or consistent with the
	// batch-level entity.
	Entity *Entity `json:"entity,omitempty"`

	// KeepEmptyRows: If false or unspecified, each row with all metrics
	// equal to 0 will not be returned. If true, these rows will be returned
	// if they are not separately removed by a filter.
	KeepEmptyRows bool `json:"keepEmptyRows,omitempty"`

	// MetricFilter: The filter clause of metrics. Applied at post
	// aggregation phase, similar to SQL having-clause. Metrics must be
	// requested to be used in this filter. Dimensions cannot be used in
	// this filter.
	MetricFilter *FilterExpression `json:"metricFilter,omitempty"`

	// Metrics: The metrics requested, at least one metric needs to be
	// specified. All defined metrics must be used by one of the following:
	// metric_expression, metric_filter, order_bys.
	Metrics []*Metric `json:"metrics,omitempty"`

	// Pivots: Describes the visual format of the report's dimensions in
	// columns or rows. The union of the fieldNames (dimension names) in all
	// pivots must be a subset of dimension names defined in Dimensions. No
	// two pivots can share a dimension. A dimension is only visible if it
	// appears in a pivot.
	Pivots []*Pivot `json:"pivots,omitempty"`

	// ReturnPropertyQuota: Toggles whether to return the current state of
	// this Analytics Property's quota. Quota is returned in
	// [PropertyQuota](#PropertyQuota).
	ReturnPropertyQuota bool `json:"returnPropertyQuota,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CohortSpec") 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. "CohortSpec") 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 *RunPivotReportRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RunPivotReportRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RunPivotReportResponse: The response pivot report table corresponding
// to a pivot request.
type RunPivotReportResponse struct {
	// Aggregates: Aggregation of metric values. Can be totals, minimums, or
	// maximums. The returned aggregations are controlled by the
	// metric_aggregations in the pivot. The type of aggregation returned in
	// each row is shown by the dimension_values which are set to
	// "RESERVED_".
	Aggregates []*Row `json:"aggregates,omitempty"`

	// DimensionHeaders: Describes dimension columns. The number of
	// DimensionHeaders and ordering of DimensionHeaders matches the
	// dimensions present in rows.
	DimensionHeaders []*DimensionHeader `json:"dimensionHeaders,omitempty"`

	// Metadata: Metadata for the report.
	Metadata *ResponseMetaData `json:"metadata,omitempty"`

	// MetricHeaders: Describes metric columns. The number of MetricHeaders
	// and ordering of MetricHeaders matches the metrics present in rows.
	MetricHeaders []*MetricHeader `json:"metricHeaders,omitempty"`

	// PivotHeaders: Summarizes the columns and rows created by a pivot.
	// Each pivot in the request produces one header in the response. If we
	// have a request like this: "pivots": [{ "fieldNames": ["country",
	// "city"] }, { "fieldNames": "eventName" }] We will have the following
	// `pivotHeaders` in the response: "pivotHeaders" : [{
	// "dimensionHeaders": [{ "dimensionValues": [ { "value": "United
	// Kingdom" }, { "value": "London" } ] }, { "dimensionValues": [ {
	// "value": "Japan" }, { "value": "Osaka" } ] }] }, {
	// "dimensionHeaders": [{ "dimensionValues": [{ "value": "session_start"
	// }] }, { "dimensionValues": [{ "value": "scroll" }] }] }]
	PivotHeaders []*PivotHeader `json:"pivotHeaders,omitempty"`

	// PropertyQuota: This Analytics Property's quota state including this
	// request.
	PropertyQuota *PropertyQuota `json:"propertyQuota,omitempty"`

	// Rows: Rows of dimension value combinations and metric values in the
	// report.
	Rows []*Row `json:"rows,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Aggregates") 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. "Aggregates") 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 *RunPivotReportResponse) MarshalJSON() ([]byte, error) {
	type NoMethod RunPivotReportResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RunReportRequest: The request to generate a report.
type RunReportRequest struct {
	// CohortSpec: Cohort group associated with this request. If there is a
	// cohort group in the request the 'cohort' dimension must be present.
	CohortSpec *CohortSpec `json:"cohortSpec,omitempty"`

	// CurrencyCode: A currency code in ISO4217 format, such as "AED",
	// "USD", "JPY". If the field is empty, the report uses the entity's
	// default currency.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// DateRanges: Date ranges of data to read. If multiple date ranges are
	// requested, each response row will contain a zero based date range
	// index. If two date ranges overlap, the event data for the overlapping
	// days is included in the response rows for both date ranges. In a
	// cohort request, this `dateRanges` must be unspecified.
	DateRanges []*DateRange `json:"dateRanges,omitempty"`

	// DimensionFilter: The filter clause of dimensions. Dimensions must be
	// requested to be used in this filter. Metrics cannot be used in this
	// filter.
	DimensionFilter *FilterExpression `json:"dimensionFilter,omitempty"`

	// Dimensions: The dimensions requested and displayed.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Entity: A property whose events are tracked. Within a batch request,
	// this entity should either be unspecified or consistent with the
	// batch-level entity.
	Entity *Entity `json:"entity,omitempty"`

	// KeepEmptyRows: If false or unspecified, each row with all metrics
	// equal to 0 will not be returned. If true, these rows will be returned
	// if they are not separately removed by a filter.
	KeepEmptyRows bool `json:"keepEmptyRows,omitempty"`

	// Limit: The number of rows to return. If unspecified, 10 rows are
	// returned. If -1, all rows are returned.
	Limit int64 `json:"limit,omitempty,string"`

	// MetricAggregations: Aggregation of metrics. Aggregated metric values
	// will be shown in rows where the dimension_values are set to
	// "RESERVED_(MetricAggregation)".
	//
	// Possible values:
	//   "METRIC_AGGREGATION_UNSPECIFIED" - Unspecified operator.
	//   "TOTAL" - SUM operator.
	//   "MINIMUM" - Minimum operator.
	//   "MAXIMUM" - Maximum operator.
	//   "COUNT" - Count operator.
	MetricAggregations []string `json:"metricAggregations,omitempty"`

	// MetricFilter: The filter clause of metrics. Applied at post
	// aggregation phase, similar to SQL having-clause. Metrics must be
	// requested to be used in this filter. Dimensions cannot be used in
	// this filter.
	MetricFilter *FilterExpression `json:"metricFilter,omitempty"`

	// Metrics: The metrics requested and displayed.
	Metrics []*Metric `json:"metrics,omitempty"`

	// Offset: The row count of the start row. The first row is counted as
	// row 0.
	Offset int64 `json:"offset,omitempty,string"`

	// OrderBys: Specifies how rows are ordered in the response.
	OrderBys []*OrderBy `json:"orderBys,omitempty"`

	// ReturnPropertyQuota: Toggles whether to return the current state of
	// this Analytics Property's quota. Quota is returned in
	// [PropertyQuota](#PropertyQuota).
	ReturnPropertyQuota bool `json:"returnPropertyQuota,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CohortSpec") 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. "CohortSpec") 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 *RunReportRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RunReportRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RunReportResponse: The response report table corresponding to a
// request.
type RunReportResponse struct {
	// DimensionHeaders: Describes dimension columns. The number of
	// DimensionHeaders and ordering of DimensionHeaders matches the
	// dimensions present in rows.
	DimensionHeaders []*DimensionHeader `json:"dimensionHeaders,omitempty"`

	// Maximums: If requested, the maximum values of metrics.
	Maximums []*Row `json:"maximums,omitempty"`

	// Metadata: Metadata for the report.
	Metadata *ResponseMetaData `json:"metadata,omitempty"`

	// MetricHeaders: Describes metric columns. The number of MetricHeaders
	// and ordering of MetricHeaders matches the metrics present in rows.
	MetricHeaders []*MetricHeader `json:"metricHeaders,omitempty"`

	// Minimums: If requested, the minimum values of metrics.
	Minimums []*Row `json:"minimums,omitempty"`

	// PropertyQuota: This Analytics Property's quota state including this
	// request.
	PropertyQuota *PropertyQuota `json:"propertyQuota,omitempty"`

	// RowCount: The total number of rows in the query result, regardless of
	// the number of rows returned in the response. For example if a query
	// returns 175 rows and includes limit = 50 in the API request, the
	// response will contain row_count = 175 but only 50 rows.
	RowCount int64 `json:"rowCount,omitempty"`

	// Rows: Rows of dimension value combinations and metric values in the
	// report.
	Rows []*Row `json:"rows,omitempty"`

	// Totals: If requested, the totaled values of metrics.
	Totals []*Row `json:"totals,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "DimensionHeaders") 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. "DimensionHeaders") 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 *RunReportResponse) MarshalJSON() ([]byte, error) {
	type NoMethod RunReportResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// StringFilter: The filter for string
type StringFilter struct {
	// CaseSensitive: If true, the string value is case sensitive.
	CaseSensitive bool `json:"caseSensitive,omitempty"`

	// MatchType: The match type for this filter.
	//
	// Possible values:
	//   "MATCH_TYPE_UNSPECIFIED" - Unspecified
	//   "EXACT" - Exact match of the string value.
	//   "BEGINS_WITH" - Begins with the string value.
	//   "ENDS_WITH" - Ends with the string value.
	//   "CONTAINS" - Contains the string value.
	//   "FULL_REGEXP" - Full regular expression match with the string
	// value.
	//   "PARTIAL_REGEXP" - Partial regular expression match with the string
	// value.
	MatchType string `json:"matchType,omitempty"`

	// Value: The string value used for the matching.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CaseSensitive") 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. "CaseSensitive") 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 *StringFilter) MarshalJSON() ([]byte, error) {
	type NoMethod StringFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UniversalMetadata: The dimensions and metrics currently accepted in
// reporting methods.
type UniversalMetadata struct {
	// Dimensions: The dimensions descriptions.
	Dimensions []*DimensionMetadata `json:"dimensions,omitempty"`

	// Metrics: The metric descriptions.
	Metrics []*MetricMetadata `json:"metrics,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Dimensions") 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. "Dimensions") 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 *UniversalMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod UniversalMetadata
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "analyticsdata.properties.getMetadata":

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

// GetMetadata: Returns metadata for dimensions and metrics available in
// reporting methods. Used to explore the dimensions and metrics. In
// this method, a Google Analytics GA4 Property Identifier is specified
// in the request, and the metadata response includes Custom dimensions
// and metrics as well as Universal metadata. For example if a custom
// metric with parameter name `levels_unlocked` is registered to a
// property, the Metadata response will contain
// `customEvent:levels_unlocked`. Universal metadata are dimensions and
// metrics applicable to any property such as `country` and
// `totalUsers`.
func (r *PropertiesService) GetMetadata(nameid string) *PropertiesGetMetadataCall {
	c := &PropertiesGetMetadataCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.nameid = nameid
	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 *PropertiesGetMetadataCall) Fields(s ...googleapi.Field) *PropertiesGetMetadataCall {
	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 *PropertiesGetMetadataCall) IfNoneMatch(entityTag string) *PropertiesGetMetadataCall {
	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 *PropertiesGetMetadataCall) Context(ctx context.Context) *PropertiesGetMetadataCall {
	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 *PropertiesGetMetadataCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "analyticsdata.properties.getMetadata" call.
// Exactly one of *Metadata or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Metadata.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 *PropertiesGetMetadataCall) Do(opts ...googleapi.CallOption) (*Metadata, 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 := &Metadata{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns metadata for dimensions and metrics available in reporting methods. Used to explore the dimensions and metrics. In this method, a Google Analytics GA4 Property Identifier is specified in the request, and the metadata response includes Custom dimensions and metrics as well as Universal metadata. For example if a custom metric with parameter name `levels_unlocked` is registered to a property, the Metadata response will contain `customEvent:levels_unlocked`. Universal metadata are dimensions and metrics applicable to any property such as `country` and `totalUsers`.",
	//   "flatPath": "v1alpha/properties/{propertiesId}/metadata",
	//   "httpMethod": "GET",
	//   "id": "analyticsdata.properties.getMetadata",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. The resource name of the metadata to retrieve. This name field is specified in the URL path and not URL parameters. Property is a numeric Google Analytics GA4 Property identifier. Example: properties/1234/metadata",
	//       "location": "path",
	//       "pattern": "^properties/[^/]+/metadata$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1alpha/{+name}",
	//   "response": {
	//     "$ref": "Metadata"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/analytics",
	//     "https://www.googleapis.com/auth/analytics.readonly"
	//   ]
	// }

}

// method id "analyticsdata.batchRunPivotReports":

type V1alphaBatchRunPivotReportsCall struct {
	s                           *Service
	batchrunpivotreportsrequest *BatchRunPivotReportsRequest
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
	header_                     http.Header
}

// BatchRunPivotReports: Returns multiple pivot reports in a batch. All
// reports must be for the same Entity.
func (r *V1alphaService) BatchRunPivotReports(batchrunpivotreportsrequest *BatchRunPivotReportsRequest) *V1alphaBatchRunPivotReportsCall {
	c := &V1alphaBatchRunPivotReportsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.batchrunpivotreportsrequest = batchrunpivotreportsrequest
	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 *V1alphaBatchRunPivotReportsCall) Fields(s ...googleapi.Field) *V1alphaBatchRunPivotReportsCall {
	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 *V1alphaBatchRunPivotReportsCall) Context(ctx context.Context) *V1alphaBatchRunPivotReportsCall {
	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 *V1alphaBatchRunPivotReportsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1alphaBatchRunPivotReportsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.batchrunpivotreportsrequest)
	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, "v1alpha:batchRunPivotReports")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "analyticsdata.batchRunPivotReports" call.
// Exactly one of *BatchRunPivotReportsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BatchRunPivotReportsResponse.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 *V1alphaBatchRunPivotReportsCall) Do(opts ...googleapi.CallOption) (*BatchRunPivotReportsResponse, 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 := &BatchRunPivotReportsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns multiple pivot reports in a batch. All reports must be for the same Entity.",
	//   "flatPath": "v1alpha:batchRunPivotReports",
	//   "httpMethod": "POST",
	//   "id": "analyticsdata.batchRunPivotReports",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha:batchRunPivotReports",
	//   "request": {
	//     "$ref": "BatchRunPivotReportsRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchRunPivotReportsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/analytics",
	//     "https://www.googleapis.com/auth/analytics.readonly"
	//   ]
	// }

}

// method id "analyticsdata.batchRunReports":

type V1alphaBatchRunReportsCall struct {
	s                      *Service
	batchrunreportsrequest *BatchRunReportsRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// BatchRunReports: Returns multiple reports in a batch. All reports
// must be for the same Entity.
func (r *V1alphaService) BatchRunReports(batchrunreportsrequest *BatchRunReportsRequest) *V1alphaBatchRunReportsCall {
	c := &V1alphaBatchRunReportsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.batchrunreportsrequest = batchrunreportsrequest
	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 *V1alphaBatchRunReportsCall) Fields(s ...googleapi.Field) *V1alphaBatchRunReportsCall {
	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 *V1alphaBatchRunReportsCall) Context(ctx context.Context) *V1alphaBatchRunReportsCall {
	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 *V1alphaBatchRunReportsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1alphaBatchRunReportsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.batchrunreportsrequest)
	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, "v1alpha:batchRunReports")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "analyticsdata.batchRunReports" call.
// Exactly one of *BatchRunReportsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BatchRunReportsResponse.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 *V1alphaBatchRunReportsCall) Do(opts ...googleapi.CallOption) (*BatchRunReportsResponse, 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 := &BatchRunReportsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns multiple reports in a batch. All reports must be for the same Entity.",
	//   "flatPath": "v1alpha:batchRunReports",
	//   "httpMethod": "POST",
	//   "id": "analyticsdata.batchRunReports",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha:batchRunReports",
	//   "request": {
	//     "$ref": "BatchRunReportsRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchRunReportsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/analytics",
	//     "https://www.googleapis.com/auth/analytics.readonly"
	//   ]
	// }

}

// method id "analyticsdata.getUniversalMetadata":

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

// GetUniversalMetadata: Returns metadata for dimensions and metrics
// available in reporting methods. Used to explore the dimensions and
// metrics. Dimensions and metrics will be mostly added over time, but
// renames and deletions may occur. This method returns Universal
// Metadata. Universal Metadata are dimensions and metrics applicable to
// any property such as `country` and `totalUsers`.
func (r *V1alphaService) GetUniversalMetadata() *V1alphaGetUniversalMetadataCall {
	c := &V1alphaGetUniversalMetadataCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	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 *V1alphaGetUniversalMetadataCall) Fields(s ...googleapi.Field) *V1alphaGetUniversalMetadataCall {
	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 *V1alphaGetUniversalMetadataCall) IfNoneMatch(entityTag string) *V1alphaGetUniversalMetadataCall {
	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 *V1alphaGetUniversalMetadataCall) Context(ctx context.Context) *V1alphaGetUniversalMetadataCall {
	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 *V1alphaGetUniversalMetadataCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

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

// Do executes the "analyticsdata.getUniversalMetadata" call.
// Exactly one of *UniversalMetadata or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UniversalMetadata.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 *V1alphaGetUniversalMetadataCall) Do(opts ...googleapi.CallOption) (*UniversalMetadata, 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 := &UniversalMetadata{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns metadata for dimensions and metrics available in reporting methods. Used to explore the dimensions and metrics. Dimensions and metrics will be mostly added over time, but renames and deletions may occur. This method returns Universal Metadata. Universal Metadata are dimensions and metrics applicable to any property such as `country` and `totalUsers`.",
	//   "flatPath": "v1alpha/universalMetadata",
	//   "httpMethod": "GET",
	//   "id": "analyticsdata.getUniversalMetadata",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha/universalMetadata",
	//   "response": {
	//     "$ref": "UniversalMetadata"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/analytics",
	//     "https://www.googleapis.com/auth/analytics.readonly"
	//   ]
	// }

}

// method id "analyticsdata.runPivotReport":

type V1alphaRunPivotReportCall struct {
	s                     *Service
	runpivotreportrequest *RunPivotReportRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// RunPivotReport: Returns a customized pivot report of your Google
// Analytics event data. Pivot reports are more advanced and expressive
// formats than regular reports. In a pivot report, dimensions are only
// visible if they are included in a pivot. Multiple pivots can be
// specified to further dissect your data.
func (r *V1alphaService) RunPivotReport(runpivotreportrequest *RunPivotReportRequest) *V1alphaRunPivotReportCall {
	c := &V1alphaRunPivotReportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.runpivotreportrequest = runpivotreportrequest
	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 *V1alphaRunPivotReportCall) Fields(s ...googleapi.Field) *V1alphaRunPivotReportCall {
	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 *V1alphaRunPivotReportCall) Context(ctx context.Context) *V1alphaRunPivotReportCall {
	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 *V1alphaRunPivotReportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1alphaRunPivotReportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.runpivotreportrequest)
	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, "v1alpha:runPivotReport")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "analyticsdata.runPivotReport" call.
// Exactly one of *RunPivotReportResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RunPivotReportResponse.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 *V1alphaRunPivotReportCall) Do(opts ...googleapi.CallOption) (*RunPivotReportResponse, 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 := &RunPivotReportResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns a customized pivot report of your Google Analytics event data. Pivot reports are more advanced and expressive formats than regular reports. In a pivot report, dimensions are only visible if they are included in a pivot. Multiple pivots can be specified to further dissect your data.",
	//   "flatPath": "v1alpha:runPivotReport",
	//   "httpMethod": "POST",
	//   "id": "analyticsdata.runPivotReport",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha:runPivotReport",
	//   "request": {
	//     "$ref": "RunPivotReportRequest"
	//   },
	//   "response": {
	//     "$ref": "RunPivotReportResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/analytics",
	//     "https://www.googleapis.com/auth/analytics.readonly"
	//   ]
	// }

}

// method id "analyticsdata.runReport":

type V1alphaRunReportCall struct {
	s                *Service
	runreportrequest *RunReportRequest
	urlParams_       gensupport.URLParams
	ctx_             context.Context
	header_          http.Header
}

// RunReport: Returns a customized report of your Google Analytics event
// data. Reports contain statistics derived from data collected by the
// Google Analytics tracking code. The data returned from the API is as
// a table with columns for the requested dimensions and metrics.
// Metrics are individual measurements of user activity on your
// property, such as active users or event count. Dimensions break down
// metrics across some common criteria, such as country or event name.
func (r *V1alphaService) RunReport(runreportrequest *RunReportRequest) *V1alphaRunReportCall {
	c := &V1alphaRunReportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.runreportrequest = runreportrequest
	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 *V1alphaRunReportCall) Fields(s ...googleapi.Field) *V1alphaRunReportCall {
	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 *V1alphaRunReportCall) Context(ctx context.Context) *V1alphaRunReportCall {
	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 *V1alphaRunReportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *V1alphaRunReportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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.runreportrequest)
	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, "v1alpha:runReport")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "analyticsdata.runReport" call.
// Exactly one of *RunReportResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RunReportResponse.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 *V1alphaRunReportCall) Do(opts ...googleapi.CallOption) (*RunReportResponse, 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 := &RunReportResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns a customized report of your Google Analytics event data. Reports contain statistics derived from data collected by the Google Analytics tracking code. The data returned from the API is as a table with columns for the requested dimensions and metrics. Metrics are individual measurements of user activity on your property, such as active users or event count. Dimensions break down metrics across some common criteria, such as country or event name.",
	//   "flatPath": "v1alpha:runReport",
	//   "httpMethod": "POST",
	//   "id": "analyticsdata.runReport",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1alpha:runReport",
	//   "request": {
	//     "$ref": "RunReportRequest"
	//   },
	//   "response": {
	//     "$ref": "RunReportResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/analytics",
	//     "https://www.googleapis.com/auth/analytics.readonly"
	//   ]
	// }

}
