// Copyright 2019 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 analyticsreporting provides access to the Analytics Reporting API.
//
// For product documentation, see: https://developers.google.com/analytics/devguides/reporting/core/v4/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/analyticsreporting/v4"
//   ...
//   ctx := context.Background()
//   analyticsreportingService, err := analyticsreporting.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:
//
//   analyticsreportingService, err := analyticsreporting.NewService(ctx, option.WithScopes(analyticsreporting.AnalyticsReadonlyScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   analyticsreportingService, err := analyticsreporting.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, ...)
//   analyticsreportingService, err := analyticsreporting.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package analyticsreporting // import "google.golang.org/api/analyticsreporting/v4"

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

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

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

const apiId = "analyticsreporting:v4"
const apiName = "analyticsreporting"
const apiVersion = "v4"
const basePath = "https://analyticsreporting.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...)
	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.Reports = NewReportsService(s)
	s.UserActivity = NewUserActivityService(s)
	return s, nil
}

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

	Reports *ReportsService

	UserActivity *UserActivityService
}

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

func NewReportsService(s *Service) *ReportsService {
	rs := &ReportsService{s: s}
	return rs
}

type ReportsService struct {
	s *Service
}

func NewUserActivityService(s *Service) *UserActivityService {
	rs := &UserActivityService{s: s}
	return rs
}

type UserActivityService struct {
	s *Service
}

// Activity: An Activity represents data for an activity of a user. Note
// that an
// Activity is different from a hit.
// A hit might result in multiple Activity's. For example, if a
// hit
// includes a transaction and a goal completion, there will be
// two
// Activity protos for this hit, one for ECOMMERCE and one for
// GOAL.
// Conversely, multiple hits can also construct one Activity. In
// classic
// e-commerce, data for one transaction might be sent through multiple
// hits.
// These hits will be merged into one ECOMMERCE Activity.
type Activity struct {
	// ActivityTime: Timestamp of the activity. If activities for a visit
	// cross midnight and
	// occur in two separate dates, then two sessions (one per date)
	// share the session identifier.
	// For example, say session ID 113472 has activity within 2019-08-20,
	// and
	// session ID 243742 has activity within 2019-08-25 and 2019-08-26.
	// Session ID
	// 113472 is one session, and session ID 243742 is two sessions.
	ActivityTime string `json:"activityTime,omitempty"`

	// ActivityType: Type of this activity.
	//
	// Possible values:
	//   "ACTIVITY_TYPE_UNSPECIFIED" - ActivityType will never have this
	// value in the response. Using this type in
	// the request will result in an error.
	//   "PAGEVIEW" - Used when the activity resulted out of a visitor
	// viewing a page.
	//   "SCREENVIEW" - Used when the activity resulted out of a visitor
	// using an application on a
	// mobile device.
	//   "GOAL" - Used to denote that a goal type activity.
	//   "ECOMMERCE" - An e-commerce transaction was performed by the
	// visitor on the page.
	//   "EVENT" - Used when the activity is an event.
	ActivityType string `json:"activityType,omitempty"`

	// Appview: This will be set if `activity_type` equals `SCREEN_VIEW`.
	Appview *ScreenviewData `json:"appview,omitempty"`

	// Campaign: For manual campaign tracking, it is the value of the
	// utm_campaign campaign
	// tracking parameter. For AdWords autotagging, it is the name(s) of
	// the
	// online ad campaign(s) you use for the property. If you use neither,
	// its
	// value is (not set).
	Campaign string `json:"campaign,omitempty"`

	// ChannelGrouping: The Channel Group associated with an end user's
	// session for this View
	// (defined by the View's Channel Groupings).
	ChannelGrouping string `json:"channelGrouping,omitempty"`

	// CustomDimension: A list of all custom dimensions associated with this
	// activity.
	CustomDimension []*CustomDimension `json:"customDimension,omitempty"`

	// Ecommerce: This will be set if `activity_type` equals `ECOMMERCE`.
	Ecommerce *EcommerceData `json:"ecommerce,omitempty"`

	// Event: This field contains all the details pertaining to an event and
	// will be
	// set if `activity_type` equals `EVENT`.
	Event *EventData `json:"event,omitempty"`

	// Goals: This field contains a list of all the goals that were reached
	// in this
	// activity when `activity_type` equals `GOAL`.
	Goals *GoalSetData `json:"goals,omitempty"`

	// Hostname: The hostname from which the tracking request was made.
	Hostname string `json:"hostname,omitempty"`

	// Keyword: For manual campaign tracking, it is the value of the
	// utm_term campaign
	// tracking parameter. For AdWords traffic, it contains the best
	// matching
	// targeting criteria. For the display network, where multiple
	// targeting
	// criteria could have caused the ad to show up, it returns the best
	// matching
	// targeting criteria as selected by Ads. This could be display_keyword,
	// site
	// placement, boomuserlist, user_interest, age, or gender. Otherwise its
	// value
	// is (not set).
	Keyword string `json:"keyword,omitempty"`

	// LandingPagePath: The first page in users' sessions, or the landing
	// page.
	LandingPagePath string `json:"landingPagePath,omitempty"`

	// Medium: The type of referrals. For manual campaign tracking, it is
	// the value of the
	// utm_medium campaign tracking parameter. For AdWords autotagging, it
	// is cpc.
	// If users came from a search engine detected by Google Analytics, it
	// is
	// organic. If the referrer is not a search engine, it is referral. If
	// users
	// came directly to the property and document.referrer is empty, its
	// value is
	// (none).
	Medium string `json:"medium,omitempty"`

	// Pageview: This will be set if `activity_type` equals `PAGEVIEW`. This
	// field
	// contains all the details about the visitor and the page that was
	// visited.
	Pageview *PageviewData `json:"pageview,omitempty"`

	// Source: The source of referrals. For manual campaign tracking, it is
	// the value of
	// the utm_source campaign tracking parameter. For AdWords autotagging,
	// it is
	// google. If you use neither, it is the domain of the source
	// (e.g., document.referrer) referring the users. It may also contain a
	// port
	// address. If users arrived without a referrer, its value is (direct).
	Source string `json:"source,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActivityTime") 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. "ActivityTime") 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 *Activity) MarshalJSON() ([]byte, error) {
	type NoMethod Activity
	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: This is used for `FIRST_VISIT_DATE` cohort, the cohort
	// selects users
	// whose first visit date is between start date and end date defined in
	// the
	// DateRange. The date ranges should be aligned for cohort requests. If
	// the
	// request contains `ga:cohortNthDay` it should be exactly one day
	// long,
	// if `ga:cohortNthWeek` it should be aligned to the week boundary
	// (starting
	// at Sunday and ending Saturday), and for `ga:cohortNthMonth` the date
	// range
	// should be aligned to the month (starting at the first and ending on
	// the
	// last day of the month).
	// For LTV requests there are no such restrictions.
	// You do not need to supply a date range for
	// the
	// `reportsRequest.dateRanges` field.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Name: A unique name for the cohort. If not defined name will be
	// auto-generated
	// with values cohort_[1234...].
	Name string `json:"name,omitempty"`

	// Type: Type of the cohort. The only supported type as of now
	// is
	// `FIRST_VISIT_DATE`. If this field is unspecified the cohort is
	// treated
	// as `FIRST_VISIT_DATE` type cohort.
	//
	// Possible values:
	//   "UNSPECIFIED_COHORT_TYPE" - If unspecified it's treated as
	// `FIRST_VISIT_DATE`.
	//   "FIRST_VISIT_DATE" - Cohorts that are selected based on first visit
	// date.
	Type string `json:"type,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)
}

