// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.analytics.data.v1beta;

option go_package = "google.golang.org/genproto/googleapis/analytics/data/v1beta;data";
option java_multiple_files = true;
option java_outer_classname = "ReportingApiProto";
option java_package = "com.google.analytics.data.v1beta";

// A contiguous set of days: `startDate`, `startDate + 1`, ..., `endDate`.
// Requests are allowed up to 4 date ranges.
message DateRange {
  // The inclusive start date for the query in the format `YYYY-MM-DD`. Cannot
  // be after `end_date`. The format `NdaysAgo`, `yesterday`, or `today` is also
  // accepted, and in that case, the date is inferred based on the property's
  // reporting time zone.
  string start_date = 1;

  // The inclusive end date for the query in the format `YYYY-MM-DD`. Cannot
  // be before `start_date`. The format `NdaysAgo`, `yesterday`, or `today` is
  // also accepted, and in that case, the date is inferred based on the
  // property's reporting time zone.
  string end_date = 2;

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

// A contiguous set of minutes: `startMinutesAgo`, `startMinutesAgo + 1`, ...,
// `endMinutesAgo`. Requests are allowed up to 2 minute ranges.
message MinuteRange {
  // The inclusive start minute for the query as a number of minutes before now.
  // For example, `"startMinutesAgo": 29` specifies the report should include
  // event data from 29 minutes ago and after. Cannot be after `endMinutesAgo`.
  //
  // If unspecified, `startMinutesAgo` is defaulted to 29. Standard Analytics
  // properties can request up to the last 30 minutes of event data
  // (`startMinutesAgo <= 29`), and 360 Analytics properties can request up to
  // the last 60 minutes of event data (`startMinutesAgo <= 59`).
  optional int32 start_minutes_ago = 1;

  // The inclusive end minute for the query as a number of minutes before now.
  // Cannot be before `startMinutesAgo`. For example, `"endMinutesAgo": 15`
  // specifies the report should include event data from prior to 15 minutes
  // ago.
  //
  // If unspecified, `endMinutesAgo` is defaulted to 0. Standard Analytics
  // properties can request any minute in the last 30 minutes of event data
  // (`endMinutesAgo <= 29`), and 360 Analytics properties can request any
  // minute in the last 60 minutes of event data (`endMinutesAgo <= 59`).
  optional int32 end_minutes_ago = 2;

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

// Dimensions are attributes of your data. For example, the dimension city
// indicates the city from which an event originates. Dimension values in report
// responses are strings; for example, the city could be "Paris" or "New York".
// Requests are allowed up to 9 dimensions.
message Dimension {
  // The name of the dimension. See the [API
  // Dimensions](https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema#dimensions)
  // for the list of dimension names.
  //
  // If `dimensionExpression` is specified, `name` can be any string that you
  // would like within the allowed character set. For example if a
  // `dimensionExpression` concatenates `country` and `city`, you could call
  // that dimension `countryAndCity`. Dimension names that you choose must match
  // the regular expression `^[a-zA-Z0-9_]$`.
  //
  // Dimensions are referenced by `name` in `dimensionFilter`, `orderBys`,
  // `dimensionExpression`, and `pivots`.
  string name = 1;

  // One dimension can be the result of an expression of multiple dimensions.
  // For example, dimension "country, city": concatenate(country, ", ", city).
  DimensionExpression dimension_expression = 2;
}

// Used to express a dimension which is the result of a formula of multiple
// dimensions. Example usages:
// 1) lower_case(dimension)
// 2) concatenate(dimension1, symbol, dimension2).
message DimensionExpression {
  // Used to convert a dimension value to a single case.
  message CaseExpression {
    // Name of a dimension. The name must refer back to a name in dimensions
    // field of the request.
    string dimension_name = 1;
  }

  // Used to combine dimension values to a single dimension.
  message ConcatenateExpression {
    // Names of dimensions. The names must refer back to names in the dimensions
    // field of the request.
    repeated string dimension_names = 1;

    // The delimiter placed between dimension names.
    //
    // Delimiters are often single characters such as "|" or "," but can be
    // longer strings. If a dimension value contains the delimiter, both will be
    // present in response with no distinction. For example if dimension 1 value
    // = "US,FR", dimension 2 value = "JP", and delimiter = ",", then the
    // response will contain "US,FR,JP".
    string delimiter = 2;
  }

  // Specify one type of dimension expression for `DimensionExpression`.
  oneof one_expression {
    // Used to convert a dimension value to lower case.
    CaseExpression lower_case = 4;

    // Used to convert a dimension value to upper case.
    CaseExpression upper_case = 5;

    // Used to combine dimension values to a single dimension.
    // For example, dimension "country, city": concatenate(country, ", ", city).
    ConcatenateExpression concatenate = 6;
  }
}

// The quantitative measurements of a report. For example, the metric
// `eventCount` is the total number of events. Requests are allowed up to 10
// metrics.
message Metric {
  // The name of the metric. See the [API
  // Metrics](https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema#metrics)
  // for the list of metric names.
  //
  // If `expression` is specified, `name` can be any string that you would like
  // within the allowed character set. For example if `expression` is
  // `screenPageViews/sessions`, you could call that metric's name =
  // `viewsPerSession`. Metric names that you choose must match the regular
  // expression `^[a-zA-Z0-9_]$`.
  //
  // Metrics are referenced by `name` in `metricFilter`, `orderBys`, and metric
  // `expression`.
  string name = 1;

  // A mathematical expression for derived metrics. For example, the metric
  // Event count per user is `eventCount/totalUsers`.
  string expression = 2;

  // Indicates if a metric is invisible in the report response. If a metric is
  // invisible, the metric will not produce a column in the response, but can be
  // used in `metricFilter`, `orderBys`, or a metric `expression`.
  bool invisible = 3;
}

// To express dimension or metric filters. The fields in the same
// FilterExpression need to be either all dimensions or all metrics.
message FilterExpression {
  // Specify one type of filter expression for `FilterExpression`.
  oneof expr {
    // The FilterExpressions in and_group have an AND relationship.
    FilterExpressionList and_group = 1;

    // The FilterExpressions in or_group have an OR relationship.
    FilterExpressionList or_group = 2;

    // The FilterExpression is NOT of not_expression.
    FilterExpression not_expression = 3;

    // A primitive filter. In the same FilterExpression, all of the filter's
    // field names need to be either all dimensions or all metrics.
    Filter filter = 4;
  }
}

// A list of filter expressions.
message FilterExpressionList {
  // A list of filter expressions.
  repeated FilterExpression expressions = 1;
}

// An expression to filter dimension or metric values.
message Filter {
  // The filter for string
  message StringFilter {
    // The match type of a string filter
    enum MatchType {
      // Unspecified
      MATCH_TYPE_UNSPECIFIED = 0;

      // Exact match of the string value.
      EXACT = 1;

      // Begins with the string value.
      BEGINS_WITH = 2;

      // Ends with the string value.
      ENDS_WITH = 3;

      // Contains the string value.
      CONTAINS = 4;

      // Full match for the regular expression with the string value.
      FULL_REGEXP = 5;

      // Partial match for the regular expression with the string value.
      PARTIAL_REGEXP = 6;
    }

    // The match type for this filter.
    MatchType match_type = 1;

    // The string value used for the matching.
    string value = 2;

    // If true, the string value is case sensitive.
    bool case_sensitive = 3;
  }

  // The result needs to be in a list of string values.
  message InListFilter {
    // The list of string values.
    // Must be non-empty.
    repeated string values = 1;

    // If true, the string value is case sensitive.
    bool case_sensitive = 2;
  }

  // Filters for numeric or date values.
  message NumericFilter {
    // The operation applied to a numeric filter
    enum Operation {
      // Unspecified.
      OPERATION_UNSPECIFIED = 0;

      // Equal
      EQUAL = 1;

      // Less than
      LESS_THAN = 2;

      // Less than or equal
      LESS_THAN_OR_EQUAL = 3;

      // Greater than
      GREATER_THAN = 4;

      // Greater than or equal
      GREATER_THAN_OR_EQUAL = 5;
    }

    // The operation type for this filter.
    Operation operation = 1;

    // A numeric value or a date value.
    NumericValue value = 2;
  }

  // To express that the result needs to be between two numbers (inclusive).
  message BetweenFilter {
    // Begins with this number.
    NumericValue from_value = 1;

    // Ends with this number.
    NumericValue to_value = 2;
  }

  // The dimension name or metric name.
  //
  // In most methods, dimensions & metrics can be used for the first time in
  // this field. However in a RunPivotReportRequest, this field must be
  // additionally specified by name in the RunPivotReportRequest's dimensions or
  // metrics.
  string field_name = 1;

  // Specify one type of filter for `Filter`.
  oneof one_filter {
    // Strings related filter.
    StringFilter string_filter = 3;

    // A filter for in list values.
    InListFilter in_list_filter = 4;

    // A filter for numeric or date values.
    NumericFilter numeric_filter = 5;

    // A filter for two values.
    BetweenFilter between_filter = 6;
  }
}

// Order bys define how rows will be sorted in the response. For example,
// ordering rows by descending event count is one ordering, and ordering rows by
// the event name string is a different ordering.
message OrderBy {
  // Sorts by metric values.
  message MetricOrderBy {
    // A metric name in the request to order by.
    string metric_name = 1;
  }

  // Sorts by dimension values.
  message DimensionOrderBy {
    // Rule to order the string dimension values by.
    enum OrderType {
      // Unspecified.
      ORDER_TYPE_UNSPECIFIED = 0;

      // Alphanumeric sort by Unicode code point. For example, "2" < "A" < "X" <
      // "b" < "z".
      ALPHANUMERIC = 1;

      // Case insensitive alphanumeric sort by lower case Unicode code point.
      // For example, "2" < "A" < "b" < "X" < "z".
      CASE_INSENSITIVE_ALPHANUMERIC = 2;

      // Dimension values are converted to numbers before sorting. For example
      // in NUMERIC sort, "25" < "100", and in `ALPHANUMERIC` sort, "100" <
      // "25". Non-numeric dimension values all have equal ordering value below
      // all numeric values.
      NUMERIC = 3;
    }

    // A dimension name in the request to order by.
    string dimension_name = 1;

    // Controls the rule for dimension value ordering.
    OrderType order_type = 2;
  }

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

      // Order by only when the named dimension is this value.
      string dimension_value = 2;
    }

    // In the response to order by, order rows by this column. Must be a metric
    // name from the request.
    string metric_name = 1;

    // Used to select a dimension name and value pivot. If multiple pivot
    // selections are given, the sort occurs on rows where all pivot selection
    // dimension name and value pairs match the row's dimension name and value
    // pair.
    repeated PivotSelection pivot_selections = 2;
  }

  // Specify one type of order by for `OrderBy`.
  oneof one_order_by {
    // Sorts results by a metric's values.
    MetricOrderBy metric = 1;

    // Sorts results by a dimension's values.
    DimensionOrderBy dimension = 2;

    // Sorts results by a metric's values within a pivot column group.
    PivotOrderBy pivot = 3;
  }

  // If true, sorts by descending order.
  bool desc = 4;
}

