// Copyright 2026 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.devicesandservices.health.v4beta;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/devicesandservices/health/v4beta/data_coordinates.proto";
import "google/devicesandservices/health/v4beta/medical_device_info.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/type/date.proto";

option csharp_namespace = "Google.DevicesAndServices.Health.V4Beta";
option go_package = "google.golang.org/genproto/googleapis/devicesandservices/health/apiv4beta;healthpb";
option java_multiple_files = true;
option java_outer_classname = "DataModelProto";
option java_package = "com.google.devicesandservices.health.v4beta";
option php_namespace = "Google\\DevicesAndServices\\Health\\V4beta";
option ruby_package = "Google::DevicesAndServices::Health::V4beta";

// The heart rate zone type.
enum HeartRateZoneType {
  // Unspecified heart rate zone.
  HEART_RATE_ZONE_TYPE_UNSPECIFIED = 0;

  // The light heart rate zone.
  LIGHT = 1;

  // The moderate heart rate zone.
  MODERATE = 2;

  // The vigorous heart rate zone.
  VIGOROUS = 3;

  // The peak heart rate zone.
  PEAK = 4;
}

// Enum representing the access level of a food item.
enum FoodAccessLevel {
  // Unspecified food access level.
  FOOD_ACCESS_LEVEL_UNSPECIFIED = 0;

  // Public food access level.
  FOOD_ACCESS_LEVEL_PUBLIC = 1;

  // Private food access level.
  FOOD_ACCESS_LEVEL_PRIVATE = 2;
}

// Enum representing the meal type.
enum MealType {
  // Unspecified meal type.
  MEAL_TYPE_UNSPECIFIED = 0;

  // Value representing a meal before breakfast.
  BEFORE_BREAKFAST = 1;

  // Value representing a breakfast.
  BREAKFAST = 2;

  // Value representing a morning snack.
  BEFORE_LUNCH = 3;

  // Value representing a lunch.
  LUNCH = 4;

  // Value representing an afternoon snack.
  BEFORE_DINNER = 5;

  // Value representing dinner.
  DINNER = 6;

  // Value representing an evening snack.
  AFTER_DINNER = 7;

  // Value representing any meal outside of the usual three meals per day.
  SNACK = 8;

  // Value representing any time (legacy NA).
  ANYTIME = 9;
}

// Enum representing the unit of energy.
enum EnergyUnit {
  // Unspecified energy unit.
  ENERGY_UNIT_UNSPECIFIED = 0;

  // Value representing joule.
  JOULE = 1;

  // Value representing kilojoule.
  KILOJOULE = 2;

  // Value representing kilocalorie.
  KILOCALORIE = 3;

  // Value representing small calorie.
  SMALL_CALORIE = 4;

  // Value representing calorie.
  CALORIE = 5;
}

// Holds information about a user logged food.
enum Nutrient {
  // Unspecified nutrient.
  NUTRIENT_UNSPECIFIED = 0;

  // Value representing biotin nutrient.
  BIOTIN = 1;

  // Value representing caffeine nutrient.
  CAFFEINE = 2;

  // Value representing calcium nutrient.
  CALCIUM = 3;

  // Value representing chloride nutrient.
  CHLORIDE = 4;

  // Value representing carbohydrates nutrient.
  CARBOHYDRATES = 5;

  // Value representing cholesterol nutrient.
  CHOLESTEROL = 6;

  // Value representing chromium nutrient.
  CHROMIUM = 7;

  // Value representing copper nutrient.
  COPPER = 8;

  // Value representing dietary fiber nutrient.
  DIETARY_FIBER = 9;

  // Value representing folic acid nutrient.
  FOLIC_ACID = 10;

  // Value representing iodine nutrient.
  IODINE = 11;

  // Value representing iron nutrient.
  IRON = 12;

  // Value representing magnesium nutrient.
  MAGNESIUM = 13;

  // Value representing manganese nutrient.
  MANGANESE = 14;

  // Value representing molybdenum nutrient.
  MOLYBDENUM = 15;

  // Value representing monounsaturated fat nutrient.
  MONOUNSATURATED_FAT = 16;

  // Value representing niacin nutrient.
  NIACIN = 17;

  // Value representing pantothenic acid nutrient.
  PANTOTHENIC_ACID = 18;

  // Value representing phosphorus nutrient.
  PHOSPHORUS = 19;

  // Value representing polyunsaturated fat nutrient.
  POLYUNSATURATED_FAT = 20;

  // Value representing potassium nutrient.
  POTASSIUM = 21;

  // Value representing protein nutrient.
  PROTEIN = 22;

  // Value representing riboflavin nutrient.
  RIBOFLAVIN = 23;

  // Value representing saturated fat nutrient.
  SATURATED_FAT = 24;

  // Value representing selenium nutrient.
  SELENIUM = 25;

  // Value representing sodium nutrient.
  SODIUM = 26;

  // Value representing sugar nutrient.
  SUGAR = 27;

  // Value representing thiamin nutrient.
  THIAMIN = 28;

  // Value representing trans fat nutrient.
  TRANS_FAT = 29;

  // Value representing unsaturated fat nutrient.
  UNSATURATED_FAT = 30;

  // Value representing vitamin A nutrient.
  VITAMIN_A = 31;

  // Value representing vitamin B12 nutrient.
  VITAMIN_B12 = 32;

  // Value representing vitamin B6 nutrient.
  VITAMIN_B6 = 33;

  // Value representing vitamin C nutrient.
  VITAMIN_C = 34;

  // Value representing vitamin D nutrient.
  VITAMIN_D = 35;

  // Value representing vitamin E nutrient.
  VITAMIN_E = 36;

  // Value representing vitamin K nutrient.
  VITAMIN_K = 37;

  // Value representing zinc nutrient.
  ZINC = 38;

  // Value representing folate nutrient.
  FOLATE = 39;
}

// Enum representing the unit of weight.
enum WeightUnit {
  // Unspecified weight unit.
  WEIGHT_UNIT_UNSPECIFIED = 0;

  // Value representing gram.
  GRAM = 1;

  // Value representing kilogram.
  KILOGRAM = 2;

  // Value representing ounce.
  OUNCE = 3;

  // Value representing pound.
  POUND = 4;

  // Value representing stone.
  STONE = 5;

  // Value representing milligram.
  MILLIGRAM = 6;

  // Value representing microgram.
  MICROGRAM = 7;

  // Value representing nanogram.
  NANOGRAM = 8;
}

// Enum representing the unit of volume.
enum VolumeUnit {
  // Unspecified volume unit.
  VOLUME_UNIT_UNSPECIFIED = 0;

  // Cup (imperial)
  CUP_IMPERIAL = 1;

  // Cup (US)
  CUP_US = 2;

  // Fluid ounce (imperial)
  FLUID_OUNCE_IMPERIAL = 3;

  // Fluid ounce (US)
  FLUID_OUNCE_US = 4;

  // Liter
  LITER = 5;

  // Milliliter
  MILLILITER = 6;

  // Pint (imperial)
  PINT_IMPERIAL = 7;

  // Pint (US)
  PINT_US = 8;
}

// Ovulation test result.
enum OvulationTestResult {
  // Unspecified result.
  OVULATION_TEST_RESULT_UNSPECIFIED = 0;

  // Negative result.
  NEGATIVE = 1;

  // Luteinizing hormone surge.
  LUTEINIZING_HORMONE_SURGE = 2;

  // Estrogen surge.
  ESTROGEN_SURGE = 3;

  // Positive result.
  POSITIVE = 4;

  // Indeterminate result.
  INDETERMINATE = 5;
}