// CohortGroup: Defines a cohort group.
// For example:
//
//     "cohortGroup": {
//       "cohorts": [{
//         "name": "cohort 1",
//         "type": "FIRST_VISIT_DATE",
//         "dateRange": { "startDate": "2015-08-01", "endDate":
// "2015-08-01" }
//       },{
//         "name": "cohort 2"
//          "type": "FIRST_VISIT_DATE"
//          "dateRange": { "startDate": "2015-07-01", "endDate":
// "2015-07-01" }
//       }]
//     }
type CohortGroup struct {
	// Cohorts: The definition for the cohort.
	Cohorts []*Cohort `json:"cohorts,omitempty"`

	// LifetimeValue: Enable Life Time Value (LTV).  LTV measures lifetime
	// value for users
	// acquired through different channels.
	// Please see:
	// [Cohort
	// Analysis](https://support.google.com/analytics/answer/6074676)
	// and
	// [Lifetime
	// Value](https://support.google.com/analytics/answer/6182550)
	// If the value of lifetimeValue is false:
	//
	// - The metric values are similar to the values in the web interface
	// cohort
	//   report.
	// - The cohort definition date ranges must be aligned to the calendar
	// week
	//   and month. i.e. while requesting `ga:cohortNthWeek` the `startDate`
	// in
	//   the cohort definition should be a Sunday and the `endDate` should
	// be the
	//   following Saturday, and for `ga:cohortNthMonth`, the `startDate`
	//   should be the 1st of the month and `endDate` should be the last
	// day
	//   of the month.
	//
	// When the lifetimeValue is true:
	//
	// - The metric values will correspond to the values in the web
	// interface
	//   LifeTime value report.
	// - The Lifetime Value report shows you how user value (Revenue) and
	//   engagement (Appviews, Goal Completions, Sessions, and Session
	// Duration)
	//   grow during the 90 days after a user is acquired.
	// - The metrics are calculated as a cumulative average per user per the
	// time
	//   increment.
	// - The cohort definition date ranges need not be aligned to the
	// calendar
	//   week and month boundaries.
	// - The `viewId` must be an
	//   [app view
	//
	// ID](https://support.google.com/analytics/answer/2649553#WebVersusAppVi
	// ews)
	LifetimeValue bool `json:"lifetimeValue,omitempty"`

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

// ColumnHeader: Column headers.
type ColumnHeader struct {
	// Dimensions: The dimension names in the response.
	Dimensions []string `json:"dimensions,omitempty"`

	// MetricHeader: Metric headers for the metrics in the response.
	MetricHeader *MetricHeader `json:"metricHeader,omitempty"`

	// 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 *ColumnHeader) MarshalJSON() ([]byte, error) {
	type NoMethod ColumnHeader
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CustomDimension: Custom dimension.
type CustomDimension struct {
	// Index: Slot number of custom dimension.
	Index int64 `json:"index,omitempty"`

	// Value: Value of the custom dimension. Default value (i.e. empty
	// string) indicates
	// clearing sesion/visitor scope custom dimension value.
	Value string `json:"value,omitempty"`

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

// DateRange: A contiguous set of days: startDate, startDate + 1 day,
// ..., endDate.
// The start and end dates are specified
// in
// [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) date format
// `YYYY-MM-DD`.
type DateRange struct {
	// EndDate: The end date for the query in the format `YYYY-MM-DD`.
	EndDate string `json:"endDate,omitempty"`

	// StartDate: The start date for the query in the format `YYYY-MM-DD`.
	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)
}

// DateRangeValues: Used to return a list of metrics for a single
// DateRange / dimension
// combination
type DateRangeValues struct {
	// PivotValueRegions: The values of each pivot region.
	PivotValueRegions []*PivotValueRegion `json:"pivotValueRegions,omitempty"`

	// Values: Each value corresponds to each Metric in the request.
	Values []string `json:"values,omitempty"`

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

// Dimension:
// [Dimensions](https://support.google.com/analytics/answer/1033861)
// are attributes of your data. For example, the dimension
// `ga:city`
// indicates the city, for example, "Paris" or "New York", from which
// a session originates.
type Dimension struct {
	// HistogramBuckets: If non-empty, we place dimension values into
	// buckets after string to
	// int64. Dimension values that are not the string representation of
	// an
	// integral value will be converted to zero.  The bucket values have to
	// be in
	// increasing order.  Each bucket is closed on the lower end, and open
	// on the
	// upper end. The "first" bucket includes all values less than the
	// first
	// boundary, the "last" bucket includes all values up to infinity.
	// Dimension
	// values that fall in a bucket get transformed to a new dimension
	// value. For
	// example, if one gives a list of "0, 1, 3, 4, 7", then we return
	// the
	// following buckets:
	//
	// - bucket #1: values < 0, dimension value "<0"
	// - bucket #2: values in [0,1), dimension value "0"
	// - bucket #3: values in [1,3), dimension value "1-2"
	// - bucket #4: values in [3,4), dimension value "3"
	// - bucket #5: values in [4,7), dimension value "4-6"
	// - bucket #6: values >= 7, dimension value "7+"
	//
	// NOTE: If you are applying histogram mutation on any dimension, and
	// using
	// that dimension in sort, you will want to use the sort
	// type
	// `HISTOGRAM_BUCKET` for that purpose. Without that the dimension
	// values
	// will be sorted according to dictionary
	// (lexicographic) order. For example the ascending dictionary order
	// is:
	//
	//    "<50", "1001+", "121-1000", "50-120"
	//
	// And the ascending `HISTOGRAM_BUCKET` order is:
	//
	//    "<50", "50-120", "121-1000", "1001+"
	//
	// The client has to explicitly request "orderType":
	// "HISTOGRAM_BUCKET"
	// for a histogram-mutated dimension.
	HistogramBuckets googleapi.Int64s `json:"histogramBuckets,omitempty"`

	// Name: Name of the dimension to fetch, for example `ga:browser`.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HistogramBuckets") 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. "HistogramBuckets") 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)
}

// DimensionFilter: Dimension filter specifies the filtering options on
// a dimension.
type DimensionFilter struct {
	// CaseSensitive: Should the match be case sensitive? Default is false.
	CaseSensitive bool `json:"caseSensitive,omitempty"`

	// DimensionName: The dimension to filter on. A DimensionFilter must
	// contain a dimension.
	DimensionName string `json:"dimensionName,omitempty"`

	// Expressions: Strings or regular expression to match against. Only the
	// first value of
	// the list is used for comparison unless the operator is `IN_LIST`.
	// If `IN_LIST` operator, then the entire list is used to filter
	// the
	// dimensions as explained in the description of the `IN_LIST` operator.
	Expressions []string `json:"expressions,omitempty"`

	// Not: Logical `NOT` operator. If this boolean is set to true, then the
	// matching
	// dimension values will be excluded in the report. The default is
	// false.
	Not bool `json:"not,omitempty"`

	// Operator: How to match the dimension to the expression. The default
	// is REGEXP.
	//
	// Possible values:
	//   "OPERATOR_UNSPECIFIED" - If the match type is unspecified, it is
	// treated as a `REGEXP`.
	//   "REGEXP" - The match expression is treated as a regular expression.
	// All match types
	// are not treated as regular expressions.
	//   "BEGINS_WITH" - Matches the value which begin with the match
	// expression provided.
	//   "ENDS_WITH" - Matches the values which end with the match
	// expression provided.
	//   "PARTIAL" - Substring match.
	//   "EXACT" - The value should match the match expression entirely.
	//   "NUMERIC_EQUAL" - Integer comparison filters.
	// case sensitivity is ignored for these and the expression
	// is assumed to be a string representing an integer.
	// Failure conditions:
	//
	// - If expression is not a valid int64, the client should expect
	//   an error.
	// - Input dimensions that are not valid int64 values will never match
	// the
	//   filter.
	//   "NUMERIC_GREATER_THAN" - Checks if the dimension is numerically
	// greater than the match
	// expression. Read the description for `NUMERIC_EQUALS` for
	// restrictions.
	//   "NUMERIC_LESS_THAN" - Checks if the dimension is numerically less
	// than the match expression.
	// Read the description for `NUMERIC_EQUALS` for restrictions.
	//   "IN_LIST" - This option is used to specify a dimension filter whose
	// expression can
	// take any value from a selected list of values. This helps
	// avoiding
	// evaluating multiple exact match dimension filters which are OR'ed
	// for
	// every single response row. For example:
	//
	//     expressions: ["A", "B", "C"]
	//
	// Any response row whose dimension has it is value as A, B or C,
	// matches
	// this DimensionFilter.
	Operator string `json:"operator,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 *DimensionFilter) MarshalJSON() ([]byte, error) {
	type NoMethod DimensionFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DimensionFilterClause: A group of dimension filters. Set the operator
// value to specify how
// the filters are logically combined.
type DimensionFilterClause struct {
	// Filters: The repeated set of filters. They are logically combined
	// based on the
	// operator specified.
	Filters []*DimensionFilter `json:"filters,omitempty"`

	// Operator: The operator for combining multiple dimension filters. If
	// unspecified, it
	// is treated as an `OR`.
	//
	// Possible values:
	//   "OPERATOR_UNSPECIFIED" - Unspecified operator. It is treated as an
	// `OR`.
	//   "OR" - The logical `OR` operator.
	//   "AND" - The logical `AND` operator.
	Operator string `json:"operator,omitempty"`

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

// DynamicSegment: Dynamic segment definition for defining the segment
// within the request.
// A segment can select users, sessions or both.
type DynamicSegment struct {
	// Name: The name of the dynamic segment.
	Name string `json:"name,omitempty"`

	// SessionSegment: Session Segment to select sessions to include in the
	// segment.
	SessionSegment *SegmentDefinition `json:"sessionSegment,omitempty"`

	// UserSegment: User Segment to select users to include in the segment.
	UserSegment *SegmentDefinition `json:"userSegment,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 *DynamicSegment) MarshalJSON() ([]byte, error) {
	type NoMethod DynamicSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EcommerceData: E-commerce details associated with the user activity.
type EcommerceData struct {
	// ActionType: Action associated with this e-commerce action.
	//
	// Possible values:
	//   "UNKNOWN" - Action type is not known.
	//   "CLICK" - Click through of product lists.
	//   "DETAILS_VIEW" - Product detail views.
	//   "ADD_TO_CART" - Add product(s) to cart.
	//   "REMOVE_FROM_CART" - Remove product(s) from cart.
	//   "CHECKOUT" - Check out.
	//   "PAYMENT" - Completed purchase.
	//   "REFUND" - Refund of purchase.
	//   "CHECKOUT_OPTION" - Checkout options.
	ActionType string `json:"actionType,omitempty"`

	// EcommerceType: The type of this e-commerce activity.
	//
	// Possible values:
	//   "ECOMMERCE_TYPE_UNSPECIFIED" - Used when the e-commerce activity
	// type is unspecified.
	//   "CLASSIC" - Used when activity has classic (non-enhanced)
	// e-commerce information.
	//   "ENHANCED" - Used when activity has enhanced e-commerce
	// information.
	EcommerceType string `json:"ecommerceType,omitempty"`

	// Products: Details of the products in this transaction.
	Products []*ProductData `json:"products,omitempty"`

	// Transaction: Transaction details of this e-commerce action.
	Transaction *TransactionData `json:"transaction,omitempty"`

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

// EventData: Represents all the details pertaining to an event.
type EventData struct {
	// EventAction: Type of interaction with the object. Eg: 'play'.
	EventAction string `json:"eventAction,omitempty"`

	// EventCategory: The object on the page that was interacted with. Eg:
	// 'Video'.
	EventCategory string `json:"eventCategory,omitempty"`

	// EventCount: Number of such events in this activity.
	EventCount int64 `json:"eventCount,omitempty,string"`

	// EventLabel: Label attached with the event.
	EventLabel string `json:"eventLabel,omitempty"`

	// EventValue: Numeric value associated with the event.
	EventValue int64 `json:"eventValue,omitempty,string"`

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

// GetReportsRequest: The batch request containing multiple report
// request.
type GetReportsRequest struct {
	// ReportRequests: Requests, each request will have a separate
	// response.
	// There can be a maximum of 5 requests. All requests should have the
	// same
	// `dateRanges`, `viewId`, `segments`, `samplingLevel`, and
	// `cohortGroup`.
	ReportRequests []*ReportRequest `json:"reportRequests,omitempty"`

	// UseResourceQuotas: Enables
	// [resource
	// based
	// quotas](/analytics/devguides/reporting/core/v4/limits-quotas#ana
	// lytics_reporting_api_v4),
	// (defaults to `False`). If this field is set to `True` the
	// per view (profile) quotas are governed by the computational
	// cost of the request. Note that using cost based quotas will
	// higher enable sampling rates. (10 Million for `SMALL`,
	// 100M for `LARGE`. See the
	// [limits and
	// quotas
	// documentation](/analytics/devguides/reporting/core/v4/limits-qu
	// otas#analytics_reporting_api_v4)
	// for details.
	UseResourceQuotas bool `json:"useResourceQuotas,omitempty"`

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

// GetReportsResponse: The main response class which holds the reports
// from the Reporting API
// `batchGet` call.
type GetReportsResponse struct {
	// QueryCost: The amount of resource quota tokens deducted to execute
	// the query. Includes
	// all responses.
	QueryCost int64 `json:"queryCost,omitempty"`

	// Reports: Responses corresponding to each of the request.
	Reports []*Report `json:"reports,omitempty"`

	// ResourceQuotasRemaining: The amount of resource quota remaining for
	// the property.
	ResourceQuotasRemaining *ResourceQuotasRemaining `json:"resourceQuotasRemaining,omitempty"`

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

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

// GoalData: Represents all the details pertaining to a goal.
type GoalData struct {
	// GoalCompletionLocation: URL of the page where this goal was
	// completed.
	GoalCompletionLocation string `json:"goalCompletionLocation,omitempty"`

	// GoalCompletions: Total number of goal completions in this activity.
	GoalCompletions int64 `json:"goalCompletions,omitempty,string"`

	// GoalIndex: This identifies the goal as configured for the profile.
	GoalIndex int64 `json:"goalIndex,omitempty"`

	// GoalName: Name of the goal.
	GoalName string `json:"goalName,omitempty"`

	// GoalPreviousStep1: URL of the page one step prior to the goal
	// completion.
	GoalPreviousStep1 string `json:"goalPreviousStep1,omitempty"`

	// GoalPreviousStep2: URL of the page two steps prior to the goal
	// completion.
	GoalPreviousStep2 string `json:"goalPreviousStep2,omitempty"`

	// GoalPreviousStep3: URL of the page three steps prior to the goal
	// completion.
	GoalPreviousStep3 string `json:"goalPreviousStep3,omitempty"`

	// GoalValue: Value in this goal.
	GoalValue float64 `json:"goalValue,omitempty"`

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

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

// GoalSetData: Represents a set of goals that were reached in an
// activity.
type GoalSetData struct {
	// Goals: All the goals that were reached in the current activity.
	Goals []*GoalData `json:"goals,omitempty"`

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

// Metric:
// [Metrics](https://support.google.com/analytics/answer/1033861)
// are the quantitative measurements. For example, the metric
// `ga:users`
// indicates the total number of users for the requested time period.
type Metric struct {
	// Alias: An alias for the metric expression is an alternate name for
	// the
	// expression. The alias can be used for filtering and sorting. This
	// field
	// is optional and is useful if the expression is not a single metric
	// but
	// a complex expression which cannot be used in filtering and
	// sorting.
	// The alias is also used in the response column header.
	Alias string `json:"alias,omitempty"`

	// Expression: A metric expression in the request. An expression is
	// constructed from one
	// or more metrics and numbers. Accepted operators include: Plus (+),
	// Minus
	// (-), Negation (Unary -), Divided by (/), Multiplied by (*),
	// Parenthesis,
	// Positive cardinal numbers (0-9), can include decimals and is limited
	// to
	// 1024 characters. Example `ga:totalRefunds/ga:users`, in most cases
	// the
	// metric expression is just a single metric name like
	// `ga:users`.
	// Adding mixed `MetricType` (E.g., `CURRENCY` + `PERCENTAGE`)
	// metrics
	// will result in unexpected results.
	Expression string `json:"expression,omitempty"`

	// FormattingType: Specifies how the metric expression should be
	// formatted, for example
	// `INTEGER`.
	//
	// Possible values:
	//   "METRIC_TYPE_UNSPECIFIED" - Metric type is unspecified.
	//   "INTEGER" - Integer metric.
	//   "FLOAT" - Float metric.
	//   "CURRENCY" - Currency metric.
	//   "PERCENT" - Percentage metric.
	//   "TIME" - Time metric in `HH:MM:SS` format.
	FormattingType string `json:"formattingType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alias") 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. "Alias") 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)
}

// MetricFilter: MetricFilter specifies the filter on a metric.
type MetricFilter struct {
	// ComparisonValue: The value to compare against.
	ComparisonValue string `json:"comparisonValue,omitempty"`

	// MetricName: The metric that will be filtered on. A metricFilter must
	// contain a metric
	// name. A metric name can be an alias earlier defined as a metric or it
	// can
	// also be a metric expression.
	MetricName string `json:"metricName,omitempty"`

	// Not: Logical `NOT` operator. If this boolean is set to true, then the
	// matching
	// metric values will be excluded in the report. The default is false.
	Not bool `json:"not,omitempty"`

	// Operator: Is the metric `EQUAL`, `LESS_THAN` or `GREATER_THAN`
	// the
	// comparisonValue, the default is `EQUAL`. If the operator
	// is
	// `IS_MISSING`, checks if the metric is missing and would ignore
	// the
	// comparisonValue.
	//
	// Possible values:
	//   "OPERATOR_UNSPECIFIED" - If the operator is not specified, it is
	// treated as `EQUAL`.
	//   "EQUAL" - Should the value of the metric be exactly equal to the
	// comparison value.
	//   "LESS_THAN" - Should the value of the metric be less than to the
	// comparison value.
	//   "GREATER_THAN" - Should the value of the metric be greater than to
	// the comparison value.
	//   "IS_MISSING" - Validates if the metric is missing.
	// Doesn't take comparisonValue into account.
	Operator string `json:"operator,omitempty"`

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

// MetricFilterClause: Represents a group of metric filters.
// Set the operator value to specify how the filters are logically
// combined.
type MetricFilterClause struct {
	// Filters: The repeated set of filters. They are logically combined
	// based on the
	// operator specified.
	Filters []*MetricFilter `json:"filters,omitempty"`

	// Operator: The operator for combining multiple metric filters. If
	// unspecified, it is
	// treated as an `OR`.
	//
	// Possible values:
	//   "OPERATOR_UNSPECIFIED" - Unspecified operator. It is treated as an
	// `OR`.
	//   "OR" - The logical `OR` operator.
	//   "AND" - The logical `AND` operator.
	Operator string `json:"operator,omitempty"`

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

// MetricHeader: The headers for the metrics.
type MetricHeader struct {
	// MetricHeaderEntries: Headers for the metrics in the response.
	MetricHeaderEntries []*MetricHeaderEntry `json:"metricHeaderEntries,omitempty"`

	// PivotHeaders: Headers for the pivots in the response.
	PivotHeaders []*PivotHeader `json:"pivotHeaders,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MetricHeaderEntries")
	// 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. "MetricHeaderEntries") 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)
}

// MetricHeaderEntry: Header for the metrics.
type MetricHeaderEntry struct {
	// Name: The name of the header.
	Name string `json:"name,omitempty"`

	// Type: The type of the metric, for example `INTEGER`.
	//
	// Possible values:
	//   "METRIC_TYPE_UNSPECIFIED" - Metric type is unspecified.
	//   "INTEGER" - Integer metric.
	//   "FLOAT" - Float metric.
	//   "CURRENCY" - Currency metric.
	//   "PERCENT" - Percentage metric.
	//   "TIME" - Time metric in `HH:MM:SS` format.
	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 *MetricHeaderEntry) MarshalJSON() ([]byte, error) {
	type NoMethod MetricHeaderEntry
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OrFiltersForSegment: A list of segment filters in the `OR` group are
// combined with the logical OR
// operator.
type OrFiltersForSegment struct {
	// SegmentFilterClauses: List of segment filters to be combined with a
	// `OR` operator.
	SegmentFilterClauses []*SegmentFilterClause `json:"segmentFilterClauses,omitempty"`

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

// OrderBy: Specifies the sorting options.
type OrderBy struct {
	// FieldName: The field which to sort by. The default sort order is
	// ascending. Example:
	// `ga:browser`.
	// Note, that you can only specify one field for sort here. For
	// example,
	// `ga:browser, ga:city` is not valid.
	FieldName string `json:"fieldName,omitempty"`

	// OrderType: The order type. The default orderType is `VALUE`.
	//
	// Possible values:
	//   "ORDER_TYPE_UNSPECIFIED" - Unspecified order type will be treated
	// as sort based on value.
	//   "VALUE" - The sort order is based on the value of the chosen
	// column; looks only at
	// the first date range.
	//   "DELTA" - The sort order is based on the difference of the values
	// of the chosen
	// column between the first two date ranges.  Usable only if there
	// are
	// exactly two date ranges.
	//   "SMART" - The sort order is based on weighted value of the chosen
	// column.  If
	// column has n/d format, then weighted value of this ratio will
	// be `(n + totals.n)/(d + totals.d)` Usable only for metrics
	// that
	// represent ratios.
	//   "HISTOGRAM_BUCKET" - Histogram order type is applicable only to
	// dimension columns with
	// non-empty histogram-buckets.
	//   "DIMENSION_AS_INTEGER" - If the dimensions are fixed length
	// numbers, ordinary sort would just
	// work fine. `DIMENSION_AS_INTEGER` can be used if the dimensions
	// are
	// variable length numbers.
	OrderType string `json:"orderType,omitempty"`

	// SortOrder: The sorting order for the field.
	//
	// Possible values:
	//   "SORT_ORDER_UNSPECIFIED" - If the sort order is unspecified, the
	// default is ascending.
	//   "ASCENDING" - Ascending sort. The field will be sorted in an
	// ascending manner.
	//   "DESCENDING" - Descending sort. The field will be sorted in a
	// descending manner.
	SortOrder string `json:"sortOrder,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FieldName") 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. "FieldName") 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)
}

// PageviewData: Represents details collected when the visitor views a
// page.
type PageviewData struct {
	// PagePath: The URL of the page that the visitor viewed.
	PagePath string `json:"pagePath,omitempty"`

	// PageTitle: The title of the page that the visitor viewed.
	PageTitle string `json:"pageTitle,omitempty"`

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

// Pivot: The Pivot describes the pivot section in the request.
// The Pivot helps rearrange the information in the table for certain
// reports
// by pivoting your data on a second dimension.
type Pivot struct {
	// DimensionFilterClauses: DimensionFilterClauses are logically combined
	// with an `AND` operator: only
	// data that is included by all these DimensionFilterClauses contributes
	// to
	// the values in this pivot region. Dimension filters can be used to
	// restrict
	// the columns shown in the pivot region. For example if you
	// have
	// `ga:browser` as the requested dimension in the pivot region, and
	// you
	// specify key filters to restrict `ga:browser` to only "IE" or
	// "Firefox",
	// then only those two browsers would show up as columns.
	DimensionFilterClauses []*DimensionFilterClause `json:"dimensionFilterClauses,omitempty"`

	// Dimensions: A list of dimensions to show as pivot columns. A Pivot
	// can have a maximum
	// of 4 dimensions. Pivot dimensions are part of the restriction on
	// the
	// total number of dimensions allowed in the request.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// MaxGroupCount: Specifies the maximum number of groups to return.
	// The default value is 10, also the maximum value is 1,000.
	MaxGroupCount int64 `json:"maxGroupCount,omitempty"`

	// Metrics: The pivot metrics. Pivot metrics are part of the
	// restriction on total number of metrics allowed in the request.
	Metrics []*Metric `json:"metrics,omitempty"`

	// StartGroup: If k metrics were requested, then the response will
	// contain some
	// data-dependent multiple of k columns in the report.  E.g., if you
	// pivoted
	// on the dimension `ga:browser` then you'd get k columns for "Firefox",
	// k
	// columns for "IE", k columns for "Chrome", etc. The ordering of the
	// groups
	// of columns is determined by descending order of "total" for the first
	// of
	// the k values.  Ties are broken by lexicographic ordering of the
	// first
	// pivot dimension, then lexicographic ordering of the second
	// pivot
	// dimension, and so on.  E.g., if the totals for the first value
	// for
	// Firefox, IE, and Chrome were 8, 2, 8, respectively, the order of
	// columns
	// would be Chrome, Firefox, IE.
	//
	// The following let you choose which of the groups of k columns
	// are
	// included in the response.
	StartGroup int64 `json:"startGroup,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "DimensionFilterClauses") 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. "DimensionFilterClauses")
	// 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)
}

// PivotHeader: The headers for each of the pivot sections defined in
// the request.
type PivotHeader struct {
	// PivotHeaderEntries: A single pivot section header.
	PivotHeaderEntries []*PivotHeaderEntry `json:"pivotHeaderEntries,omitempty"`

	// TotalPivotGroupsCount: The total number of groups for this pivot.
	TotalPivotGroupsCount int64 `json:"totalPivotGroupsCount,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PivotHeaderEntries")
	// 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. "PivotHeaderEntries") 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)
}

// PivotHeaderEntry: The headers for the each of the metric column
// corresponding to the metrics
// requested in the pivots section of the response.
type PivotHeaderEntry struct {
	// DimensionNames: The name of the dimensions in the pivot response.
	DimensionNames []string `json:"dimensionNames,omitempty"`

	// DimensionValues: The values for the dimensions in the pivot.
	DimensionValues []string `json:"dimensionValues,omitempty"`

	// Metric: The metric header for the metric in the pivot.
	Metric *MetricHeaderEntry `json:"metric,omitempty"`

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

// PivotValueRegion: The metric values in the pivot region.
type PivotValueRegion struct {
	// Values: The values of the metrics in each of the pivot regions.
	Values []string `json:"values,omitempty"`

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

// ProductData: Details of the products in an e-commerce transaction.
type ProductData struct {
	// ItemRevenue: The total revenue from purchased product items.
	ItemRevenue float64 `json:"itemRevenue,omitempty"`

	// ProductName: The product name, supplied by the e-commerce tracking
	// application, for
	// the purchased items.
	ProductName string `json:"productName,omitempty"`

	// ProductQuantity: Total number of this product units in the
	// transaction.
	ProductQuantity int64 `json:"productQuantity,omitempty,string"`

	// ProductSku: Unique code that represents the product.
	ProductSku string `json:"productSku,omitempty"`

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

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

// Report: The data response corresponding to the request.
type Report struct {
	// ColumnHeader: The column headers.
	ColumnHeader *ColumnHeader `json:"columnHeader,omitempty"`

	// Data: Response data.
	Data *ReportData `json:"data,omitempty"`

	// NextPageToken: Page token to retrieve the next page of results in the
	// list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

// ReportData: The data part of the report.
type ReportData struct {
	// DataLastRefreshed: The last time the data in the report was
	// refreshed. All the hits received
	// before this timestamp are included in the calculation of the report.
	DataLastRefreshed string `json:"dataLastRefreshed,omitempty"`

	// IsDataGolden: Indicates if response to this request is golden or not.
	// Data is
	// golden when the exact same request will not produce any new results
	// if
	// asked at a later point in time.
	IsDataGolden bool `json:"isDataGolden,omitempty"`

	// Maximums: Minimum and maximum values seen over all matching rows.
	// These are both
	// empty when `hideValueRanges` in the request is false, or
	// when
	// rowCount is zero.
	Maximums []*DateRangeValues `json:"maximums,omitempty"`

	// Minimums: Minimum and maximum values seen over all matching rows.
	// These are both
	// empty when `hideValueRanges` in the request is false, or
	// when
	// rowCount is zero.
	Minimums []*DateRangeValues `json:"minimums,omitempty"`

	// RowCount: Total number of matching rows for this query.
	RowCount int64 `json:"rowCount,omitempty"`

	// Rows: There's one ReportRow for every unique combination of
	// dimensions.
	Rows []*ReportRow `json:"rows,omitempty"`

	// SamplesReadCounts: If the results
	// are
	// [sampled](https://support.google.com/analytics/answer/2637192),
	// th
	// is returns the total number of samples read, one entry per date
	// range.
	// If the results are not sampled this field will not be defined.
	// See
	// [developer
	// guide](/analytics/devguides/reporting/core/v4/basics#sampling)
	// for details.
	SamplesReadCounts googleapi.Int64s `json:"samplesReadCounts,omitempty"`

	// SamplingSpaceSizes: If the results
	// are
	// [sampled](https://support.google.com/analytics/answer/2637192),
	// th
	// is returns the total number of
	// samples present, one entry per date range. If the results are not
	// sampled
	// this field will not be defined. See
	// [developer
	// guide](/analytics/devguides/reporting/core/v4/basics#sampling)
	// for details.
	SamplingSpaceSizes googleapi.Int64s `json:"samplingSpaceSizes,omitempty"`

	// Totals: For each requested date range, for the set of all rows that
	// match
	// the query, every requested value format gets a total. The total
	// for a value format is computed by first totaling the
	// metrics
	// mentioned in the value format and then evaluating the value
	// format as a scalar expression.  E.g., The "totals" for
	// `3 / (ga:sessions + 2)` we compute
	// `3 / ((sum of all relevant ga:sessions) + 2)`.
	// Totals are computed before pagination.
	Totals []*DateRangeValues `json:"totals,omitempty"`

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

// ReportRequest: The main request class which specifies the Reporting
// API request.
type ReportRequest struct {
	// CohortGroup: Cohort group associated with this request. If there is a
	// cohort group
	// in the request the `ga:cohort` dimension must be present.
	// Every [ReportRequest](#ReportRequest) within a `batchGet` method
	// must
	// contain the same `cohortGroup` definition.
	CohortGroup *CohortGroup `json:"cohortGroup,omitempty"`

	// DateRanges: Date ranges in the request. The request can have a
	// maximum of 2 date
	// ranges. The response will contain a set of metric values for
	// each
	// combination of the dimensions for each date range in the request. So,
	// if
	// there are two date ranges, there will be two set of metric values,
	// one for
	// the original date range and one for the second date range.
	// The `reportRequest.dateRanges` field should not be specified for
	// cohorts
	// or Lifetime value requests.
	// If a date range is not provided, the default date range is
	// (startDate:
	// current date - 7 days, endDate: current date - 1 day).
	// Every
	// [ReportRequest](#ReportRequest) within a `batchGet` method
	// must
	// contain the same `dateRanges` definition.
	DateRanges []*DateRange `json:"dateRanges,omitempty"`

	// DimensionFilterClauses: The dimension filter clauses for filtering
	// Dimension Values. They are
	// logically combined with the `AND` operator. Note that filtering
	// occurs
	// before any dimensions are aggregated, so that the returned
	// metrics
	// represent the total for only the relevant dimensions.
	DimensionFilterClauses []*DimensionFilterClause `json:"dimensionFilterClauses,omitempty"`

	// Dimensions: The dimensions requested.
	// Requests can have a total of 9 dimensions.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// FiltersExpression: Dimension or metric filters that restrict the data
	// returned for your
	// request. To use the `filtersExpression`, supply a dimension or metric
	// on
	// which to filter, followed by the filter expression. For example,
	// the
	// following expression selects `ga:browser` dimension which starts
	// with
	// Firefox; `ga:browser=~^Firefox`. For more information on
	// dimensions
	// and metric filters,
	// see
	// [Filters
	// reference](https://developers.google.com/analytics/devgui
	// des/reporting/core/v3/reference#filters).
	FiltersExpression string `json:"filtersExpression,omitempty"`

	// HideTotals: If set to true, hides the total of all metrics for all
	// the matching rows,
	// for every date range. The default false and will return the totals.
	HideTotals bool `json:"hideTotals,omitempty"`

	// HideValueRanges: If set to true, hides the minimum and maximum across
	// all matching rows.
	// The default is false and the value ranges are returned.
	HideValueRanges bool `json:"hideValueRanges,omitempty"`

	// IncludeEmptyRows: If set to false, the response does not include rows
	// if all the retrieved
	// metrics are equal to zero. The default is false which will exclude
	// these
	// rows.
	IncludeEmptyRows bool `json:"includeEmptyRows,omitempty"`

	// MetricFilterClauses: The metric filter clauses. They are logically
	// combined with the `AND`
	// operator.  Metric filters look at only the first date range and not
	// the
	// comparing date range. Note that filtering on metrics occurs after
	// the
	// metrics are aggregated.
	MetricFilterClauses []*MetricFilterClause `json:"metricFilterClauses,omitempty"`

	// Metrics: The metrics requested.
	// Requests must specify at least one metric. Requests can have a
	// total of 10 metrics.
	Metrics []*Metric `json:"metrics,omitempty"`

	// OrderBys: Sort order on output rows. To compare two rows, the
	// elements of the
	// following are applied in order until a difference is found.  All
	// date
	// ranges in the output get the same row order.
	OrderBys []*OrderBy `json:"orderBys,omitempty"`

	// PageSize: Page size is for paging and specifies the maximum number of
	// returned rows.
	// Page size should be >= 0. A query returns the default of 1,000
	// rows.
	// The Analytics Core Reporting API returns a maximum of 100,000 rows
	// per
	// request, no matter how many you ask for. It can also return fewer
	// rows
	// than requested, if there aren't as many dimension segments as you
	// expect.
	// For instance, there are fewer than 300 possible values for
	// `ga:country`,
	// so when segmenting only by country, you can't get more than 300
	// rows,
	// even if you set `pageSize` to a higher value.
	PageSize int64 `json:"pageSize,omitempty"`

	// PageToken: A continuation token to get the next page of the results.
	// Adding this to
	// the request will return the rows after the pageToken. The pageToken
	// should
	// be the value returned in the nextPageToken parameter in the response
	// to
	// the GetReports request.
	PageToken string `json:"pageToken,omitempty"`

	// Pivots: The pivot definitions. Requests can have a maximum of 2
	// pivots.
	Pivots []*Pivot `json:"pivots,omitempty"`

	// SamplingLevel: The desired
	// report
	// [sample](https://support.google.com/analytics/answer/2637192)
	// size.
	// If the the `samplingLevel` field is unspecified the `DEFAULT`
	// sampling
	// level is used. Every [ReportRequest](#ReportRequest) within
	// a
	// `batchGet` method must contain the same `samplingLevel` definition.
	// See
	// [developer
	// guide](/analytics/devguides/reporting/core/v4/basics#sampling)
	//  for details.
	//
	// Possible values:
	//   "SAMPLING_UNSPECIFIED" - If the `samplingLevel` field is
	// unspecified the `DEFAULT` sampling level
	// is used.
	//   "DEFAULT" - Returns response with a sample size that balances speed
	// and
	// accuracy.
	//   "SMALL" - It returns a fast response with a smaller sampling size.
	//   "LARGE" - Returns a more accurate response using a large sampling
	// size. But this
	// may result in response being slower.
	SamplingLevel string `json:"samplingLevel,omitempty"`

	// Segments: Segment the data returned for the request. A segment
	// definition helps look
	// at a subset of the segment request. A request can contain up to
	// four
	// segments. Every [ReportRequest](#ReportRequest) within a
	// `batchGet` method must contain the same `segments` definition.
	// Requests
	// with segments must have the `ga:segment` dimension.
	Segments []*Segment `json:"segments,omitempty"`

	// ViewId: The Analytics
	// [view ID](https://support.google.com/analytics/answer/1009618)
	// from which to retrieve data. Every
	// [ReportRequest](#ReportRequest)
	// within a `batchGet` method must contain the same `viewId`.
	ViewId string `json:"viewId,omitempty"`

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

// ReportRow: A row in the report.
type ReportRow struct {
	// Dimensions: List of requested dimensions.
	Dimensions []string `json:"dimensions,omitempty"`

	// Metrics: List of metrics for each requested DateRange.
	Metrics []*DateRangeValues `json:"metrics,omitempty"`

	// 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 *ReportRow) MarshalJSON() ([]byte, error) {
	type NoMethod ReportRow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResourceQuotasRemaining: The resource quota tokens remaining for the
// property after the request is
// completed.
type ResourceQuotasRemaining struct {
	// DailyQuotaTokensRemaining: Daily resource quota remaining remaining.
	DailyQuotaTokensRemaining int64 `json:"dailyQuotaTokensRemaining,omitempty"`

	// HourlyQuotaTokensRemaining: Hourly resource quota tokens remaining.
	HourlyQuotaTokensRemaining int64 `json:"hourlyQuotaTokensRemaining,omitempty"`

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

type ScreenviewData struct {
	// AppName: The application name.
	AppName string `json:"appName,omitempty"`

	// MobileDeviceBranding: Mobile manufacturer or branded name. Eg:
	// "Google", "Apple" etc.
	MobileDeviceBranding string `json:"mobileDeviceBranding,omitempty"`

	// MobileDeviceModel: Mobile device model. Eg: "Pixel", "iPhone" etc.
	MobileDeviceModel string `json:"mobileDeviceModel,omitempty"`

	// ScreenName: The name of the screen.
	ScreenName string `json:"screenName,omitempty"`

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

// SearchUserActivityRequest: The request to fetch User Report from
// Reporting API `userActivity:get` call.
type SearchUserActivityRequest struct {
	// ActivityTypes: Set of all activity types being requested. Only
	// acvities matching these
	// types will be returned in the response. If empty, all activies will
	// be
	// returned.
	//
	// Possible values:
	//   "ACTIVITY_TYPE_UNSPECIFIED" - ActivityType will never have this
	// value in the response. Using this type in
	// the request will result in an error.
	//   "PAGEVIEW" - Used when the activity resulted out of a visitor
	// viewing a page.
	//   "SCREENVIEW" - Used when the activity resulted out of a visitor
	// using an application on a
	// mobile device.
	//   "GOAL" - Used to denote that a goal type activity.
	//   "ECOMMERCE" - An e-commerce transaction was performed by the
	// visitor on the page.
	//   "EVENT" - Used when the activity is an event.
	ActivityTypes []string `json:"activityTypes,omitempty"`

	// DateRange: Date range for which to retrieve the user activity. If a
	// date range is not
	// provided, the default date range is (startDate: current date - 7
	// days,
	// endDate: current date - 1 day).
	DateRange *DateRange `json:"dateRange,omitempty"`

	// PageSize: Page size is for paging and specifies the maximum number of
	// returned rows.
	// Page size should be > 0. If the value is 0 or if the field isn't
	// specified,
	// the request returns the default of 1000 rows per page.
	PageSize int64 `json:"pageSize,omitempty"`

	// PageToken: A continuation token to get the next page of the results.
	// Adding this to
	// the request will return the rows after the pageToken. The pageToken
	// should
	// be the value returned in the nextPageToken parameter in the response
	// to
	// the [SearchUserActivityRequest](#SearchUserActivityRequest) request.
	PageToken string `json:"pageToken,omitempty"`

	// User: Required. Unique user Id to query for.
	// Every
	// [SearchUserActivityRequest](#SearchUserActivityRequest) must contain
	// this
	// field.
	User *User `json:"user,omitempty"`

	// ViewId: Required. The Analytics
	// [view ID](https://support.google.com/analytics/answer/1009618)
	// from which to retrieve data.
	// Every
	// [SearchUserActivityRequest](#SearchUserActivityRequest) must contain
	// the
	// `viewId`.
	ViewId string `json:"viewId,omitempty"`

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

// SearchUserActivityResponse: The response from `userActivity:get`
// call.
type SearchUserActivityResponse struct {
	// NextPageToken: This token should be passed
	// to
	// [SearchUserActivityRequest](#SearchUserActivityRequest) to retrieve
	// the
	// next page.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// SampleRate: This field represents the
	// [sampling rate](https://support.google.com/analytics/answer/2637192)
	// for
	// the given request and is a number between 0.0 to 1.0. See
	// [developer
	// guide](/analytics/devguides/reporting/core/v4/basics#sampling)
	// for details.
	SampleRate float64 `json:"sampleRate,omitempty"`

	// Sessions: Each record represents a session (device details, duration,
	// etc).
	Sessions []*UserActivitySession `json:"sessions,omitempty"`

	// TotalRows: Total rows returned by this query (across different
	// pages).
	TotalRows int64 `json:"totalRows,omitempty"`

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

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

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

// Segment: The segment definition, if the report needs to be
// segmented.
// A Segment is a subset of the Analytics data. For example, of the
// entire
// set of users, one Segment might be users from a particular country or
// city.
type Segment struct {
	// DynamicSegment: A dynamic segment definition in the request.
	DynamicSegment *DynamicSegment `json:"dynamicSegment,omitempty"`

	// SegmentId: The segment ID of a built-in or custom segment, for
	// example `gaid::-3`.
	SegmentId string `json:"segmentId,omitempty"`

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

// SegmentDefinition: SegmentDefinition defines the segment to be a set
// of SegmentFilters which
// are combined together with a logical `AND` operation.
type SegmentDefinition struct {
	// SegmentFilters: A segment is defined by a set of segment filters
	// which are combined
	// together with a logical `AND` operation.
	SegmentFilters []*SegmentFilter `json:"segmentFilters,omitempty"`

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

// SegmentDimensionFilter: Dimension filter specifies the filtering
// options on a dimension.
type SegmentDimensionFilter struct {
	// CaseSensitive: Should the match be case sensitive, ignored for
	// `IN_LIST` operator.
	CaseSensitive bool `json:"caseSensitive,omitempty"`

	// DimensionName: Name of the dimension for which the filter is being
	// applied.
	DimensionName string `json:"dimensionName,omitempty"`

	// Expressions: The list of expressions, only the first element is used
	// for all operators
	Expressions []string `json:"expressions,omitempty"`

	// MaxComparisonValue: Maximum comparison values for `BETWEEN` match
	// type.
	MaxComparisonValue string `json:"maxComparisonValue,omitempty"`

	// MinComparisonValue: Minimum comparison values for `BETWEEN` match
	// type.
	MinComparisonValue string `json:"minComparisonValue,omitempty"`

	// Operator: The operator to use to match the dimension with the
	// expressions.
	//
	// Possible values:
	//   "OPERATOR_UNSPECIFIED" - If the match type is unspecified, it is
	// treated as a REGEXP.
	//   "REGEXP" - The match expression is treated as a regular expression.
	// All other match
	// types are not treated as regular expressions.
	//   "BEGINS_WITH" - Matches the values which begin with the match
	// expression provided.
	//   "ENDS_WITH" - Matches the values which end with the match
	// expression provided.
	//   "PARTIAL" - Substring match.
	//   "EXACT" - The value should match the match expression entirely.
	//   "IN_LIST" - This option is used to specify a dimension filter whose
	// expression can
	// take any value from a selected list of values. This helps
	// avoiding
	// evaluating multiple exact match dimension filters which are OR'ed
	// for
	// every single response row. For example:
	//
	//     expressions: ["A", "B", "C"]
	//
	// Any response row whose dimension has it is value as A, B or C,
	// matches
	// this DimensionFilter.
	//   "NUMERIC_LESS_THAN" - Integer comparison filters.
	// case sensitivity is ignored for these and the expression
	// is assumed to be a string representing an integer.
	// Failure conditions:
	//
	// - if expression is not a valid int64, the client should expect
	//   an error.
	// - input dimensions that are not valid int64 values will never match
	// the
	//   filter.
	//
	// Checks if the dimension is numerically less than the match
	// expression.
	//   "NUMERIC_GREATER_THAN" - Checks if the dimension is numerically
	// greater than the match
	// expression.
	//   "NUMERIC_BETWEEN" - Checks if the dimension is numerically between
	// the minimum and maximum
	// of the match expression, boundaries excluded.
	Operator string `json:"operator,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 *SegmentDimensionFilter) MarshalJSON() ([]byte, error) {
	type NoMethod SegmentDimensionFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SegmentFilter: SegmentFilter defines the segment to be either a
// simple or a sequence
// segment. A simple segment condition contains dimension and metric
// conditions
// to select the sessions or users. A sequence segment condition can be
// used to
// select users or sessions based on sequential conditions.
type SegmentFilter struct {
	// Not: If true, match the complement of simple or sequence segment.
	// For example, to match all visits not from "New York", we can define
	// the
	// segment as follows:
	//
	//       "sessionSegment": {
	//         "segmentFilters": [{
	//           "simpleSegment" :{
	//             "orFiltersForSegment": [{
	//               "segmentFilterClauses":[{
	//                 "dimensionFilter": {
	//                   "dimensionName": "ga:city",
	//                   "expressions": ["New York"]
	//                 }
	//               }]
	//             }]
	//           },
	//           "not": "True"
	//         }]
	//       },
	Not bool `json:"not,omitempty"`

	// SequenceSegment: Sequence conditions consist of one or more steps,
	// where each step is
	// defined by one or more dimension/metric conditions. Multiple steps
	// can
	// be combined with special sequence operators.
	SequenceSegment *SequenceSegment `json:"sequenceSegment,omitempty"`

	// SimpleSegment: A Simple segment conditions consist of one or more
	// dimension/metric
	// conditions that can be combined
	SimpleSegment *SimpleSegment `json:"simpleSegment,omitempty"`

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

// SegmentFilterClause: Filter Clause to be used in a segment
// definition, can be wither a metric or
// a dimension filter.
type SegmentFilterClause struct {
	// DimensionFilter: Dimension Filter for the segment definition.
	DimensionFilter *SegmentDimensionFilter `json:"dimensionFilter,omitempty"`

	// MetricFilter: Metric Filter for the segment definition.
	MetricFilter *SegmentMetricFilter `json:"metricFilter,omitempty"`

	// Not: Matches the complement (`!`) of the filter.
	Not bool `json:"not,omitempty"`

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

// SegmentMetricFilter: Metric filter to be used in a segment filter
// clause.
type SegmentMetricFilter struct {
	// ComparisonValue: The value to compare against. If the operator is
	// `BETWEEN`, this value is
	// treated as minimum comparison value.
	ComparisonValue string `json:"comparisonValue,omitempty"`

	// MaxComparisonValue: Max comparison value is only used for `BETWEEN`
	// operator.
	MaxComparisonValue string `json:"maxComparisonValue,omitempty"`

	// MetricName: The metric that will be filtered on. A `metricFilter`
	// must contain a
	// metric name.
	MetricName string `json:"metricName,omitempty"`

	// Operator: Specifies is the operation to perform to compare the
	// metric. The default
	// is `EQUAL`.
	//
	// Possible values:
	//   "UNSPECIFIED_OPERATOR" - Unspecified operator is treated as
	// `LESS_THAN` operator.
	//   "LESS_THAN" - Checks if the metric value is less than comparison
	// value.
	//   "GREATER_THAN" - Checks if the metric value is greater than
	// comparison value.
	//   "EQUAL" - Equals operator.
	//   "BETWEEN" - For between operator, both the minimum and maximum are
	// exclusive.
	// We will use `LT` and `GT` for comparison.
	Operator string `json:"operator,omitempty"`

	// Scope: Scope for a metric defines the level at which that metric is
	// defined.  The
	// specified metric scope must be equal to or greater than its primary
	// scope
	// as defined in the data model. The primary scope is defined by if
	// the
	// segment is selecting users or sessions.
	//
	// Possible values:
	//   "UNSPECIFIED_SCOPE" - If the scope is unspecified, it defaults to
	// the condition scope,
	// `USER` or `SESSION` depending on if the segment is trying to
	// choose
	// users or sessions.
	//   "PRODUCT" - Product scope.
	//   "HIT" - Hit scope.
	//   "SESSION" - Session scope.
	//   "USER" - User scope.
	Scope string `json:"scope,omitempty"`

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

// SegmentSequenceStep: A segment sequence definition.
type SegmentSequenceStep struct {
	// MatchType: Specifies if the step immediately precedes or can be any
	// time before the
	// next step.
	//
	// Possible values:
	//   "UNSPECIFIED_MATCH_TYPE" - Unspecified match type is treated as
	// precedes.
	//   "PRECEDES" - Operator indicates that the previous step precedes the
	// next step.
	//   "IMMEDIATELY_PRECEDES" - Operator indicates that the previous step
	// immediately precedes the next
	// step.
	MatchType string `json:"matchType,omitempty"`

	// OrFiltersForSegment: A sequence is specified with a list of Or
	// grouped filters which are
	// combined with `AND` operator.
	OrFiltersForSegment []*OrFiltersForSegment `json:"orFiltersForSegment,omitempty"`

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

// SequenceSegment: Sequence conditions consist of one or more steps,
// where each step is defined
// by one or more dimension/metric conditions. Multiple steps can be
// combined
// with special sequence operators.
type SequenceSegment struct {
	// FirstStepShouldMatchFirstHit: If set, first step condition must match
	// the first hit of the visitor (in
	// the date range).
	FirstStepShouldMatchFirstHit bool `json:"firstStepShouldMatchFirstHit,omitempty"`

	// SegmentSequenceSteps: The list of steps in the sequence.
	SegmentSequenceSteps []*SegmentSequenceStep `json:"segmentSequenceSteps,omitempty"`

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

// SimpleSegment: A Simple segment conditions consist of one or more
// dimension/metric
// conditions that can be combined.
type SimpleSegment struct {
	// OrFiltersForSegment: A list of segment filters groups which are
	// combined with logical `AND`
	// operator.
	OrFiltersForSegment []*OrFiltersForSegment `json:"orFiltersForSegment,omitempty"`

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

// TransactionData: Represents details collected when the visitor
// performs a transaction on the
// page.
type TransactionData struct {
	// TransactionId: The transaction ID, supplied by the e-commerce
	// tracking method, for the
	// purchase in the shopping cart.
	TransactionId string `json:"transactionId,omitempty"`

	// TransactionRevenue: The total sale revenue (excluding shipping and
	// tax) of the transaction.
	TransactionRevenue float64 `json:"transactionRevenue,omitempty"`

	// TransactionShipping: Total cost of shipping.
	TransactionShipping float64 `json:"transactionShipping,omitempty"`

	// TransactionTax: Total tax for the transaction.
	TransactionTax float64 `json:"transactionTax,omitempty"`

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

func (s *TransactionData) UnmarshalJSON(data []byte) error {
	type NoMethod TransactionData
	var s1 struct {
		TransactionRevenue  gensupport.JSONFloat64 `json:"transactionRevenue"`
		TransactionShipping gensupport.JSONFloat64 `json:"transactionShipping"`
		TransactionTax      gensupport.JSONFloat64 `json:"transactionTax"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.TransactionRevenue = float64(s1.TransactionRevenue)
	s.TransactionShipping = float64(s1.TransactionShipping)
	s.TransactionTax = float64(s1.TransactionTax)
	return nil
}

// User: Contains information to identify a particular user uniquely.
type User struct {
	// Type: Type of the user in the request. The field `userId` is
	// associated with this
	// type.
	//
	// Possible values:
	//   "USER_ID_TYPE_UNSPECIFIED" - When the User Id Type is not
	// specified, the default type used will be
	// CLIENT_ID.
	//   "USER_ID" - A single user, like a signed-in user account, that may
	// interact with
	// content across one or more devices and / or browser instances.
	//   "CLIENT_ID" - Analytics assigned client_id.
	Type string `json:"type,omitempty"`

	// UserId: Unique Id of the user for which the data is being requested.
	UserId string `json:"userId,omitempty"`

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

// UserActivitySession: This represents a user session performed on a
// specific device at a certain
// time over a period of time.
type UserActivitySession struct {
	// Activities: Represents a detailed view into each of the activity in
	// this session.
	Activities []*Activity `json:"activities,omitempty"`

	// DataSource: The data source of a hit. By default, hits sent from
	// analytics.js are
	// reported as "web" and hits sent from the mobile SDKs are reported as
	// "app".
	// These values can be overridden in the Measurement Protocol.
	DataSource string `json:"dataSource,omitempty"`

	// DeviceCategory: The type of device used: "mobile", "tablet" etc.
	DeviceCategory string `json:"deviceCategory,omitempty"`

	// Platform: Platform on which the activity happened: "android", "ios"
	// etc.
	Platform string `json:"platform,omitempty"`

	// SessionDate: Date of this session in ISO-8601 format.
	SessionDate string `json:"sessionDate,omitempty"`

	// SessionId: Unique ID of the session.
	SessionId string `json:"sessionId,omitempty"`

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

// method id "analyticsreporting.reports.batchGet":

type ReportsBatchGetCall struct {
	s                 *Service
	getreportsrequest *GetReportsRequest
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// BatchGet: Returns the Analytics data.
func (r *ReportsService) BatchGet(getreportsrequest *GetReportsRequest) *ReportsBatchGetCall {
	c := &ReportsBatchGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.getreportsrequest = getreportsrequest
	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 *ReportsBatchGetCall) Fields(s ...googleapi.Field) *ReportsBatchGetCall {
	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 *ReportsBatchGetCall) Context(ctx context.Context) *ReportsBatchGetCall {
	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 *ReportsBatchGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsBatchGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191122")
	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.getreportsrequest)
	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, "v4/reports:batchGet")
	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 "analyticsreporting.reports.batchGet" call.
// Exactly one of *GetReportsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GetReportsResponse.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 *ReportsBatchGetCall) Do(opts ...googleapi.CallOption) (*GetReportsResponse, 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 := &GetReportsResponse{
		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 the Analytics data.",
	//   "flatPath": "v4/reports:batchGet",
	//   "httpMethod": "POST",
	//   "id": "analyticsreporting.reports.batchGet",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v4/reports:batchGet",
	//   "request": {
	//     "$ref": "GetReportsRequest"
	//   },
	//   "response": {
	//     "$ref": "GetReportsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/analytics",
	//     "https://www.googleapis.com/auth/analytics.readonly"
	//   ]
	// }

}

// method id "analyticsreporting.userActivity.search":

type UserActivitySearchCall struct {
	s                         *Service
	searchuseractivityrequest *SearchUserActivityRequest
	urlParams_                gensupport.URLParams
	ctx_                      context.Context
	header_                   http.Header
}

// Search: Returns User Activity data.
func (r *UserActivityService) Search(searchuseractivityrequest *SearchUserActivityRequest) *UserActivitySearchCall {
	c := &UserActivitySearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.searchuseractivityrequest = searchuseractivityrequest
	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 *UserActivitySearchCall) Fields(s ...googleapi.Field) *UserActivitySearchCall {
	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 *UserActivitySearchCall) Context(ctx context.Context) *UserActivitySearchCall {
	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 *UserActivitySearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserActivitySearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191122")
	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.searchuseractivityrequest)
	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, "v4/userActivity:search")
	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 "analyticsreporting.userActivity.search" call.
// Exactly one of *SearchUserActivityResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *SearchUserActivityResponse.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 *UserActivitySearchCall) Do(opts ...googleapi.CallOption) (*SearchUserActivityResponse, 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 := &SearchUserActivityResponse{
		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 User Activity data.",
	//   "flatPath": "v4/userActivity:search",
	//   "httpMethod": "POST",
	//   "id": "analyticsreporting.userActivity.search",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v4/userActivity:search",
	//   "request": {
	//     "$ref": "SearchUserActivityRequest"
	//   },
	//   "response": {
	//     "$ref": "SearchUserActivityResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/analytics",
	//     "https://www.googleapis.com/auth/analytics.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *UserActivitySearchCall) Pages(ctx context.Context, f func(*SearchUserActivityResponse) error) error {
	c.ctx_ = ctx
	defer func(pt string) { c.searchuseractivityrequest.PageToken = pt }(c.searchuseractivityrequest.PageToken) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.searchuseractivityrequest.PageToken = x.NextPageToken
	}
}