// Describes the visible dimension columns and rows in the report response.
message Pivot {
  // Dimension names for visible columns in the report response. Including
  // "dateRange" produces a date range column; for each row in the response,
  // dimension values in the date range column will indicate the corresponding
  // date range from the request.
  repeated string field_names = 1;

  // Specifies how dimensions are ordered in the pivot. In the first Pivot, the
  // OrderBys determine Row and PivotDimensionHeader ordering; in subsequent
  // Pivots, the OrderBys determine only PivotDimensionHeader ordering.
  // Dimensions specified in these OrderBys must be a subset of
  // Pivot.field_names.
  repeated OrderBy order_bys = 2;

  // The row count of the start row. The first row is counted as row 0.
  int64 offset = 3;

  // The number of unique combinations of dimension values to return in this
  // pivot. The `limit` parameter is required. A `limit` of 10,000 is common for
  // single pivot requests.
  //
  // The product of the `limit` for each `pivot` in a `RunPivotReportRequest`
  // must not exceed 250,000. For example, a two pivot request with `limit:
  // 1000` in each pivot will fail because the product is `1,000,000`.
  int64 limit = 4;

  // Aggregate the metrics by dimensions in this pivot using the specified
  // metric_aggregations.
  repeated MetricAggregation metric_aggregations = 5;
}