// Record of active zone minutes in a given time interval.
message ActiveZoneMinutes {
  // Represents different heart rate zones.
  enum HeartRateZone {
    // Unspecified heart rate zone.
    HEART_RATE_ZONE_UNSPECIFIED = 0;

    // The fat burn heart rate zone.
    FAT_BURN = 1;

    // The cardio heart rate zone.
    CARDIO = 2;

    // The peak heart rate zone.
    PEAK = 3;
  }

  // Required. Observed interval.
  ObservationTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Heart rate zone in which the active zone minutes have been
  // earned, in the given time interval.
  HeartRateZone heart_rate_zone = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Number of Active Zone Minutes earned in the given time interval.
  // Note: active_zone_minutes equals to 1 for low intensity (fat burn) zones or
  // 2 for high intensity zones (cardio, peak).
  optional int64 active_zone_minutes = 3
      [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the active zone minutes data type.
message ActiveZoneMinutesRollupValue {
  // Active zone minutes in `HeartRateZone.CARDIO`.
  optional int64 sum_in_cardio_heart_zone = 1;

  // Active zone minutes in `HeartRateZone.PEAK`.
  optional int64 sum_in_peak_heart_zone = 2;

  // Active zone minutes in `HeartRateZone.FAT_BURN`.
  optional int64 sum_in_fat_burn_heart_zone = 3;
}

// Record of active minutes in a given time interval.
message ActiveMinutes {
  // Active minutes at a given activity level.
  message ActiveMinutesByActivityLevel {
    // Required. The level of activity.
    ActivityLevel activity_level = 1 [(google.api.field_behavior) = REQUIRED];

    // Required. Number of whole minutes spent in activity.
    optional int64 active_minutes = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // Activity level.
  enum ActivityLevel {
    // Activity level is unspecified.
    ACTIVITY_LEVEL_UNSPECIFIED = 0;

    // Light activity level.
    LIGHT = 1;

    // Moderate activity level.
    MODERATE = 2;

    // Vigorous activity level.
    VIGOROUS = 3;
  }

  // Required. Observed interval.
  ObservationTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Active minutes by activity level. At most one record per activity
  // level is allowed.
  repeated ActiveMinutesByActivityLevel active_minutes_by_activity_level = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the active minutes data type.
message ActiveMinutesRollupValue {
  // Active minutes by activity level.
  message ActiveMinutesRollupByActivityLevel {
    // The level of activity.
    ActiveMinutes.ActivityLevel activity_level = 1;

    // Number of whole minutes spent in activity.
    optional int64 active_minutes_sum = 2;
  }

  // Active minutes by activity level. At most one record per activity level
  // is allowed.
  repeated ActiveMinutesRollupByActivityLevel
      active_minutes_rollup_by_activity_level = 1;
}

// Internal type to capture activity level during a certain time interval.
message ActivityLevel {
  // Represents different activity level types.
  enum ActivityLevelType {
    // Unspecified activity level type.
    ACTIVITY_LEVEL_TYPE_UNSPECIFIED = 0;

    // Sedentary activity level.
    SEDENTARY = 1;

    // Lightly active activity level.
    LIGHTLY_ACTIVE = 2;

    // Moderately active activity level.
    MODERATELY_ACTIVE = 3;

    // Very active activity level.
    VERY_ACTIVE = 4;
  }

  // Required. Observed interval.
  ObservationTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Activity level type in the given time interval.
  ActivityLevelType activity_level_type = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the activity level data type.
message ActivityLevelRollupValue {
  // Represents the total duration in a specific activity level type.
  message ActivityLevelRollupByActivityLevelType {
    // Activity level type.
    ActivityLevel.ActivityLevelType activity_level_type = 1;

    // Total duration in the activity level type.
    google.protobuf.Duration total_duration = 2;
  }

  // List of total durations in each activity level type.
  repeated ActivityLevelRollupByActivityLevelType
      activity_level_rollups_by_activity_level_type = 1;
}

// Captures the altitude gain (i.e. deltas), and not level above sea, for a user
// in millimeters.
message Altitude {
  // Required. Observed interval.
  ObservationTimeInterval interval = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Altitude gain in millimeters over the observed interval.
  // Must be in the range `[-1000000000, 1000000000]`.
  optional int64 gain_millimeters = 3 [(google.api.field_behavior) = REQUIRED];
}

// Number of calories burned due to basal metabolic rate (BMR) over a period of
// time.
message BasalEnergyBurned {
  // Required. Observed interval.
  ObservationTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Number of calories burned due to basal metabolic rate in
  // kilocalories over the observed interval.
  optional double kcal = 2 [(google.api.field_behavior) = REQUIRED];
}

// Body fat measurement.
message BodyFat {
  // Required. The time at which body fat was measured.
  ObservationSampleTime sample_time = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. Body fat percentage. Must be in the range `[0, 100]`.
  optional double percentage = 3 [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the body fat data type.
message BodyFatRollupValue {
  // Average body fat percentage.
  optional double body_fat_percentage_avg = 1;
}

// //////////////////////////////////////////////////////////////////////////
// SkinTemperature
// //////////////////////////////////////////////////////////////////////////
// Skin temperature measurement.
message SkinTemperature {
  // Metadata for the skin temperature measurement.
  message SkinTemperatureMetadata {
    // Optional. The location of the skin temperature measurement.
    MeasurementLocation measurement_location = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. The motion state of the skin temperature measurement.
    MeasurementState measurement_state = 2
        [(google.api.field_behavior) = OPTIONAL];
  }

  // The location of the skin temperature measurement.
  enum MeasurementLocation {
    // Measurement location is unspecified.
    MEASUREMENT_LOCATION_UNSPECIFIED = 0;

    // Other measurement location.
    OTHER = 1;

    // Finger measurement location.
    FINGER = 2;

    // Toe measurement location.
    TOE = 3;

    // Wrist measurement location.
    WRIST = 4;
  }

  // The motion state when the skin temperature was measured.
  enum MeasurementState {
    // Measurement state is unspecified.
    MEASUREMENT_STATE_UNSPECIFIED = 0;

    // Other measurement state.
    MEASUREMENT_STATE_OTHER = 1;

    // Measurement state at rest.
    MEASUREMENT_STATE_AT_REST = 2;

    // Measurement state during sleep.
    MEASUREMENT_STATE_SLEEP = 3;
  }

  // Required. The time at which skin temperature was measured.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The skin temperature in Celsius.
  // Must be in the range `[0, 100]`.
  optional double temperature_celsius = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. The baseline skin temperature in Celsius.
  // Must be in the range `[0, 100]`.
  optional double baseline_temperature_celsius = 3
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Metadata for the skin temperature measurement.
  SkinTemperatureMetadata metadata = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the result of the rollup of the skin temperature data type.
message SkinTemperatureRollupValue {
  // Average skin temperature in Celsius.
  optional double temperature_celsius_avg = 1;

  // Maximum skin temperature in Celsius.
  optional double temperature_celsius_max = 2;

  // Minimum skin temperature in Celsius.
  optional double temperature_celsius_min = 3;
}

// Skin temperature sensor data containing multi-sensor readings.
message SkinTemperatureSensors {
  // Metadata for the sensor measurement.
  message SensorMetadata {
    // The motion state when the sensor temperature was measured.
    enum MeasurementState {
      // Measurement state is unspecified.
      MEASUREMENT_STATE_UNSPECIFIED = 0;

      // Other measurement state.
      OTHER = 1;

      // Measurement state at rest.
      AT_REST = 2;

      // Measurement state during sleep.
      SLEEP = 3;
    }

    // The type of sensor.
    enum SensorType {
      // Sensor type is unspecified.
      SENSOR_TYPE_UNSPECIFIED = 0;

      // Skin temperature sensor (bottom contact sensor).
      SKIN_TEMPERATURE_SENSOR = 1;

      // Internal device temperature sensor (top/ambient sensor).
      INTERNAL_DEVICE_TEMPERATURE_SENSOR = 2;
    }

    // Optional. The location of the sensor measurement.
    MeasurementLocation measurement_location = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. The motion state of the sensor measurement.
    MeasurementState measurement_state = 2
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. The type of the sensor.
    SensorType sensor_type = 3 [(google.api.field_behavior) = OPTIONAL];
  }

  // Individual sensor reading and metadata.
  message SensorData {
    // Required. The temperature reading in Celsius.
    optional double temperature_celsius = 1
        [(google.api.field_behavior) = REQUIRED];

    // Optional. Metadata for the sensor reading.
    SensorMetadata metadata = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  // The location where the temperature was measured.
  enum MeasurementLocation {
    // Measurement location is unspecified.
    MEASUREMENT_LOCATION_UNSPECIFIED = 0;

    // Other measurement location.
    OTHER = 1;

    // Finger measurement location.
    FINGER = 2;

    // Toe measurement location.
    TOE = 3;

    // Wrist measurement location.
    WRIST = 4;
  }

  // Required. The observation sample time.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. Repeated sensor data readings for this sample.
  repeated SensorData sensor_data = 2 [(google.api.field_behavior) = REQUIRED];
}

// Core body temperature measurement, distinct from peripheral body temperature,
// reflects the temperature of the body's internal organs.
message CoreBodyTemperature {
  // Measurement location for core body temperature.
  enum MeasurementLocation {
    // Measurement location is unspecified.
    MEASUREMENT_LOCATION_UNSPECIFIED = 0;

    // Other measurement location.
    OTHER = 1;

    // Armpit measurement location.
    ARMPIT = 2;

    // Body measurement location.
    BODY = 3;

    // Ear measurement location.
    EAR = 4;

    // Finger measurement location.
    FINGER = 5;

    // Gastro-intestinal measurement location.
    GASTRO_INTESTINAL = 6;

    // Mouth measurement location.
    MOUTH = 7;

    // Rectum measurement location.
    RECTUM = 8;

    // Toe measurement location.
    TOE = 9;

    // Ear drum measurement location.
    EAR_DRUM = 10;

    // Temporal artery measurement location.
    TEMPORAL_ARTERY = 11;

    // Forehead measurement location.
    FOREHEAD = 12;

    // Urinary bladder measurement location.
    URINARY_BLADDER = 13;

    // Nasal measurement location.
    NASAL = 14;

    // Nasopharyngeal measurement location.
    NASOPHARYNGEAL = 15;

    // Wrist measurement location.
    WRIST = 16;

    // Vagina measurement location.
    VAGINA = 17;
  }

  // Required. The time at which core body temperature was measured.
  ObservationSampleTime sample_time = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. The core body temperature in Celsius.
  // Must be in the range `[0, 100]`.
  optional double temperature_celsius = 3
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The location of the core body temperature measurement.
  MeasurementLocation measurement_location = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The unique identifier of the core body temperature measurement.
  string id = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the result of the rollup of the core body temperature data type.
message CoreBodyTemperatureRollupValue {
  // Average core body temperature in Celsius.
  optional double temperature_celsius_avg = 1;

  // Maximum core body temperature in Celsius.
  optional double temperature_celsius_max = 2;

  // Minimum core body temperature in Celsius.
  optional double temperature_celsius_min = 3;
}

// Represents the result of the rollup of the calories in heart rate zone data
// type.
message CaloriesInHeartRateZoneRollupValue {
  // Represents the amount of kilocalories burned in a specific heart rate zone.
  message CaloriesInHeartRateZoneValue {
    // The heart rate zone.
    HeartRateZoneType heart_rate_zone = 1;

    // The amount of kilocalories burned in the specified heart rate zone.
    optional double kcal = 2;
  }

  // List of calories burned in each heart rate zone.
  repeated CaloriesInHeartRateZoneValue calories_in_heart_rate_zones = 1;
}

// User's heart rate zone thresholds based on the Karvonen algorithm for a
// specific day.
message DailyHeartRateZones {
  // The heart rate zone.
  message HeartRateZone {
    // Required. The heart rate zone type.
    HeartRateZoneType heart_rate_zone_type = 1
        [(google.api.field_behavior) = REQUIRED];

    // Required. Minimum heart rate for this zone in beats per minute.
    optional int64 min_beats_per_minute = 2
        [(google.api.field_behavior) = REQUIRED];

    // Required. Maximum heart rate for this zone in beats per minute.
    optional int64 max_beats_per_minute = 3
        [(google.api.field_behavior) = REQUIRED];
  }

  // Required. Date (in user's timezone) of the heart rate zones record.
  google.type.Date date = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The heart rate zones.
  repeated HeartRateZone heart_rate_zones = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Represents the daily heart rate variability data type.
//
// At least one of the following fields must be set:
//
// - `average_heart_rate_variability_milliseconds`
// - `non_rem_heart_rate_beats_per_minute`
// - `entropy`
// - `deep_sleep_root_mean_square_of_successive_differences_milliseconds`
message DailyHeartRateVariability {
  // Required. Date (in the user's timezone) of heart rate variability
  // measurement.
  google.type.Date date = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. A user's average heart rate variability calculated using the root
  // mean square of successive differences (RMSSD) in times between heartbeats.
  optional double average_heart_rate_variability_milliseconds = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Non-REM heart rate
  optional int64 non_rem_heart_rate_beats_per_minute = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The Shanon entropy of heartbeat intervals.
  // Entropy quantifies randomness or disorder in a system. High entropy
  // indicates high HRV. Entropy is measured from the histogram of time interval
  // between successive heart beats values measured during sleep.
  optional double entropy = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The root mean square of successive differences (RMSSD) value
  // during deep sleep.
  optional double
      deep_sleep_root_mean_square_of_successive_differences_milliseconds = 7
      [(google.api.field_behavior) = OPTIONAL];
}

// A daily average respiratory rate (breaths per minute) for a day of the year.
// One data point per day calculated for the main sleep.
message DailyRespiratoryRate {
  // Required. The date on which the respiratory rate was measured.
  google.type.Date date = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The average number of breaths taken per minute.
  optional double breaths_per_minute = 2
      [(google.api.field_behavior) = REQUIRED];
}

// A daily oxygen saturation (SpO2) record.
// Represents the user's daily oxygen saturation summary, typically calculated
// during sleep.
message DailyOxygenSaturation {
  // Required. Date (in user's timezone) of the daily oxygen saturation record.
  google.type.Date date = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The average value of the oxygen saturation samples during the
  // sleep. Must be in the range `[0, 100]`.
  optional double average_percentage = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. The lower bound of the confidence interval of oxygen saturation
  // samples during sleep.
  // Must be in the range `[0, 100]`.
  optional double lower_bound_percentage = 3
      [(google.api.field_behavior) = REQUIRED];

  // Required. The upper bound of the confidence interval of oxygen saturation
  // samples during sleep.
  // Must be in the range `[0, 100]`.
  optional double upper_bound_percentage = 4
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Standard deviation of the daily oxygen saturation averages from
  // the past 7-30 days.
  optional double standard_deviation_percentage = 5
      [(google.api.field_behavior) = OPTIONAL];
}

// Measures the daily resting heart rate for a user, calculated using the all
// day heart rate measurements.
message DailyRestingHeartRate {
  // Metadata for the daily resting heart rate.
  message DailyRestingHeartRateMetadata {
    // The method used to calculate the resting heart rate.
    enum CalculationMethod {
      // The calculation method is unspecified.
      CALCULATION_METHOD_UNSPECIFIED = 0;

      // The resting heart rate is calculated using the sleep data.
      WITH_SLEEP = 1;

      // The resting heart rate is calculated using only awake data.
      ONLY_WITH_AWAKE_DATA = 2;
    }

    // Required. The method used to calculate the resting heart rate.
    CalculationMethod calculation_method = 1
        [(google.api.field_behavior) = REQUIRED];
  }

  // Required. Date  (in the user's timezone) of the resting heart rate
  // measurement.
  google.type.Date date = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The resting heart rate value in beats per minute.
  optional int64 beats_per_minute = 4 [(google.api.field_behavior) = REQUIRED];

  // Optional. Metadata for the daily resting heart rate.
  DailyRestingHeartRateMetadata daily_resting_heart_rate_metadata = 5
      [(google.api.field_behavior) = OPTIONAL];
}

// Provides derived sleep temperature values, calculated from skin or internal
// device temperature readings during sleep.
message DailySleepTemperatureDerivations {
  // Required. Date for which the sleep temperature derivations are calculated.
  google.type.Date date = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The user's nightly skin temperature. It is the mean of skin
  // temperature samples taken from the user’s sleep.
  optional double nightly_temperature_celsius = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The user's baseline skin temperature. It is the median of the
  // user's nightly skin temperature over the past 30 days.
  optional double baseline_temperature_celsius = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The standard deviation of the user’s relative nightly skin
  // temperature (temperature - baseline) over the past 30 days.
  optional double relative_nightly_stddev_30d_celsius = 4
      [(google.api.field_behavior) = OPTIONAL];
}

// Contains a daily summary of the user's VO2 max (cardio fitness score),
// which is the maximum rate of oxygen the body can use during exercise.
message DailyVO2Max {
  // The cardio fitness level categories.
  enum CardioFitnessLevel {
    // Unspecified cardio fitness level.
    CARDIO_FITNESS_LEVEL_UNSPECIFIED = 0;

    // Poor cardio fitness level.
    POOR = 1;

    // Fair cardio fitness level.
    FAIR = 2;

    // Average cardio fitness level.
    AVERAGE = 3;

    // Good cardio fitness level.
    GOOD = 4;

    // Very good cardio fitness level.
    VERY_GOOD = 5;

    // Excellent cardio fitness level.
    EXCELLENT = 6;
  }

  // Required. The date for which the Daily VO2 max was measured.
  google.type.Date date = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Daily VO2 max value measured as in ml consumed oxygen / kg of
  // body weight / min. Must be in the range `[0, 100]`.
  optional double vo2_max = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. An estimated field is added to indicate when the confidence has
  // decreased sufficiently to consider the value an estimation.
  bool estimated = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Represents the user's cardio fitness level based on their VO2
  // max.
  CardioFitnessLevel cardio_fitness_level = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The covariance of the VO2 max value.
  optional double vo2_max_covariance = 5
      [(google.api.field_behavior) = OPTIONAL];
}

// Distance traveled over an interval of time.
message Distance {
  // Required. Observed interval.
  ObservationTimeInterval interval = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Distance in millimeters over the observed interval.
  // Must be in the range `[0, 1000000000]`.
  optional int64 millimeters = 3 [(google.api.field_behavior) = REQUIRED];
}

// Result of the rollup of the user's distance.
message DistanceRollupValue {
  // Sum of the distance in millimeters.
  optional int64 millimeters_sum = 1;
}

// Represents an Electrocardiogram (ECG) measurement session.
// This data type is based on SaMD feature and any changes to it may require
// additional review.
message Electrocardiogram {
  // The classification of the ECG reading rhythm.
  enum ResultClassification {
    // Unspecified result classification.
    RESULT_CLASSIFICATION_UNSPECIFIED = 0;

    // Heart rhythm appears normal. Corresponds to result "Normal Sinus Rhythm".
    NORMAL_SINUS_RHYTHM = 1;

    // Signs of Atrial Fibrillation detected. Corresponds to result "Atrial
    // Fibrillation".
    ATRIAL_FIBRILLATION = 2;

    // The reading is inconclusive as it could not be classified. Corresponds to
    // result "Inconclusive".
    INCONCLUSIVE = 3;

    // The reading is inconclusive as it could not be classified because
    // heart rate is high (>120bpm). Corresponds to result "Inconclusive: High
    // heart rate".
    INCONCLUSIVE_HIGH_HEART_RATE = 4;

    // The reading is inconclusive as it could not be classified because
    // heart rate is low (<50bpm). Corresponds to result "Inconclusive: Low
    // heart rate".
    INCONCLUSIVE_LOW_HEART_RATE = 5;

    // The reading is unreadable.
    UNREADABLE = 6;

    // The reading was not analyzed.
    NOT_ANALYZED = 7;
  }

  // Required. Observed interval.
  //
  // NOTE: Historical ECG data lacks timezone offsets, so `start_utc_offset`
  // and `end_utc_offset` will be missing or default to zero. As a result,
  // the civil time fields within this interval will default to UTC.
  // It is recommended to use physical time fields instead for accurate
  // time referencing.
  //
  // NOTE: The `start_time` and `end_time` of the interval are equal,
  // representing the reading time.
  SessionTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Average heart rate recorded during ECG reading in beats per
  // minute.
  optional int64 beats_per_minute_avg = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The result classification of the ECG reading.
  ResultClassification result_classification = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. An array of voltage values representing lead I ECG values.
  // Each sample represents voltage difference in ECG graph.
  // The first value in array corresponds to the start of the reading.
  repeated sint32 waveform_samples = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The sampling frequency of waveform samples in hertz.
  optional int32 sampling_frequency_hertz = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The factor by which to divide waveform samples to get voltage in
  // millivolts: millivolts = waveform_sample / millivolts_scaling_factor.
  optional int32 millivolts_scaling_factor = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The number of leads used for ECG reading.
  optional int32 lead_number = 7 [(google.api.field_behavior) = OPTIONAL];

  // Output only. The meta information for the compatible device used to conduct
  // the measurement.
  //
  // ECG measurements typically populate `firmware_version`, `feature_version`,
  // and `device_model`.
  MedicalDeviceInfo medical_device_info = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// An exercise that stores information about a physical activity.
message Exercise {
  // Represents splits or laps recorded within an exercise. Lap events
  // partition a workout into segments based on criteria like distance, time, or
  // calories.
  message SplitSummary {
    // The type of the split, such as manual, duration, distance, calories.
    enum SplitType {
      // Split type is unspecified.
      SPLIT_TYPE_UNSPECIFIED = 0;

      // Manual split.
      MANUAL = 1;

      // Split by duration.
      DURATION = 2;

      // Split by distance.
      DISTANCE = 3;

      // Split by calories.
      CALORIES = 4;
    }

    // Required. Lap start time
    google.protobuf.Timestamp start_time = 1
        [(google.api.field_behavior) = REQUIRED];

    // Required. Lap start time offset from UTC
    google.protobuf.Duration start_utc_offset = 2
        [(google.api.field_behavior) = REQUIRED];

    // Required. Lap end time
    google.protobuf.Timestamp end_time = 3
        [(google.api.field_behavior) = REQUIRED];

    // Required. Lap end time offset from UTC
    google.protobuf.Duration end_utc_offset = 4
        [(google.api.field_behavior) = REQUIRED];

    // Output only. Lap time excluding the pauses.
    google.protobuf.Duration active_duration = 5
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Required. Summary metrics for this split.
    MetricsSummary metrics_summary = 6 [(google.api.field_behavior) = REQUIRED];

    // Required. Method used to split the exercise laps.
    // Users may manually mark the lap as complete even if the tracking
    // is automatic.
    SplitType split_type = 7 [(google.api.field_behavior) = REQUIRED];
  }

  // Represents instantaneous events that happen during an exercise,
  // such as start, stop, pause, split.
  message ExerciseEvent {
    // The type of the event, such as start, stop, pause, resume.
    enum ExerciseEventType {
      // Exercise event type is unspecified.
      EXERCISE_EVENT_TYPE_UNSPECIFIED = 0;

      // Exercise start event.
      START = 1;

      // Exercise stop event.
      STOP = 2;

      // Exercise pause event.
      PAUSE = 3;

      // Exercise resume event.
      RESUME = 4;

      // Exercise auto-pause event.
      AUTO_PAUSE = 5;

      // Exercise auto-resume event.
      AUTO_RESUME = 6;
    }

    // Required. Exercise event time
    google.protobuf.Timestamp event_time = 1
        [(google.api.field_behavior) = REQUIRED];

    // Required. Exercise event time offset from UTC
    google.protobuf.Duration event_utc_offset = 2
        [(google.api.field_behavior) = REQUIRED];

    // Required. The type of the event, such as start, stop, pause, resume.
    ExerciseEventType exercise_event_type = 3
        [(google.api.field_behavior) = REQUIRED];
  }

  // Additional exercise metadata.
  message ExerciseMetadata {
    // Optional. Pool length in millimeters. Only present in the swimming
    // exercises.
    optional int64 pool_length_millimeters = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Whether the exercise had GPS tracking.
    bool has_gps = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  // The type of activity performed during an exercise.
  // May receive new values in the future.
  enum ExerciseType {
    // Exercise type is unspecified.
    EXERCISE_TYPE_UNSPECIFIED = 0;

    // Aerobic workout type.
    AEROBIC_WORKOUT = 13;

    // Archery type.
    ARCHERY = 47;

    // Assault bike type.
    ASSAULT_BIKE = 164;

    // Backpacking type.
    BACKPACKING = 181;

    // Badminton type.
    BADMINTON = 48;

    // Ballet type.
    BALLET = 103;

    // Ballroom dance type.
    BALLROOM_DANCE = 156;

    // Barre class type.
    BARRE_CLASS = 49;

    // Baseball type.
    BASEBALL = 50;

    // Basketball type.
    BASKETBALL = 51;

    // Biking type.
    BIKING = 3;

    // Billiards type.
    BILLIARDS = 180;

    // Body weight type.
    BODY_WEIGHT = 149;

    // Bootcamp type.
    BOOTCAMP = 14;

    // Bowling type.
    BOWLING = 52;

    // Boxing type.
    BOXING = 53;

    // Breakdancing type.
    BREAKDANCING = 157;

    // Calisthenics type.
    CALISTHENICS = 54;

    // Canoeing type.
    CANOEING = 15;

    // Cardio sculpt type.
    CARDIO_SCULPT = 129;

    // Cardio workout type.
    CARDIO_WORKOUT = 140;

    // Carpentry type.
    CARPENTRY = 108;

    // Cheerleading type.
    CHEERLEADING = 165;

    // Circuit training type.
    CIRCUIT_TRAINING = 16;

    // Cleaning type.
    CLEANING = 105;

    // Climbing type.
    CLIMBING = 55;

    // Core training type.
    CORE_TRAINING = 17;

    // Cricket type.
    CRICKET = 56;

    // Croquet type.
    CROQUET = 111;

    // Cross country ski type.
    CROSS_COUNTRY_SKI = 18;

    // Cross training type.
    CROSS_TRAINING = 57;

    // Crossfit type.
    CROSSFIT = 19;

    // Curling type.
    CURLING = 58;

    // Dancing type.
    DANCING = 20;

    // Diving type.
    DIVING = 59;

    // Electric bike type.
    ELECTRIC_BIKE = 152;

    // Electric scooter type.
    ELECTRIC_SCOOTER = 168;

    // Elliptical type.
    ELLIPTICAL = 21;

    // Equestrian sports type.
    EQUESTRIAN_SPORTS = 60;

    // Exercise class type.
    EXERCISE_CLASS = 61;

    // Fencing type.
    FENCING = 62;

    // Field hockey type.
    FIELD_HOCKEY = 113;

    // Fishing type.
    FISHING = 63;

    // Fitness gaming type.
    FITNESS_GAMING = 64;

    // Foiling type.
    FOILING = 175;

    // Football american type.
    FOOTBALL_AMERICAN = 65;

    // Football australian type.
    FOOTBALL_AUSTRALIAN = 66;

    // Free weights type.
    FREE_WEIGHTS = 148;

    // Frisbee playing general type.
    FRISBEE_PLAYING_GENERAL = 67;

    // Functional strength training type.
    FUNCTIONAL_STRENGTH_TRAINING = 68;

    // Gardening type.
    GARDENING = 107;

    // Golf type.
    GOLF = 22;

    // Gymnastics type.
    GYMNASTICS = 69;

    // Handball type.
    HANDBALL = 70;

    // Hand cycling type.
    HAND_CYCLING = 71;

    // Hiit type.
    HIIT = 9;

    // Hiking type.
    HIKING = 5;

    // Hip hop type.
    HIP_HOP = 158;

    // Hockey type.
    HOCKEY = 72;

    // Hoeing type.
    HOEING = 109;

    // Household chores type.
    HOUSEHOLD_CHORES = 137;

    // Hunting type.
    HUNTING = 73;

    // Ice skating type.
    ICE_SKATING = 127;

    // Incline run type.
    INCLINE_RUN = 142;

    // Incline walk type.
    INCLINE_WALK = 146;

    // Indoor climbing type.
    INDOOR_CLIMBING = 23;

    // Interval workout type.
    INTERVAL_WORKOUT = 24;

    // Jazz dance type.
    JAZZ_DANCE = 154;

    // Jiu jitsu type.
    JIU_JITSU = 160;

    // Jumping rope type.
    JUMPING_ROPE = 74;

    // Karate type.
    KARATE = 159;

    // Kayaking type.
    KAYAKING = 25;

    // Kickboxing type.
    KICKBOXING = 26;

    // Kitesurfing type.
    KITESURFING = 172;

    // Lacrosse type.
    LACROSSE = 75;

    // Martial arts type.
    MARTIAL_ARTS = 27;

    // Meditate type.
    MEDITATE = 28;

    // Modern dance type.
    MODERN_DANCE = 153;

    // Motocross type.
    MOTOCROSS = 114;

    // Motorcycle type.
    MOTORCYCLE = 121;

    // Mountain bike type.
    MOUNTAIN_BIKE = 128;

    // Mowing lawn type.
    MOWING_LAWN = 106;

    // Muay thai type.
    MUAY_THAI = 162;

    // Multisport type.
    MULTISPORT = 76;

    // Musical performance type.
    MUSICAL_PERFORMANCE = 163;

    // Nordic walking type.
    NORDIC_WALKING = 145;

    // Orienteering type.
    ORIENTEERING = 115;

    // Other type.
    OTHER = 12;

    // Outdoor bike type.
    OUTDOOR_BIKE = 29;

    // Outdoor workout type.
    OUTDOOR_WORKOUT = 30;

    // Paddleboarding type.
    PADDLEBOARDING = 31;

    // Padel type.
    PADEL = 176;

    // Painting type.
    PAINTING = 170;

    // Paragliding type.
    PARAGLIDING = 78;

    // Parkour type.
    PARKOUR = 166;

    // Pickelball type.
    PICKELBALL = 79;

    // Pilates type.
    PILATES = 7;

    // Polo type.
    POLO = 116;

    // Powerlifting type.
    POWERLIFTING = 32;

    // Power walking type.
    POWER_WALKING = 143;

    // Racket sports type.
    RACKET_SPORTS = 169;

    // Racquetball type.
    RACQUETBALL = 80;

    // Resistance bands type.
    RESISTANCE_BANDS = 151;

    // Rock climbing type.
    ROCK_CLIMBING = 123;

    // Rollerblading type.
    ROLLERBLADING = 33;

    // Roller skating type.
    ROLLER_SKATING = 118;

    // Rowing type.
    ROWING = 81;

    // Rowing machine type.
    ROWING_MACHINE = 34;

    // Rucking type.
    RUCKING = 144;

    // Rugby type.
    RUGBY = 82;

    // Running type.
    RUNNING = 1;

    // Sailing type.
    SAILING = 83;

    // Scootering type.
    SCOOTERING = 167;

    // Scuba diving type.
    SCUBA_DIVING = 84;

    // Shooting type.
    SHOOTING = 104;

    // Shoveling type.
    SHOVELING = 171;

    // Skateboarding type.
    SKATEBOARDING = 117;

    // Skating type.
    SKATING = 35;

    // Skiing type.
    SKIING = 36;

    // Skydiving type.
    SKYDIVING = 182;

    // Snorkeling type.
    SNORKELING = 37;

    // Snowboarding type.
    SNOWBOARDING = 38;

    // Snowmobiling type.
    SNOWMOBILING = 179;

    // Snowshoeing type.
    SNOWSHOEING = 85;

    // Snow sport type.
    SNOW_SPORT = 86;

    // Soccer type.
    SOCCER = 87;

    // Softball type.
    SOFTBALL = 88;

    // Speed skating type.
    SPEED_SKATING = 178;

    // Spinning type.
    SPINNING = 39;

    // Sport type.
    SPORT = 40;

    // Squash type.
    SQUASH = 89;

    // Stairclimber type.
    STAIRCLIMBER = 41;

    // Stationary bike type.
    STATIONARY_BIKE = 139;

    // Step training type.
    STEP_TRAINING = 90;

    // Strength training type.
    STRENGTH_TRAINING = 11;

    // Stretching type.
    STRETCHING = 42;

    // Stroller walk type.
    STROLLER_WALK = 122;

    // Surfing type.
    SURFING = 43;

    // Swimming type.
    SWIMMING = 4;

    // Swimming open water type.
    SWIMMING_OPEN_WATER = 91;

    // Swimming pool type.
    SWIMMING_POOL = 101;

    // Synchronized swimming type.
    SYNCHRONIZED_SWIMMING = 177;

    // Tabata workout type.
    TABATA_WORKOUT = 130;

    // Table tennis type.
    TABLE_TENNIS = 92;

    // Taekwondo type.
    TAEKWONDO = 161;

    // Tai chi type.
    TAI_CHI = 93;

    // Tango type.
    TANGO = 155;

    // Tennis type.
    TENNIS = 44;

    // Track and field type.
    TRACK_AND_FIELD = 94;

    // Trail run type.
    TRAIL_RUN = 141;

    // Trampoline type.
    TRAMPOLINE = 119;

    // Treadmill type.
    TREADMILL = 45;

    // Treadmill walk type.
    TREADMILL_WALK = 138;

    // Trx type.
    TRX = 131;

    // Ultimate frisbee type.
    ULTIMATE_FRISBEE = 112;

    // Unicycling type.
    UNICYCLING = 102;

    // Volleyball type.
    VOLLEYBALL = 95;

    // Volleyball beach type.
    VOLLEYBALL_BEACH = 120;

    // Wakeboarding type.
    WAKEBOARDING = 173;

    // Walking type.
    WALKING = 2;

    // Walk with weights type.
    WALK_WITH_WEIGHTS = 147;

    // Water aerobics type.
    WATER_AEROBICS = 96;

    // Water jogging type.
    WATER_JOGGING = 126;

    // Water polo type.
    WATER_POLO = 97;

    // Water skiing type.
    WATER_SKIING = 124;

    // Water sport type.
    WATER_SPORT = 98;

    // Water volleyball type.
    WATER_VOLLEYBALL = 125;

    // Weeding type.
    WEEDING = 110;

    // Weightlifting type.
    WEIGHTLIFTING = 10;

    // Weight machines type.
    WEIGHT_MACHINES = 150;

    // Weights type.
    WEIGHTS = 46;

    // Wheelchair type.
    WHEELCHAIR = 99;

    // Windsurfing type.
    WINDSURFING = 174;

    // Workout type.
    WORKOUT = 8;

    // Wrestling type.
    WRESTLING = 100;

    // Yoga type.
    YOGA = 6;

    // Yoga bikram type.
    YOGA_BIKRAM = 132;

    // Yoga hatha type.
    YOGA_HATHA = 133;

    // Yoga power type.
    YOGA_POWER = 134;

    // Yoga vinyasa type.
    YOGA_VINYASA = 135;

    // Zumba type.
    ZUMBA = 136;
  }

  // Required. Observed exercise interval
  SessionTimeInterval interval = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. The type of activity performed during an exercise.
  ExerciseType exercise_type = 6 [(google.api.field_behavior) = REQUIRED];

  // Optional. The default split is 1 km or 1 mile.
  // -  if the movement distance is less than the default,
  //    then there are no splits
  // -  if the movement distance is greater than or equal to the
  // default,
  //    then we have splits
  repeated SplitSummary splits = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Exercise events that happen during an exercise, such as pause &
  // restarts.
  repeated ExerciseEvent exercise_events = 15
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Laps or splits recorded within an exercise.
  // Laps could be split based on distance or other criteria (duration, etc.)
  // Laps should not be overlapping with each other.
  repeated SplitSummary split_summaries = 9
      [(google.api.field_behavior) = OPTIONAL];

  // Required. Summary metrics for this exercise
  // ( )
  MetricsSummary metrics_summary = 10 [(google.api.field_behavior) = REQUIRED];

  // Optional. Additional exercise metadata.
  ExerciseMetadata exercise_metadata = 11
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The localized, human-readable name of the exercise.
  // For all exercise types other than `OTHER`, the system ignores client
  // input and overrides this field with a generated name based on
  // `exercise_type` (e.g., "Walking" for `WALKING`). If `exercise_type` is
  // `OTHER`, this field can contain the user's custom, free-form display
  // name.
  string display_name = 12 [(google.api.field_behavior) = REQUIRED];

  // Optional. Duration excluding pauses.
  google.protobuf.Duration active_duration = 13
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Standard free-form notes captured at manual logging.
  string notes = 14 [(google.api.field_behavior) = OPTIONAL];

  // Output only. This is the timestamp of the last update to the exercise.
  google.protobuf.Timestamp update_time = 16
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Represents the timestamp of the creation of the exercise.
  google.protobuf.Timestamp create_time = 17
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Gained elevation measured in floors over the time interval
message Floors {
  // Required. Observed interval
  ObservationTimeInterval interval = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Number of floors in the recorded interval.
  // Must be in the range `[0, 1000000]`.
  optional int64 count = 4 [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the user's floors.
message FloorsRollupValue {
  // Sum of the floors count.
  optional int64 count_sum = 1;
}

// Represents the result of the rollup of the user's altitude.
message AltitudeRollupValue {
  // Sum of the altitude gain in millimeters.
  optional int64 gain_millimeters_sum = 1;
}

// A heart rate measurement.
message HeartRate {
  // Heart rate metadata.
  message HeartRateMetadata {
    // The user’s level of activity when the heart rate sample was measured.
    enum MotionContext {
      // The default value when no data is available.
      MOTION_CONTEXT_UNSPECIFIED = 0;

      // The user is active.
      ACTIVE = 1;

      // The user is inactive.
      SEDENTARY = 2;
    }

    // The location of the sensor that measured the heart rate.
    enum SensorLocation {
      // The default value when no data is available.
      SENSOR_LOCATION_UNSPECIFIED = 0;

      // Chest sensor.
      CHEST = 1;

      // Wrist sensor.
      WRIST = 2;

      // Finger sensor.
      FINGER = 3;

      // Hand sensor.
      HAND = 4;

      // Ear lobe sensor.
      EAR_LOBE = 5;

      // Foot sensor.
      FOOT = 6;
    }

    // Optional. Indicates the user’s level of activity when the heart rate
    // sample was measured
    MotionContext motion_context = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Indicates the location of the sensor that measured the heart
    // rate.
    SensorLocation sensor_location = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. Observation time
  ObservationSampleTime sample_time = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. The heart rate value in beats per minute.
  // Must be in the range `[1, 300]`.
  optional int64 beats_per_minute = 4 [(google.api.field_behavior) = REQUIRED];

  // Optional. Metadata about the heart rate sample.
  HeartRateMetadata metadata = 6 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the result of the rollup of the heart rate data type.
message HeartRateRollupValue {
  // The average heart rate value in the interval.
  optional double beats_per_minute_avg = 1;

  // The maximum heart rate value in the interval.
  optional double beats_per_minute_max = 2;

  // The minimum heart rate value in the interval.
  optional double beats_per_minute_min = 3;
}

// Represents the result of the rollup of the user's daily heart rate
// variability personal range.
message RunVO2MaxRollupValue {
  // Minimum value of run VO2 max in the interval..
  optional double rate_min = 1;

  // Maximum value of run VO2 max in the interval.
  optional double rate_max = 2;

  // Average value of run VO2 max in the interval.
  optional double rate_avg = 3;
}

// VO2 max value calculated based on the user's running activity.
// Value stored in ml/kg/min.
message RunVO2Max {
  // Required. The time at which the metric was measured.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. Run VO2 max value in ml/kg/min.
  // Must be in the range `[0, 100]`.
  optional double run_vo2_max = 2 [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the user's daily heart rate
// variability personal range.
message HeartRateVariabilityPersonalRangeRollupValue {
  // The lower bound of the user's average heart rate variability personal
  // range.
  optional double average_heart_rate_variability_milliseconds_min = 1;

  // The upper bound of the user's average heart rate variability personal
  // range.
  optional double average_heart_rate_variability_milliseconds_max = 2;
}

// Body height measurement.
message Height {
  // Required. The time at which the height was recorded.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. Height of the user in millimeters.
  // Must be in the range `[0, 3000]`.
  optional int64 height_millimeters = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Captures user's heart rate variability (HRV) as measured by the root mean
// square of successive differences (RMSSD) between normal heartbeats or by
// standard deviation of the inter-beat intervals (SDNN).
message HeartRateVariability {
  // Metadata for HeartRateVariability.
  message HeartRateVariabilityMetadata {
    // Optional. The power in interbeat interval fluctuations within the high
    // frequency band (0.15 Hz - 0.4 Hz).
    double high_frequency_power = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The power in interbeat interval fluctuations within the low
    // frequency band (0.04 Hz - 0.15 Hz).
    double low_frequency_power = 3 [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The time of the heart rate variability measurement.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Optional. The root mean square of successive differences between normal
  // heartbeats. This is a measure of heart rate variability used by Google
  // Health. Must be in the range `[1, 200]`.
  optional double root_mean_square_of_successive_differences_milliseconds = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The standard deviation of the heart rate variability measurement.
  optional double standard_deviation_milliseconds = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Additional information about the heart rate variability
  // measurement.
  HeartRateVariabilityMetadata metadata = 4
      [(google.api.field_behavior) = OPTIONAL];
}

// Represents the volume quantity.
message VolumeQuantity {
  // Required. Value representing the volume in milliliters.
  // Must be in the range `[0, 100000]`.
  optional double milliliters = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Value representing the user provided unit, used only for
  // user-facing input and display purposes. In the API format, all volume
  // quantities are converted to milliliters.
  VolumeUnit user_provided_unit = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Holds information about a user logged hydration.
message HydrationLog {
  // Required. Observed interval.
  SessionTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Amount of liquid (ex. water) consumed.
  VolumeQuantity amount_consumed = 2 [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the hydration log data type.
message HydrationLogRollupValue {
  // Rollup for volume quantity.
  message VolumeQuantityRollup {
    // Required. The sum of volume in milliliters.
    optional double milliliters_sum = 1
        [(google.api.field_behavior) = REQUIRED];

    // Optional. The user provided unit on the last element.
    VolumeUnit user_provided_unit_last = 2
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Rollup for amount consumed.
  VolumeQuantityRollup amount_consumed = 1;
}

// Represents an Irregular Rhythm Notification alert, indicating a potential
// sign of atrial fibrillation (AFib).
// This data type is based on SaMD feature and any changes to it may require
// additional review.
message IrregularRhythmNotification {
  // A single heart beat measurement.
  message HeartBeat {
    // Required. The time of the heart beat measurement.
    google.protobuf.Timestamp physical_time = 1
        [(google.api.field_behavior) = REQUIRED];

    // Required. The UTC offset of the user's timezone when the heart beat
    // measurement occurred.
    google.protobuf.Duration utc_offset = 2
        [(google.api.field_behavior) = REQUIRED];

    // Output only. The civil time in the timezone the subject is in
    // at the time of the observation.
    CivilDateTime civil_time = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Required. The beats-per-minute value extrapolated from the time before
    // the following heart beat. This is calculated as 60000 / rr, where rr is
    // the gap between heart beats in milliseconds (IBI - Interbeat Interval).
    optional int32 beats_per_minute = 4
        [(google.api.field_behavior) = REQUIRED];
  }

  // An analysis window evaluated for AFib.
  //
  // Note: The current version of the algorithm will only produce alerts if all
  // windows are positive. So anything returned from the API will always have
  // the positive bit set to true. Internally, windows can be negative, however.
  // We never save "inconclusive" windows (they aren't produced by the
  // algorithm).
  message AlertWindow {
    // Required. Observed interval.
    // The start time of the analysis window.
    google.protobuf.Timestamp start_time = 1
        [(google.api.field_behavior) = REQUIRED];

    // Required. The UTC offset of the user's timezone when the analysis window
    // started.
    google.protobuf.Duration start_utc_offset = 2
        [(google.api.field_behavior) = REQUIRED];

    // Required. The end time of the analysis window.
    google.protobuf.Timestamp end_time = 3
        [(google.api.field_behavior) = REQUIRED];

    // Required. The UTC offset of the user's timezone when the analysis window
    // ended.
    google.protobuf.Duration end_utc_offset = 4
        [(google.api.field_behavior) = REQUIRED];

    // Output only. Observed interval start time in civil time in the timezone
    // the subject is in at the start of the observed interval
    CivilDateTime civil_start_time = 5
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Observed interval end time in civil time in the timezone the
    // subject is in at the end of the observed interval
    CivilDateTime civil_end_time = 6
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Optional. Flag indicating whether the window was positive for AFib or
    // not. A `true` value indicates that AFib was detected in this window. A
    // `false` value means AFib was not detected, but does not guarantee the
    // absence of AFib.
    bool positive = 7 [(google.api.field_behavior) = OPTIONAL];

    // Optional. All heart beats in the interval contained in this analysis
    // window.
    repeated HeartBeat heart_beats = 8 [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. Observed interval.
  SessionTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The overlapping analysis windows that were used to evaluate
  // rhythm for potential AFib, containing specific information about the user's
  // heart rhythm.
  repeated AlertWindow alert_windows = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Output only. The meta information for the compatible device used to conduct
  // the measurement.
  //
  // Irregular Rhythm Notification measurements typically populate
  // `algorithm_version`, `service_version`, and `device_model`.
  MedicalDeviceInfo medical_device_info = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Summary metrics for an exercise.
message MetricsSummary {
  // Time spent in each heart rate zone.
  message TimeInHeartRateZones {
    // Optional. Time spent in light heart rate zone.
    google.protobuf.Duration light_time = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Time spent in moderate heart rate zone.
    google.protobuf.Duration moderate_time = 2
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Time spent in vigorous heart rate zone.
    google.protobuf.Duration vigorous_time = 3
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Time spent in peak heart rate zone.
    google.protobuf.Duration peak_time = 4
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Mobility workouts specific metrics
  message MobilityMetrics {
    // Optional. Cadence is a measure of the frequency of your foot strikes.
    // Steps / min in real time during workout.
    optional double avg_cadence_steps_per_minute = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Stride length is a measure of the distance covered by a single
    // stride
    optional int64 avg_stride_length_millimeters = 2
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Distance off the ground your center of mass moves with each
    // stride while running
    optional int64 avg_vertical_oscillation_millimeters = 3
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. Vertical oscillation/stride length between [5.0, 11.0].
    optional double avg_vertical_ratio = 4
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. The ground contact time for a particular stride is the amount
    // of time for which the foot was in contact with the ground on that stride
    google.protobuf.Duration avg_ground_contact_time_duration = 5
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Optional. Total calories burned by the user during the exercise.
  optional double calories_kcal = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Total distance covered by the user during the exercise.
  optional double distance_millimeters = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Total steps taken during the exercise.
  optional int64 steps = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Average speed in millimeters per second.
  optional double average_speed_millimeters_per_second = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Average pace in seconds per meter.
  optional double average_pace_seconds_per_meter = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Average heart rate during the exercise.
  optional int64 average_heart_rate_beats_per_minute = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Total elevation gain during the exercise.
  optional double elevation_gain_millimeters = 7
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Total active zone minutes for the exercise.
  optional int64 active_zone_minutes = 9
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Run VO2 max value for the exercise. Only present in the running
  // exercises at the top level as in the summary of the whole exercise.
  optional double run_vo2_max = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Number of full pool lengths completed during the exercise. Only
  // present in the swimming exercises at the top level as in the summary of the
  // whole exercise.
  optional double total_swim_lengths = 11
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Time spent in each heart rate zone.
  TimeInHeartRateZones heart_rate_zone_durations = 12
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Mobility workouts specific metrics. Only present in the advanced
  // running exercises.
  MobilityMetrics mobility_metrics = 13
      [(google.api.field_behavior) = OPTIONAL];
}

// Represents the weight quantity.
message WeightQuantity {
  // Required. The weight value in grams.
  // Must be in the range `[0, 100000]`.
  optional double grams = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Value representing the user provided unit.
  WeightUnit user_provided_unit = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the energy quantity.
message EnergyQuantity {
  // Required. The energy value in kilocalories.
  // Must be in the range `[0, 100000]`.
  optional double kcal = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Value representing the user provided unit.
  EnergyUnit user_provided_unit = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the quantity of a nutrient.
message NutrientQuantity {
  // Required. The quantity of the nutrient, measured in grams.
  WeightQuantity quantity = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The nutrient type.
  Nutrient nutrient = 2 [(google.api.field_behavior) = REQUIRED];
}

// Holds information about food logged by a user.
//
// There are two ways of creating a nutrition log based on the food type:
// 1. Identified food: Using the food field, which is a reference to a Food
// resource. In this case fields `nutrients`, `energy`, `energy_from_fat`,
// `total_carbohydrate`, `total_fat`, `food_display_name` will be populated
// based on the referenced food.
// 2. Anonymous food: Using the `food_display_name` field and setting
// the  `nutrients`, `energy`, `energy_from_fat`, `total_carbohydrate`,
// `total_fat` fields manually.
//
// The identified food is preferred over the anonymous food.
// Nutrition logs created from anonymous food are not editable.
message NutritionLog {
  // Represents different properties and information about the serving of a
  // specific food.
  message Serving {
    // Optional. The number of servings.
    optional double amount = 1 [(google.api.field_behavior) = OPTIONAL];

    // Required. Food measurement unit
    string food_measurement_unit = 2 [
      (google.api.field_behavior) = REQUIRED,
      (google.api.resource_reference) = {
        type: "health.googleapis.com/DataPoint"
      }
    ];

    // Output only. Legacy measurement unit for serving size in singular form
    // (e.g. "piece", "gram").
    string food_measurement_unit_display_name = 3
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Required. The time window when the food was logged.
  SessionTimeInterval interval = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. An array of individual nutrient values for the nutrition log.
  repeated NutrientQuantity nutrients = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The total energy of the food, measured in kilocalories (`kcal`).
  EnergyQuantity energy = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The energy from fat, measured in kilocalories (`kcal`).
  EnergyQuantity energy_from_fat = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The total carbohydrate content, measured in grams.
  WeightQuantity total_carbohydrate = 7
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The total fat content, measured in grams.
  WeightQuantity total_fat = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The meal category. One of `BREAKFAST`, `LUNCH`, `DINNER`, or
  // `SNACK`.
  MealType meal_type = 13 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The serving information for the logged food.
  Serving serving = 14 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The resource name of the Food item. Required when creating a
  // nutrition log from an identified food. For anonymous food logs, use the
  // `food_display_name` field instead.
  string food = 15 [
    (google.api.field_behavior) = OPTIONAL,
    (google.api.resource_reference) = {
      type: "health.googleapis.com/DataPoint"
    }
  ];

  // The display name of the food. For identified food logs, this is populated
  // automatically from the referenced food.
  string food_display_name = 16;
}

// Represents a food item.
message Food {
  // Represents different properties and information about the serving of a
  // specific food.
  message FoodServing {
    // Optional. Amount of food consumed, fractional values are supported.
    optional double amount = 1 [(google.api.field_behavior) = OPTIONAL];

    // Required. Food measurement unit
    string food_measurement_unit = 2 [
      (google.api.field_behavior) = REQUIRED,
      (google.api.resource_reference) = {
        type: "health.googleapis.com/DataPoint"
      }
    ];

    // Output only. Legacy measurement unit for serving size in singular form
    // (e.g. "piece", "gram").
    string food_measurement_unit_display_name = 3
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Legacy measurement unit for serving size in plural form
    // (e.g. "pieces", "grams").
    string food_measurement_unit_display_name_plural = 4
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Optional. Value representing the multiplier used to compute the energy
    // when using this serving instead of the default serving.
    double multiplier = 5 [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The display name of the food.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The brand of the food.
  string brand = 3 [(google.api.field_behavior) = OPTIONAL];

  // Required. The access level of the food.
  FoodAccessLevel access_level = 4 [(google.api.field_behavior) = REQUIRED];

  // Optional. The description of the food.
  string description = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The language code where the food is available in format xx-XX.
  // Supported values are defined in
  // [Settings.food_language_code][google.devicesandservices.health.v4beta.Settings.food_language_code].
  string language_code = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The meal type associated with this food.
  MealType meal_type = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Value representing the nutrients of the food for the default
  // serving.
  repeated NutrientQuantity nutrients = 12
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Value representing the energy from fat of the food for the
  // default serving.
  EnergyQuantity energy_from_fat = 13 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Value representing the total carbohydrate of the food for the
  // default serving.
  WeightQuantity total_carbohydrate = 14
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Value representing the total fat of the food for the default
  // serving.
  WeightQuantity total_fat = 15 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Value representing the minimum energy of the food for the default
  // serving.
  EnergyQuantity energy_min = 16 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Value representing the average energy of the food for the default
  // serving.
  EnergyQuantity energy_avg = 17 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Value representing the maximum energy of the food for the default
  // serving.
  EnergyQuantity energy_max = 18 [(google.api.field_behavior) = OPTIONAL];

  // Required. Value representing the default serving of the food.
  FoodServing default_serving = 19 [(google.api.field_behavior) = REQUIRED];

  // Optional. The serving of the food.
  repeated FoodServing servings = 20 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the result of the rollup of the nutrition log data type.
message NutritionLogRollupValue {
  // Rollup for the weight.
  message WeightQuantityRollup {
    // Required. The sum of the weight in grams.
    optional double grams_sum = 1 [(google.api.field_behavior) = REQUIRED];

    // Optional. The user provided unit on the last element.
    WeightUnit user_provided_unit_last = 2
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Rollup for the energy quantity.
  message EnergyQuantityRollup {
    // Required. The sum of the energy in kilocalories.
    optional double kcal_sum = 1 [(google.api.field_behavior) = REQUIRED];

    // Optional. The user provided unit on the last element.
    EnergyUnit user_provided_unit_last = 2
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Nutrient quantity rollup.
  message NutrientQuantityRollup {
    // Required. Aggregated nutrient weight.
    WeightQuantityRollup quantity = 1 [(google.api.field_behavior) = REQUIRED];

    // Required. Aggregated nutrient.
    Nutrient nutrient = 2 [(google.api.field_behavior) = REQUIRED];
  }

  // List of the nutrient roll-ups by the nutrient type.
  repeated NutrientQuantityRollup nutrients = 1;

  // Energy rollup.
  EnergyQuantityRollup energy = 2;

  // Value
  // Energy from fat rollup.
  EnergyQuantityRollup energy_from_fat = 3;

  // Total carbohydrate rollup.
  WeightQuantityRollup total_carbohydrate = 4;

  // Total fat rollup.
  WeightQuantityRollup total_fat = 5;
}

// Captures the user's instantaneous oxygen saturation percentage (SpO2).
message OxygenSaturation {
  // Required. The time at which oxygen saturation was measured.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The oxygen saturation percentage.
  // Must be in the range `[0, 100]`.
  optional double percentage = 2 [(google.api.field_behavior) = REQUIRED];
}

// Represents the rollup value for the daily resting heart rate data type.
message RestingHeartRatePersonalRangeRollupValue {
  // The lower bound of the user's daily resting heart rate personal range.
  optional double beats_per_minute_min = 1;

  // The upper bound of the user's daily resting heart rate personal range.
  optional double beats_per_minute_max = 2;
}

// Represents a food measurement unit.
message FoodMeasurementUnit {
  // Required. The display name of the food measurement unit (e.g., "gram",
  // "piece").
  string display_name = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The plural display name of the food measurement unit (e.g.,
  // "grams", "pieces").
  string plural_display_name = 2 [(google.api.field_behavior) = OPTIONAL];
}

// Records respiratory rate details during sleep.
// Can have multiple per day if the user sleeps multiple times.
message RespiratoryRateSleepSummary {
  // Respiratory rate statistics for a given sleep stage.
  message RespiratoryRateSleepSummaryStatistics {
    // Required. Average breaths per minute.
    optional double breaths_per_minute = 1
        [(google.api.field_behavior) = REQUIRED];

    // Optional. Standard deviation of the respiratory rate during sleep.
    optional double standard_deviation = 2
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. How trustworthy the data is for the computation.
    optional double signal_to_noise = 3
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The time at which respiratory rate was measured.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Respiratory rate statistics for deep sleep.
  RespiratoryRateSleepSummaryStatistics deep_sleep_stats = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Respiratory rate statistics for light sleep.
  RespiratoryRateSleepSummaryStatistics light_sleep_stats = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Respiratory rate statistics for REM sleep.
  RespiratoryRateSleepSummaryStatistics rem_sleep_stats = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Required. Full respiratory rate statistics.
  RespiratoryRateSleepSummaryStatistics full_sleep_stats = 5
      [(google.api.field_behavior) = REQUIRED];
}

// A sleep session possibly including stages.
message Sleep {
  // Sleep stage segment.
  message SleepStage {
    // Required. Sleep stage start time.
    google.protobuf.Timestamp start_time = 3
        [(google.api.field_behavior) = REQUIRED];

    // Required. The offset of the user's local time at the start of the sleep
    // stage relative to the Coordinated Universal Time (UTC).
    google.protobuf.Duration start_utc_offset = 4
        [(google.api.field_behavior) = REQUIRED];

    // Required. Sleep stage end time.
    google.protobuf.Timestamp end_time = 5
        [(google.api.field_behavior) = REQUIRED];

    // Required. The offset of the user's local time at the end of the sleep
    // stage relative to the Coordinated Universal Time (UTC).
    google.protobuf.Duration end_utc_offset = 6
        [(google.api.field_behavior) = REQUIRED];

    // Required. Sleep stage type: AWAKE, DEEP, REM, LIGHT etc.
    SleepStageType type = 7 [(google.api.field_behavior) = REQUIRED];

    // Output only. Creation time of this sleep stages segment.
    google.protobuf.Timestamp create_time = 8
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Last update time of this sleep stages segment.
    google.protobuf.Timestamp update_time = 9
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // A time interval to represent an out-of-bed segment.
  message OutOfBedSegment {
    // Required. Segment tart time.
    google.protobuf.Timestamp start_time = 1
        [(google.api.field_behavior) = REQUIRED];

    // Required. The offset of the user's local time at the start of the segment
    // relative to the Coordinated Universal Time (UTC).
    google.protobuf.Duration start_utc_offset = 2
        [(google.api.field_behavior) = REQUIRED];

    // Required. Segment end time.
    google.protobuf.Timestamp end_time = 3
        [(google.api.field_behavior) = REQUIRED];

    // Required. The offset of the user's local time at the end of the segment
    // relative to the Coordinated Universal Time (UTC).
    google.protobuf.Duration end_utc_offset = 4
        [(google.api.field_behavior) = REQUIRED];
  }

  // Additional information about how the sleep was processed.
  message SleepMetadata {
    // Sleep stages algorithm processing status.
    enum StagesState {
      // Output only. Sleep stages status is unspecified.
      STAGES_STATE_UNSPECIFIED = 0;

      // Output only. Sleep stages cannot be computed due to low RR coverage.
      REJECTED_COVERAGE = 1;

      // Output only. Sleep stages cannot be computed due to the large middle
      // gap (2h).
      REJECTED_MAX_GAP = 2;

      // Output only. Sleep stages cannot be computed due to the large start
      // gap (1h).
      REJECTED_START_GAP = 3;

      // Output only. Sleep stages cannot be computed due to the large end gap
      // (1h).
      REJECTED_END_GAP = 4;

      // Output only. Sleep stages cannot be computed because the sleep log is a
      // nap (has < 3h duration).
      REJECTED_NAP = 5;

      // Output only. Sleep stages cannot be computed because input data is not
      // available (PPGV2, wake magnitude, etc).
      REJECTED_SERVER = 6;

      // Output only. Sleep stages cannot be computed due to server timeout.
      TIMEOUT = 7;

      // Output only. Sleep stages successfully computed.
      SUCCEEDED = 8;

      // Output only. Sleep stages cannot be computed due to server internal
      // error.
      PROCESSING_INTERNAL_ERROR = 9;
    }

    // Output only. Sleep stages algorithm processing status.
    StagesState stages_status = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Sleep and sleep stages algorithms finished processing.
    // A `true` value indicates whether all data processing for the session is
    // complete.
    // A `false` value means sleep period is detected but sleep stages is still
    // processing.
    bool processed = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Naps are sleeps without stages and relatively short
    // durations.
    bool nap = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Some sleeps autodetected by algorithms can be manually
    // edited by users.
    bool manually_edited = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Optional. Sleep identifier relevant in the context of the data source.
    string external_id = 7 [(google.api.field_behavior) = OPTIONAL];

    // Output only. `main_sleep`: the longest sleep session with stages within
    // one day. If no sleep session has stages, then the longest sleep is the
    // `main_sleep`.  If there are multiple days of sleep in the response, there
    // is one `main_sleep` per day.
    bool main_sleep = 9 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  //
  // Sleep summary: metrics and stages summary.
  message SleepSummary {
    // Total duration and segment count for a stage.
    message StageSummary {
      // Output only. Sleep stage type: AWAKE, DEEP, REM, LIGHT etc.
      SleepStageType type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. Total duration in minutes of a sleep stage.
      optional int64 minutes = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. Number of sleep stages segments.
      optional int64 count = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
    }

    // Output only. Delta between wake time and bedtime. It is the sum of all
    // stages.
    optional int64 minutes_in_sleep_period = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Minutes after wake up calculated by restlessness algorithm.
    optional int64 minutes_after_wake_up = 2
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Minutes to fall asleep calculated by restlessness algorithm.
    optional int64 minutes_to_fall_asleep = 3
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Total number of minutes asleep.
    // For classic sleep it is the sum of ASLEEP stages (excluding AWAKE and
    // RESTLESS). For "stages" sleep it is the sum of LIGHT, REM and DEEP stages
    // (excluding AWAKE).
    optional int64 minutes_asleep = 4
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Total number of minutes awake. It is a sum of all AWAKE
    // stages.
    optional int64 minutes_awake = 5
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. List of summaries (total duration and segment count) per
    // each sleep stage type.
    repeated StageSummary stages_summary = 6
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Sleep type: classic or stages.
  enum SleepType {
    // Sleep type is unspecified.
    SLEEP_TYPE_UNSPECIFIED = 0;

    // Classic sleep is a sleep with 3 stages types: AWAKE, RESTLESS and ASLEEP.
    CLASSIC = 1;

    // On top of "classic" sleep stages an additional processing pass can
    // calculate stages more precisely, overwriting the prior stages with AWAKE,
    // LIGHT, REM and DEEP.
    STAGES = 2;
  }

  // Sleep stage type: AWAKE, DEEP, REM, LIGHT etc.
  enum SleepStageType {
    // The default unset value.
    SLEEP_STAGE_TYPE_UNSPECIFIED = 0;

    // Sleep stage AWAKE.
    AWAKE = 1;

    // Sleep stage LIGHT.
    LIGHT = 2;

    // Sleep stage DEEP.
    DEEP = 3;

    // Sleep stage REM.
    REM = 4;

    // Sleep stage ASLEEP.
    ASLEEP = 5;

    // Sleep stage RESTLESS.
    RESTLESS = 6;
  }

  // Required. Observed sleep interval.
  SessionTimeInterval interval = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. SleepType: classic or stages.
  SleepType type = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. List of non-overlapping contiguous sleep stage segments that
  // cover the sleep period.
  repeated SleepStage stages = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional.
  // “Out of bed” segments that can overlap with sleep stages.
  repeated OutOfBedSegment out_of_bed_segments = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Sleep metadata: `processed`, `main_sleep`, `manually_edited`, and
  // `stages_status`.
  SleepMetadata metadata = 8 [(google.api.field_behavior) = OPTIONAL];

  // Output only. Sleep summary: metrics and stages summary.
  SleepSummary summary = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Creation time of this sleep observation.
  google.protobuf.Timestamp create_time = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Last update time of this sleep observation.
  google.protobuf.Timestamp update_time = 11
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. List of short awake segments (under a set threshold) that are
  // part of the sleep session. These can overlap with sleep stages.
  repeated SleepStage short_awakenings = 12
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Step count over the time interval.
message Steps {
  // Required. Observed interval.
  ObservationTimeInterval interval = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Number of steps in the recorded interval.
  // Must be in the range `[0, 1000000]`.
  optional int64 count = 4 [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the steps data type.
message StepsRollupValue {
  // Total number of steps in the interval.
  optional int64 count_sum = 1;
}

// Swim lengths data over the time interval.
message SwimLengthsData {
  // Swim stroke type.
  enum SwimStrokeType {
    // Swim stroke type is unspecified.
    SWIM_STROKE_TYPE_UNSPECIFIED = 0;

    // Freestyle swim stroke type.
    FREESTYLE = 1;

    // Backstroke swim stroke type.
    BACKSTROKE = 2;

    // Breaststroke swim stroke type.
    BREASTSTROKE = 3;

    // Butterfly swim stroke type.
    BUTTERFLY = 4;
  }

  // Required. Observed interval.
  ObservationTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Swim stroke type.
  SwimStrokeType swim_stroke_type = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Number of strokes in the lap.
  optional int64 stroke_count = 3 [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the swim lengths data type.
message SwimLengthsDataRollupValue {
  // Total number of swim strokes in the interval.
  optional int64 stroke_count_sum = 1;
}

// Time in heart rate zone record. It's an interval spent in specific heart
// rate zone.
message TimeInHeartRateZone {
  // Required. Observed interval.
  ObservationTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Heart rate zone type.
  HeartRateZoneType heart_rate_zone_type = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the time in heart rate zone data
// type.
message TimeInHeartRateZoneRollupValue {
  // Represents the total time spent in a specific heart rate zone.
  message TimeInHeartRateZoneValue {
    // The heart rate zone.
    HeartRateZoneType heart_rate_zone = 1;

    // The total time spent in the specified heart rate zone.
    google.protobuf.Duration duration = 2;
  }

  // List of time spent in each heart rate zone.
  repeated TimeInHeartRateZoneValue time_in_heart_rate_zones = 1;
}

// Represents the result of the rollup of the user's total calories.
//
// Note: Queries for the `total-calories` data type must include a time
// interval filter (such as
// [`total_calories.interval.start_time`][google.devicesandservices.health.v4main.ObservationTimeInterval.start_time]
// or
// [`total_calories.interval.civil_start_time`][google.devicesandservices.health.v4main.ObservationTimeInterval.civil_start_time]).
// The maximum range is 14 days.
//
// Example filter query:
// `total_calories.interval.start_time >= "2026-04-20T00:00:00Z" AND
// total_calories.interval.start_time < "2026-04-21T00:00:00Z"`
message TotalCaloriesRollupValue {
  // Sum of the total calories in kilocalories.
  optional double kcal_sum = 1;
}

// VO2 max measurement.
message VO2Max {
  // Measurement method used to measure the VO2 max value.
  enum MeasurementMethod {
    // Unspecified measurement method.
    MEASUREMENT_METHOD_UNSPECIFIED = 0;

    // Fitbit specific, measures VO2 max rate during a run.
    FITBIT_RUN = 1;

    // Google specific, measures VO2 max rate for a user based on their
    // demographic data.
    GOOGLE_DEMOGRAPHIC = 2;

    // Run as far as possible for 12 minutes. Distance correlated with age and
    // gender translates to a VO2 max value.
    COOPER_TEST = 3;

    // Maximum heart rate divided by the resting heart rate, with a multiplier
    // applied. Does not require any exercise.
    HEART_RATE_RATIO = 4;

    // Measured by a medical device called metabolic cart.
    METABOLIC_CART = 5;

    // Continuous 20m back-and-forth runs with increasing difficulty, until
    // exhaustion.
    MULTISTAGE_FITNESS_TEST = 6;

    // Measured using walking exercise.
    ROCKPORT_FITNESS_TEST = 7;

    // Healthkit specific, measures VO2 max rate by monitoring exercise to the
    // user’s physical limit. Similar to COOPER_TEST or
    // MULTISTAGE_FITNESS_TEST.
    MAX_EXERCISE = 8;

    // Healthkit specific, estimates VO2 max rate based on low-intensity
    // exercise. Similar to ROCKPORT_FITNESS_TEST.
    PREDICTION_SUB_MAX_EXERCISE = 9;

    // Healthkit specific, estimates VO2 max rate without any exercise.
    // Similar to HEART_RATE_RATIO.
    PREDICTION_NON_EXERCISE = 10;

    // Use when the method is not covered in this enum.
    OTHER = 11;
  }

  // Required. The time at which VO2 max was measured.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. VO2 max value measured as in ml consumed oxygen / kg of body
  // weight / min. Must be in the range `[0, 100]`.
  optional double vo2_max = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The method used to measure the VO2 max value.
  MeasurementMethod measurement_method = 4
      [(google.api.field_behavior) = OPTIONAL];
}

// Body weight measurement.
message Weight {
  // Required. The time at which the weight was measured
  ObservationSampleTime sample_time = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. Weight of a user in grams.
  // Must be in the range `[0, 1000000]`.
  optional double weight_grams = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. Standard free-form notes captured at manual logging.
  string notes = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the result of the rollup of the weight data type.
message WeightRollupValue {
  // Average weight in grams.
  optional double weight_grams_avg = 1;
}

// Represents a blood glucose level measurement.
// LINT: LEGACY_NAMES
message BloodGlucose {
  // The clinical method or tool used to measure the blood glucose level.
  enum MeasurementSource {
    // Unspecified measurement source.
    MEASUREMENT_SOURCE_UNSPECIFIED = 0;

    // Self-monitoring of blood glucose (Blood glucose meter)
    SELF_MONITORING_BLOOD_GLUCOSE = 1;

    // Continuous glucose monitoring device
    CONTINUOUS_GLUCOSE_MONITORING = 2;

    // Laboratory test
    LAB_TEST = 3;
  }

  // Meal type associated with the measurement.
  enum MealType {
    // Unspecified meal type.
    MEAL_TYPE_UNSPECIFIED = 0;

    // Breakfast.
    BREAKFAST = 1;

    // Lunch.
    LUNCH = 2;

    // Dinner.
    DINNER = 3;

    // Snack.
    SNACK = 4;
  }

  // Timing of the measurement.
  enum MeasurementTiming {
    // Unspecified measurement timing.
    MEASUREMENT_TIMING_UNSPECIFIED = 0;

    // Measurement taken after meal.
    AFTER_MEAL = 1;

    // Measurement taken before meal.
    BEFORE_MEAL = 2;

    // Measurement taken while fasting.
    FASTING = 3;

    // General measurement (not associated with a meal or time of day).
    GENERAL = 4;

    // Measurement taken before bed.
    BEFORE_BED = 5;

    // Measurement taken over night.
    OVER_NIGHT = 6;
  }

  // Type of body fluid used to measure the blood glucose.
  enum Specimen {
    // Unspecified specimen.
    SPECIMEN_UNSPECIFIED = 0;

    // Capillary blood.
    CAPILLARY_BLOOD = 1;

    // Interstitial fluid.
    INTERSTITIAL_FLUID = 2;

    // Plasma.
    PLASMA = 3;

    // Serum.
    SERUM = 4;

    // Tears.
    TEARS = 5;

    // Whole blood.
    WHOLE_BLOOD = 6;
  }

  // Required. The time at which blood glucose was measured.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. Blood glucose level concentration in mg/dL.
  // Must be in the range `[0, 900]`.
  optional double blood_glucose_milligrams_per_deciliter = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Source of the measurement.
  MeasurementSource measurement_source = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Meal type of the measurement.
  MealType meal_type = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Timing of the measurement.
  MeasurementTiming measurement_timing = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Type of body fluid used to measure the blood glucose.
  Specimen specimen = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Standard free-form notes captured at manual logging.
  string notes = 8 [(google.api.field_behavior) = OPTIONAL];
}

// Represents the result of the rollup of the blood glucose data type.
// LINT: LEGACY_NAMES
message BloodGlucoseRollupValue {
  // Average blood glucose level in mg/dL.
  optional double blood_glucose_milligrams_per_deciliter_avg = 1;
}

// SedentaryPeriod
//
// SedentaryPeriod data represents the periods of time that the user was
// sedentary (i.e. not moving while wearing the device).
message SedentaryPeriod {
  // Required. Observed interval.
  ObservationTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of the user's sedentary periods.
message SedentaryPeriodRollupValue {
  // The total time user spent sedentary during the interval.
  google.protobuf.Duration duration_sum = 1;
}

// Energy burned as part of an activity, excluding the basal energy burn.
message ActiveEnergyBurned {
  // Required. Observed interval
  ObservationTimeInterval interval = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. Energy burned during an activity, measured in kilocalories.
  // Must be in the range `[0, 1000000]`.
  optional double kcal = 2 [(google.api.field_behavior) = REQUIRED];
}

// Represents the result of the rollup of active energy burned.
message ActiveEnergyBurnedRollupValue {
  // Output only. Sum of the active energy burned in kilocalories.
  optional double kcal_sum = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Menstrual period record.
message MenstrualPeriod {
  // Required. Observed interval.
  ObservationTimeInterval interval = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Standard free-form notes captured at manual logging.
  string notes = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Ovulation test record.
message OvulationTest {
  // Required. The time at which ovulation test was measured.
  ObservationSampleTime sample_time = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. The result of the ovulation test.
  OvulationTestResult result = 3 [(google.api.field_behavior) = REQUIRED];
}

// Symptoms logged by the user.
message Symptoms {
  // Enum representing possible symptom values.
  enum SymptomValue {
    // Unspecified symptom value.
    SYMPTOM_VALUE_UNSPECIFIED = 0;

    // Abdominal cramps.
    CRAMPS = 1;

    // Headache.
    HEADACHE = 2;

    // Tender breasts.
    TENDER_BREASTS = 3;

    // Acne.
    ACNE = 4;

    // Feeling sick or unwell.
    SICK = 5;

    // Bloating or abdominal swelling.
    BLOATED = 6;

    // Hot flashes.
    HOT_FLASHES = 7;

    // Premenstrual syndrome symptoms.
    PMS = 8;

    // Coughing.
    COUGH = 9;

    // Fever or elevated body temperature.
    FEVER = 10;

    // Difficulty breathing or shortness of breath.
    DIFFICULTY_BREATHING = 11;

    // Back pain.
    BACK_PAIN = 12;

    // Shakiness or tremors.
    SHAKINESS = 13;

    // Excessive hunger.
    HUNGER = 14;

    // Excessive sweating.
    SWEATING = 15;

    // Anxiety or nervousness.
    ANXIETY = 16;

    // Excessive thirst.
    THIRST = 17;

    // Frequent urination.
    FREQUENT_URINATION = 18;

    // Blurred vision.
    BLURRED_VISION = 19;

    // Other symptoms.
    OTHER = 20;

    // High sex drive.
    SEX_DRIVE_HIGH = 21;

    // Medium sex drive.
    SEX_DRIVE_MEDIUM = 22;

    // Low sex drive.
    SEX_DRIVE_LOW = 23;

    // Heart palpitations or racing heart.
    HEART_PALPITATIONS = 24;

    // Fainting or loss of consciousness.
    FAINTING = 25;

    // Chest pain or discomfort.
    CHEST_PAIN = 26;

    // Fatigue or extreme tiredness.
    FATIGUE = 27;

    // Confusion or mental fogginess.
    CONFUSION = 28;

    // Dizziness or lightheadedness.
    DIZZINESS = 29;

    // Abdominal pain.
    ABDOMINAL_PAIN = 30;

    // Bladder leaks.
    BLADDER_LEAKS = 31;

    // Bleeding gums.
    BLEEDING_GUMS = 32;

    // Brain fog.
    BRAIN_FOG = 33;

    // Burning mouth.
    BURNING_MOUTH = 34;

    // Constipation.
    CONSTIPATION = 35;

    // Food cravings.
    CRAVINGS = 36;

    // Decreased appetite.
    DECREASED_APPETITE = 37;

    // Diarrhea.
    DIARRHEA = 38;

    // Drawing pain.
    DRAWING_PAIN = 39;

    // Dry eyes.
    DRY_EYES = 40;

    // Dry hair.
    DRY_HAIR = 41;

    // Dry skin.
    DRY_SKIN = 42;

    // Exhaustion.
    EXHAUSTION = 43;

    // Feeling good or well.
    FEEL_GOOD = 44;

    // Food aversions.
    FOOD_AVERSIONS = 45;

    // Hair loss.
    HAIR_LOSS = 46;

    // Heartburn.
    HEARTBURN = 47;

    // Hyperpigmentation.
    HYPERPIGMENTATION = 48;

    // Increased appetite.
    INCREASED_APPETITE = 49;

    // Increased appetite V2.
    INCREASED_APPETITE_V2 = 50;

    // Insomnia or difficulty sleeping.
    INSOMNIA = 51;

    // Joint pain.
    JOINT_PAIN = 52;

    // Leg cramps.
    LEG_CRAMPS = 53;

    // Milky nipple discharge.
    MILKY_NIPPLE_DISCHARGE = 54;

    // Nausea.
    NAUSEA = 55;

    // Night sweats.
    NIGHT_SWEATS = 56;

    // Normal digestion.
    NORMAL_DIGESTION = 57;

    // Normal stool.
    NORMAL_STOOL = 58;

    // Perineum pain.
    PERINEUM_PAIN = 59;

    // Sleepiness or drowsiness.
    SLEEPINESS = 60;

    // Stretch marks.
    STRETCH_MARKS = 61;

    // Swelling.
    SWELLING = 62;

    // Vaginal dryness.
    VAGINAL_DRYNESS = 63;

    // Vaginal itching.
    VAGINAL_ITCHING = 64;

    // Vomiting.
    VOMITING = 65;
  }

  // Required. Time when the symptoms were logged.
  ObservationSampleTime sample_time = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. List of symptoms experienced.
  repeated SymptomValue symptoms = 2 [(google.api.field_behavior) = REQUIRED];
}

// Moods record.
message Moods {
  // The mood.
  enum Mood {
    // Unspecified mood.
    MOOD_UNSPECIFIED = 0;

    // Amazed.
    AMAZED = 1;

    // Amused.
    AMUSED = 2;

    // Angry.
    ANGRY = 3;

    // Annoyed.
    ANNOYED = 4;

    // Anxious.
    ANXIOUS = 5;

    // Happy.
    HAPPY = 6;

    // Content.
    CONTENT = 7;

    // Sad.
    SAD = 8;

    // Worried.
    WORRIED = 9;

    // Frustrated.
    FRUSTRATED = 10;

    // Excited.
    EXCITED = 11;

    // Calm.
    CALM = 12;

    // Stressed.
    STRESSED = 13;

    // Ashamed.
    ASHAMED = 14;

    // Brave.
    BRAVE = 15;

    // Confident.
    CONFIDENT = 16;

    // Disappointed.
    DISAPPOINTED = 17;

    // Discouraged.
    DISCOURAGED = 18;

    // Disgusted.
    DISGUSTED = 19;

    // Drained.
    DRAINED = 20;

    // Embarrassed.
    EMBARRASSED = 21;

    // Grateful.
    GRATEFUL = 22;

    // Guilty.
    GUILTY = 23;

    // Hopeful.
    HOPEFUL = 24;

    // Hopeless.
    HOPELESS = 25;

    // Indifferent.
    INDIFFERENT = 26;

    // Irritated.
    IRRITATED = 27;

    // Jealous.
    JEALOUS = 28;

    // Joyful.
    JOYFUL = 29;

    // Lonely.
    LONELY = 30;

    // Overwhelmed.
    OVERWHELMED = 31;

    // Passionate.
    PASSIONATE = 32;

    // Peaceful.
    PEACEFUL = 33;

    // Proud.
    PROUD = 34;

    // Relieved.
    RELIEVED = 35;

    // Satisfied.
    SATISFIED = 36;

    // Scared.
    SCARED = 37;

    // Surprised.
    SURPRISED = 38;

    // Energized.
    ENERGIZED = 39;

    // Fatigued.
    FATIGUED = 40;

    // Very calm.
    VERY_CALM = 41;

    // Very stressed.
    VERY_STRESSED = 42;

    // Neutral.
    NEUTRAL = 43;

    // Afraid.
    AFRAID = 44;

    // Hurting.
    HURTING = 45;

    // Bored.
    BORED = 46;

    // Bitter.
    BITTER = 47;

    // Envious.
    ENVIOUS = 48;

    // Confused.
    CONFUSED = 49;

    // Curious.
    CURIOUS = 50;

    // Awestruck.
    AWESTRUCK = 51;

    // Inspired.
    INSPIRED = 52;

    // Longing.
    LONGING = 53;

    // Accomplished.
    ACCOMPLISHED = 54;

    // Loving.
    LOVING = 55;

    // Compassionate.
    COMPASSIONATE = 56;

    // Depressed.
    DEPRESSED = 57;

    // Good.
    GOOD = 58;

    // Low energy.
    LOW_ENERGY = 59;

    // Obsessive thoughts.
    OBSESSIVE_THOUGHTS = 60;

    // Panic.
    PANIC = 61;

    // Playful.
    PLAYFUL = 62;

    // Pleased.
    PLEASED = 63;

    // Sensitive.
    SENSITIVE = 64;

    // Sleepy.
    SLEEPY = 65;

    // Mood swings.
    SWINGS = 66;

    // Unhappy.
    UNHAPPY = 67;

    // Very self-critical.
    VERY_SELF_CRITICAL = 68;
  }

  // The valence.
  enum Valence {
    // Unspecified valence.
    VALENCE_UNSPECIFIED = 0;

    // Unpleasant.
    UNPLEASANT = 1;

    // Baseline.
    BASELINE = 2;

    // Pleasant.
    PLEASANT = 3;
  }

  // Required. The time at which moods were measured.
  ObservationSampleTime sample_time = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. The moods logged.
  repeated Mood moods = 3 [(google.api.field_behavior) = REQUIRED];

  // Optional. The valences.
  repeated Valence valences = 5 [(google.api.field_behavior) = OPTIONAL];
}