// The specification of cohorts for a cohort report.
//
// Cohort reports create a time series of user retention for the cohort. For
// example, you could select the cohort of users that were acquired in the first
// week of September and follow that cohort for the next six weeks. Selecting
// the users acquired in the first week of September cohort is specified in the
// `cohort` object. Following that cohort for the next six weeks is specified in
// the `cohortsRange` object.
//
// For examples, see [Cohort Report
// Examples](https://developers.google.com/analytics/devguides/reporting/data/v1/advanced#cohort_report_examples).
//
// The report response could show a weekly time series where say your app has
// retained 60% of this cohort after three weeks and 25% of this cohort after
// six weeks. These two percentages can be calculated by the metric
// `cohortActiveUsers/cohortTotalUsers` and will be separate rows in the report.
message CohortSpec {
  // Defines the selection criteria to group users into cohorts.
  //
  // Most cohort reports define only a single cohort. If multiple cohorts are
  // specified, each cohort can be recognized in the report by their name.
  repeated Cohort cohorts = 1;

  // Cohort reports follow cohorts over an extended reporting date range. This
  // range specifies an offset duration to follow the cohorts over.
  CohortsRange cohorts_range = 2;

  // Optional settings for a cohort report.
  CohortReportSettings cohort_report_settings = 3;
}

// Defines a cohort selection criteria. A cohort is a group of users who share
// a common characteristic. For example, users with the same `firstSessionDate`
// belong to the same cohort.
message Cohort {
  // Assigns a name to this cohort. The dimension `cohort` is valued to this
  // name in a report response. If set, cannot begin with `cohort_` or
  // `RESERVED_`. If not set, cohorts are named by their zero based index
  // `cohort_0`, `cohort_1`, etc.
  string name = 1;

  // Dimension used by the cohort. Required and only supports
  // `firstSessionDate`.
  string dimension = 2;

  // The cohort selects users whose first touch date is between start date and
  // end date defined in the `dateRange`. This `dateRange` does not specify the
  // full date range of event data that is present in a cohort report. In a
  // cohort report, this `dateRange` is extended by the granularity and offset
  // present in the `cohortsRange`; event data for the extended reporting date
  // range is present in a cohort report.
  //
  // In a cohort request, this `dateRange` is required and the `dateRanges` in
  // the `RunReportRequest` or `RunPivotReportRequest` must be unspecified.
  //
  // This `dateRange` should generally be aligned with the cohort's granularity.
  // If `CohortsRange` uses daily granularity, this `dateRange` can be a single
  // day. If `CohortsRange` uses weekly granularity, this `dateRange` can be
  // aligned to a week boundary, starting at Sunday and ending Saturday. If
  // `CohortsRange` uses monthly granularity, this `dateRange` can be aligned to
  // a month, starting at the first and ending on the last day of the month.
  DateRange date_range = 3;
}

// Configures the extended reporting date range for a cohort report. Specifies
// an offset duration to follow the cohorts over.
message CohortsRange {
  // The granularity used to interpret the `startOffset` and `endOffset` for the
  // extended reporting date range for a cohort report.
  enum Granularity {
    // Should never be specified.
    GRANULARITY_UNSPECIFIED = 0;

    // Daily granularity. Commonly used if the cohort's `dateRange` is a single
    // day and the request contains `cohortNthDay`.
    DAILY = 1;

    // Weekly granularity. Commonly used if the cohort's `dateRange` is a week
    // in duration (starting on Sunday and ending on Saturday) and the request
    // contains `cohortNthWeek`.
    WEEKLY = 2;

    // Monthly granularity. Commonly used if the cohort's `dateRange` is a month
    // in duration and the request contains `cohortNthMonth`.
    MONTHLY = 3;
  }

  // Required. The granularity used to interpret the `startOffset` and
  // `endOffset` for the extended reporting date range for a cohort report.
  Granularity granularity = 1;

  // `startOffset` specifies the start date of the extended reporting date range
  // for a cohort report. `startOffset` is commonly set to 0 so that reports
  // contain data from the acquisition of the cohort forward.
  //
  // If `granularity` is `DAILY`, the `startDate` of the extended reporting date
  // range is `startDate` of the cohort plus `startOffset` days.
  //
  // If `granularity` is `WEEKLY`, the `startDate` of the extended reporting
  // date range is `startDate` of the cohort plus `startOffset * 7` days.
  //
  // If `granularity` is `MONTHLY`, the `startDate` of the extended reporting
  // date range is `startDate` of the cohort plus `startOffset * 30` days.
  int32 start_offset = 2;

  // Required. `endOffset` specifies the end date of the extended reporting date
  // range for a cohort report. `endOffset` can be any positive integer but is
  // commonly set to 5 to 10 so that reports contain data on the cohort for the
  // next several granularity time periods.
  //
  // If `granularity` is `DAILY`, the `endDate` of the extended reporting date
  // range is `endDate` of the cohort plus `endOffset` days.
  //
  // If `granularity` is `WEEKLY`, the `endDate` of the extended reporting date
  // range is `endDate` of the cohort plus `endOffset * 7` days.
  //
  // If `granularity` is `MONTHLY`, the `endDate` of the extended reporting date
  // range is `endDate` of the cohort plus `endOffset * 30` days.
  int32 end_offset = 3;
}

// Optional settings of a cohort report.
message CohortReportSettings {
  // If true, accumulates the result from first touch day to the end day. Not
  // supported in `RunReportRequest`.
  bool accumulate = 1;
}

// Response's metadata carrying additional information about the report content.
message ResponseMetaData {
  // The schema restrictions actively enforced in creating this report. To learn
  // more, see [Access and data-restriction
  // management](https://support.google.com/analytics/answer/10851388).
  message SchemaRestrictionResponse {
    // A metric actively restricted in creating the report.
    message ActiveMetricRestriction {
      // The name of the restricted metric.
      optional string metric_name = 1;

      // The reason for this metric's restriction.
      repeated RestrictedMetricType restricted_metric_types = 2;
    }

    // All restrictions actively enforced in creating the report. For example,
    // `purchaseRevenue` always has the restriction type `REVENUE_DATA`.
    // However, this active response restriction is only populated if the user's
    // custom role disallows access to `REVENUE_DATA`.
    repeated ActiveMetricRestriction active_metric_restrictions = 1;
  }

  // If true, indicates some buckets of dimension combinations are rolled into
  // "(other)" row. This can happen for high cardinality reports.
  //
  // The metadata parameter dataLossFromOtherRow is populated based on the
  // aggregated data table used in the report. The parameter will be accurately
  // populated regardless of the filters and limits in the report.
  //
  // For example, the (other) row could be dropped from the report because the
  // request contains a filter on sessionSource = google. This parameter will
  // still be populated if data loss from other row was present in the input
  // aggregate data used to generate this report.
  //
  // To learn more, see [About the (other) row and data
  // sampling](https://support.google.com/analytics/answer/13208658#reports).
  bool data_loss_from_other_row = 3;

  // Describes the schema restrictions actively enforced in creating this
  // report. To learn more, see [Access and data-restriction
  // management](https://support.google.com/analytics/answer/10851388).
  optional SchemaRestrictionResponse schema_restriction_response = 4;

  // The currency code used in this report. Intended to be used in formatting
  // currency metrics like `purchaseRevenue` for visualization. If currency_code
  // was specified in the request, this response parameter will echo the request
  // parameter; otherwise, this response parameter is the property's current
  // currency_code.
  //
  // Currency codes are string encodings of currency types from the ISO 4217
  // standard (https://en.wikipedia.org/wiki/ISO_4217); for example "USD",
  // "EUR", "JPY". To learn more, see
  // https://support.google.com/analytics/answer/9796179.
  optional string currency_code = 5;

  // The property's current timezone. Intended to be used to interpret
  // time-based dimensions like `hour` and `minute`. Formatted as strings from
  // the IANA Time Zone database (https://www.iana.org/time-zones); for example
  // "America/New_York" or "Asia/Tokyo".
  optional string time_zone = 6;

  // If empty reason is specified, the report is empty for this reason.
  optional string empty_reason = 7;

  // If `subjectToThresholding` is true, this report is subject to thresholding
  // and only returns data that meets the minimum aggregation thresholds. It is
  // possible for a request to be subject to thresholding thresholding and no
  // data is absent from the report, and this happens when all data is above the
  // thresholds. To learn more, see [Data
  // thresholds](https://support.google.com/analytics/answer/9383630) and [About
  // Demographics and
  // Interests](https://support.google.com/analytics/answer/2799357).
  optional bool subject_to_thresholding = 8;
}

// Describes a dimension column in the report. Dimensions requested in a report
// produce column entries within rows and DimensionHeaders. However, dimensions
// used exclusively within filters or expressions do not produce columns in a
// report; correspondingly, those dimensions do not produce headers.
message DimensionHeader {
  // The dimension's name.
  string name = 1;
}

// Describes a metric column in the report. Visible metrics requested in a
// report produce column entries within rows and MetricHeaders. However,
// metrics used exclusively within filters or expressions do not produce columns
// in a report; correspondingly, those metrics do not produce headers.
message MetricHeader {
  // The metric's name.
  string name = 1;

  // The metric's data type.
  MetricType type = 2;
}

// Dimensions' values in a single pivot.
message PivotHeader {
  // The size is the same as the cardinality of the corresponding dimension
  // combinations.
  repeated PivotDimensionHeader pivot_dimension_headers = 1;

  // The cardinality of the pivot. The total number of rows for this pivot's
  // fields regardless of how the parameters `offset` and `limit` are specified
  // in the request.
  int32 row_count = 2;
}

// Summarizes dimension values from a row for this pivot.
message PivotDimensionHeader {
  // Values of multiple dimensions in a pivot.
  repeated DimensionValue dimension_values = 1;
}

// Report data for each row.
// For example if RunReportRequest contains:
//
// ```none
// "dimensions": [
//   {
//     "name": "eventName"
//   },
//   {
//     "name": "countryId"
//   }
// ],
// "metrics": [
//   {
//     "name": "eventCount"
//   }
// ]
// ```
//
// One row with 'in_app_purchase' as the eventName, 'JP' as the countryId, and
// 15 as the eventCount, would be:
//
// ```none
// "dimensionValues": [
//   {
//     "value": "in_app_purchase"
//   },
//   {
//     "value": "JP"
//   }
// ],
// "metricValues": [
//   {
//     "value": "15"
//   }
// ]
// ```
message Row {
  // List of requested dimension values. In a PivotReport, dimension_values
  // are only listed for dimensions included in a pivot.
  repeated DimensionValue dimension_values = 1;

  // List of requested visible metric values.
  repeated MetricValue metric_values = 2;
}

// The value of a dimension.
message DimensionValue {
  // One kind of dimension value
  oneof one_value {
    // Value as a string if the dimension type is a string.
    string value = 1;
  }
}

// The value of a metric.
message MetricValue {
  // One of metric value
  oneof one_value {
    // Measurement value. See MetricHeader for type.
    string value = 4;
  }
}

// To represent a number.
message NumericValue {
  // One of a numeric value
  oneof one_value {
    // Integer value
    int64 int64_value = 1;

    // Double value
    double double_value = 2;
  }
}

// Current state of all quotas for this Analytics Property. If any quota for a
// property is exhausted, all requests to that property will return Resource
// Exhausted errors.
message PropertyQuota {
  // Standard Analytics Properties can use up to 200,000 tokens per day;
  // Analytics 360 Properties can use 2,000,000 tokens per day. Most requests
  // consume fewer than 10 tokens.
  QuotaStatus tokens_per_day = 1;

  // Standard Analytics Properties can use up to 40,000 tokens per hour;
  // Analytics 360 Properties can use 400,000 tokens per hour. An API request
  // consumes a single number of tokens, and that number is deducted from all of
  // the hourly, daily, and per project hourly quotas.
  QuotaStatus tokens_per_hour = 2;

  // Standard Analytics Properties can send up to 10 concurrent requests;
  // Analytics 360 Properties can use up to 50 concurrent requests.
  QuotaStatus concurrent_requests = 3;

  // Standard Analytics Properties and cloud project pairs can have up to 10
  // server errors per hour; Analytics 360 Properties and cloud project pairs
  // can have up to 50 server errors per hour.
  QuotaStatus server_errors_per_project_per_hour = 4;

  // Analytics Properties can send up to 120 requests with potentially
  // thresholded dimensions per hour. In a batch request, each report request
  // is individually counted for this quota if the request contains potentially
  // thresholded dimensions.
  QuotaStatus potentially_thresholded_requests_per_hour = 5;

  // Analytics Properties can use up to 35% of their tokens per project per
  // hour. This amounts to standard Analytics Properties can use up to 14,000
  // tokens per project per hour, and Analytics 360 Properties can use 140,000
  // tokens per project per hour. An API request consumes a single number of
  // tokens, and that number is deducted from all of the hourly, daily, and per
  // project hourly quotas.
  QuotaStatus tokens_per_project_per_hour = 6;
}

// Current state for a particular quota group.
message QuotaStatus {
  // Quota consumed by this request.
  int32 consumed = 1;

  // Quota remaining after this request.
  int32 remaining = 2;
}

// Explains a dimension.
message DimensionMetadata {
  // This dimension's name. Useable in [Dimension](#Dimension)'s `name`. For
  // example, `eventName`.
  string api_name = 1;

  // This dimension's name within the Google Analytics user interface. For
  // example, `Event name`.
  string ui_name = 2;

  // Description of how this dimension is used and calculated.
  string description = 3;

  // Still usable but deprecated names for this dimension. If populated, this
  // dimension is available by either `apiName` or one of `deprecatedApiNames`
  // for a period of time. After the deprecation period, the dimension will be
  // available only by `apiName`.
  repeated string deprecated_api_names = 4;

  // True if the dimension is a custom dimension for this property.
  bool custom_definition = 5;

  // The display name of the category that this dimension belongs to. Similar
  // dimensions and metrics are categorized together.
  string category = 7;
}

// Explains a metric.
message MetricMetadata {
  // Justifications for why this metric is blocked.
  enum BlockedReason {
    // Will never be specified in API response.
    BLOCKED_REASON_UNSPECIFIED = 0;

    // If present, your access is blocked to revenue related metrics for this
    // property, and this metric is revenue related.
    NO_REVENUE_METRICS = 1;

    // If present, your access is blocked to cost related metrics for this
    // property, and this metric is cost related.
    NO_COST_METRICS = 2;
  }

  // A metric name. Useable in [Metric](#Metric)'s `name`. For example,
  // `eventCount`.
  string api_name = 1;

  // This metric's name within the Google Analytics user interface. For example,
  // `Event count`.
  string ui_name = 2;

  // Description of how this metric is used and calculated.
  string description = 3;

  // Still usable but deprecated names for this metric. If populated, this
  // metric is available by either `apiName` or one of `deprecatedApiNames`
  // for a period of time. After the deprecation period, the metric will be
  // available only by `apiName`.
  repeated string deprecated_api_names = 4;

  // The type of this metric.
  MetricType type = 5;

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

  // True if the metric is a custom metric for this property.
  bool custom_definition = 7;

  // If reasons are specified, your access is blocked to this metric for this
  // property. API requests from you to this property for this metric will
  // succeed; however, the report will contain only zeros for this metric. API
  // requests with metric filters on blocked metrics will fail. If reasons are
  // empty, you have access to this metric.
  //
  // To learn more, see [Access and data-restriction
  // management](https://support.google.com/analytics/answer/10851388).
  repeated BlockedReason blocked_reasons = 8;

  // The display name of the category that this metrics belongs to. Similar
  // dimensions and metrics are categorized together.
  string category = 10;
}

// The compatibility for a single dimension.
message DimensionCompatibility {
  // The dimension metadata contains the API name for this compatibility
  // information. The dimension metadata also contains other helpful information
  // like the UI name and description.
  optional DimensionMetadata dimension_metadata = 1;

  // The compatibility of this dimension. If the compatibility is COMPATIBLE,
  // this dimension can be successfully added to the report.
  optional Compatibility compatibility = 2;
}

// The compatibility for a single metric.
message MetricCompatibility {
  // The metric metadata contains the API name for this compatibility
  // information. The metric metadata also contains other helpful information
  // like the UI name and description.
  optional MetricMetadata metric_metadata = 1;

  // The compatibility of this metric. If the compatibility is COMPATIBLE,
  // this metric can be successfully added to the report.
  optional Compatibility compatibility = 2;
}

// Represents aggregation of metrics.
enum MetricAggregation {
  // Unspecified operator.
  METRIC_AGGREGATION_UNSPECIFIED = 0;

  // SUM operator.
  TOTAL = 1;

  // Minimum operator.
  MINIMUM = 5;

  // Maximum operator.
  MAXIMUM = 6;

  // Count operator.
  COUNT = 4;
}

// A metric's value type.
enum MetricType {
  // Unspecified type.
  METRIC_TYPE_UNSPECIFIED = 0;

  // Integer type.
  TYPE_INTEGER = 1;

  // Floating point type.
  TYPE_FLOAT = 2;

  // A duration of seconds; a special floating point type.
  TYPE_SECONDS = 4;

  // A duration in milliseconds; a special floating point type.
  TYPE_MILLISECONDS = 5;

  // A duration in minutes; a special floating point type.
  TYPE_MINUTES = 6;

  // A duration in hours; a special floating point type.
  TYPE_HOURS = 7;

  // A custom metric of standard type; a special floating point type.
  TYPE_STANDARD = 8;

  // An amount of money; a special floating point type.
  TYPE_CURRENCY = 9;

  // A length in feet; a special floating point type.
  TYPE_FEET = 10;

  // A length in miles; a special floating point type.
  TYPE_MILES = 11;

  // A length in meters; a special floating point type.
  TYPE_METERS = 12;

  // A length in kilometers; a special floating point type.
  TYPE_KILOMETERS = 13;
}

// Categories of data that you may be restricted from viewing on certain GA4
// properties.
enum RestrictedMetricType {
  // Unspecified type.
  RESTRICTED_METRIC_TYPE_UNSPECIFIED = 0;

  // Cost metrics such as `adCost`.
  COST_DATA = 1;

  // Revenue metrics such as `purchaseRevenue`.
  REVENUE_DATA = 2;
}

// The compatibility types for a single dimension or metric.
enum Compatibility {
  // Unspecified compatibility.
  COMPATIBILITY_UNSPECIFIED = 0;

  // The dimension or metric is compatible. This dimension or metric can be
  // successfully added to a report.
  COMPATIBLE = 1;

  // The dimension or metric is incompatible. This dimension or metric cannot be
  // successfully added to a report.
  INCOMPATIBLE = 2;
}
