// Copyright 2024 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.maps.places.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/geo/type/viewport.proto";
import "google/maps/places/v1/contextual_content.proto";
import "google/maps/places/v1/ev_charging.proto";
import "google/maps/places/v1/geometry.proto";
import "google/maps/places/v1/place.proto";
import "google/type/latlng.proto";

option cc_enable_arenas = true;
option csharp_namespace = "Google.Maps.Places.V1";
option go_package = "cloud.google.com/go/maps/places/apiv1/placespb;placespb";
option java_multiple_files = true;
option java_outer_classname = "PlacesServiceProto";
option java_package = "com.google.maps.places.v1";
option objc_class_prefix = "GMPSV1";
option php_namespace = "Google\\Maps\\Places\\V1";

// Service definition for the Places API.
// Note: every request (except for Autocomplete requests) requires a field mask
// set outside of the request proto (`all/*`, is not assumed). The field mask
// can be set via the HTTP header `X-Goog-FieldMask`. See:
// https://developers.google.com/maps/documentation/places/web-service/choose-fields
service Places {
  option (google.api.default_host) = "places.googleapis.com";

  // Search for places near locations.
  rpc SearchNearby(SearchNearbyRequest) returns (SearchNearbyResponse) {
    option (google.api.http) = {
      post: "/v1/places:searchNearby"
      body: "*"
    };
  }

  // Text query based place search.
  rpc SearchText(SearchTextRequest) returns (SearchTextResponse) {
    option (google.api.http) = {
      post: "/v1/places:searchText"
      body: "*"
    };
  }

  // Get a photo media with a photo reference string.
  rpc GetPhotoMedia(GetPhotoMediaRequest) returns (PhotoMedia) {
    option (google.api.http) = {
      get: "/v1/{name=places/*/photos/*/media}"
    };
    option (google.api.method_signature) = "name";
  }

  // Get the details of a place based on its resource name, which is a string
  // in the `places/{place_id}` format.
  rpc GetPlace(GetPlaceRequest) returns (Place) {
    option (google.api.http) = {
      get: "/v1/{name=places/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Returns predictions for the given input.
  rpc AutocompletePlaces(AutocompletePlacesRequest)
      returns (AutocompletePlacesResponse) {
    option (google.api.http) = {
      post: "/v1/places:autocomplete"
      body: "*"
    };
  }
}

// Request proto for Search Nearby.
//
//
message SearchNearbyRequest {
  // The region to search.
  message LocationRestriction {
    oneof type {
      // A circle defined by center point and radius.
      Circle circle = 2;
    }
  }

  // How results will be ranked in the response.
  enum RankPreference {
    // RankPreference value not set. Will use rank by POPULARITY by default.
    RANK_PREFERENCE_UNSPECIFIED = 0;

    // Ranks results by distance.
    DISTANCE = 1;

    // Ranks results by popularity.
    POPULARITY = 2;
  }

  // Place details will be displayed with the preferred language if available.
  // If the language code is unspecified or unrecognized, place details of any
  // language may be returned, with a preference for English if such details
  // exist.
  //
  // Current list of supported languages:
  // https://developers.google.com/maps/faq#languagesupport.
  string language_code = 1;

  // The Unicode country/region code (CLDR) of the location where the
  // request is coming from. This parameter is used to display the place
  // details, like region-specific place name, if available. The parameter can
  // affect results based on applicable law.
  //
  // For more information, see
  // https://www.unicode.org/cldr/charts/latest/supplemental/territory_language_information.html.
  //
  //
  // Note that 3-digit region codes are not currently supported.
  string region_code = 2;

  // Included Place type (eg, "restaurant" or "gas_station") from
  // https://developers.google.com/maps/documentation/places/web-service/place-types.
  //
  // Up to 50 types from [Table
  // A](https://developers.google.com/maps/documentation/places/web-service/place-types#table-a)
  // may be specified.
  //
  // If there are any conflicting types, i.e. a type appears in both
  // included_types and excluded_types, an INVALID_ARGUMENT error is
  // returned.
  //
  // If a Place type is specified with multiple type restrictions, only places
  // that satisfy all of the restrictions are returned. For example, if we
  // have {included_types = ["restaurant"], excluded_primary_types =
  // ["restaurant"]}, the returned places provide "restaurant"
  // related services but do not operate primarily as "restaurants".
  repeated string included_types = 3;

  // Excluded Place type (eg, "restaurant" or "gas_station") from
  // https://developers.google.com/maps/documentation/places/web-service/place-types.
  //
  // Up to 50 types from [Table
  // A](https://developers.google.com/maps/documentation/places/web-service/place-types#table-a)
  // may be specified.
  //
  // If the client provides both included_types (e.g. restaurant) and
  // excluded_types (e.g. cafe), then the response should include places that
  // are restaurant but not cafe. The response includes places that match at
  // least one of the included_types and none of the excluded_types.
  //
  // If there are any conflicting types, i.e. a type appears in both
  // included_types and excluded_types, an INVALID_ARGUMENT error is returned.
  //
  // If a Place type is specified with multiple type restrictions, only places
  // that satisfy all of the restrictions are returned. For example, if we
  // have {included_types = ["restaurant"], excluded_primary_types =
  // ["restaurant"]}, the returned places provide "restaurant"
  // related services but do not operate primarily as "restaurants".
  repeated string excluded_types = 4;

  // Included primary Place type (e.g. "restaurant" or "gas_station") from
  // https://developers.google.com/maps/documentation/places/web-service/place-types.
  // A place can only have a single primary type from the supported types table
  // associated with it.
  //
  // Up to 50 types from [Table
  // A](https://developers.google.com/maps/documentation/places/web-service/place-types#table-a)
  // may be specified.
  //
  // If there are any conflicting primary types, i.e. a type appears in both
  // included_primary_types and excluded_primary_types, an INVALID_ARGUMENT
  // error is returned.
  //
  // If a Place type is specified with multiple type restrictions, only places
  // that satisfy all of the restrictions are returned. For example, if we
  // have {included_types = ["restaurant"], excluded_primary_types =
  // ["restaurant"]}, the returned places provide "restaurant"
  // related services but do not operate primarily as "restaurants".
  repeated string included_primary_types = 5;

  // Excluded primary Place type (e.g. "restaurant" or "gas_station") from
  // https://developers.google.com/maps/documentation/places/web-service/place-types.
  //
  // Up to 50 types from [Table
  // A](https://developers.google.com/maps/documentation/places/web-service/place-types#table-a)
  // may be specified.
  //
  // If there are any conflicting primary types, i.e. a type appears in both
  // included_primary_types and excluded_primary_types, an INVALID_ARGUMENT
  // error is returned.
  //
  // If a Place type is specified with multiple type restrictions, only places
  // that satisfy all of the restrictions are returned. For example, if we
  // have {included_types = ["restaurant"], excluded_primary_types =
  // ["restaurant"]}, the returned places provide "restaurant"
  // related services but do not operate primarily as "restaurants".
  repeated string excluded_primary_types = 6;

  // Maximum number of results to return. It must be between 1 and 20 (default),
  // inclusively. If the number is unset, it falls back to the upper limit. If
  // the number is set to negative or exceeds the upper limit, an
  // INVALID_ARGUMENT error is returned.
  int32 max_result_count = 7;

  // Required. The region to search.
  LocationRestriction location_restriction = 8
      [(google.api.field_behavior) = REQUIRED];

  // How results will be ranked in the response.
  RankPreference rank_preference = 9;
}

// Response proto for Search Nearby.
//
message SearchNearbyResponse {
  // A list of places that meets user's requirements like places
  // types, number of places and specific location restriction.
  repeated Place places = 1;
}

// Request proto for SearchText.
//
//
message SearchTextRequest {
  // How results will be ranked in the response.
  enum RankPreference {
    // For a categorical query such as "Restaurants in New York City", RELEVANCE
    // is the default. For non-categorical queries such as "Mountain View, CA"
    // we recommend that you leave rankPreference unset.
    RANK_PREFERENCE_UNSPECIFIED = 0;

    // Ranks results by distance.
    DISTANCE = 1;

    // Ranks results by relevance. Sort order determined by normal ranking
    // stack.
    RELEVANCE = 2;
  }

  // The region to search. This location serves as a bias which means results
  // around given location might be returned.
  message LocationBias {
    oneof type {
      // A rectangle box defined by northeast and southwest corner.
      // `rectangle.high()` must be the northeast point of the rectangle
      // viewport. `rectangle.low()` must be the southwest point of the
      // rectangle viewport. `rectangle.low().latitude()` cannot be greater than
      // `rectangle.high().latitude()`. This will result in an empty latitude
      // range. A rectangle viewport cannot be wider than 180 degrees.
      google.geo.type.Viewport rectangle = 1;

      // A circle defined by center point and radius.
      Circle circle = 2;
    }
  }

  // The region to search. This location serves as a restriction which means
  // results outside given location will not be returned.
  message LocationRestriction {
    oneof type {
      // A rectangle box defined by northeast and southwest corner.
      // `rectangle.high()` must be the northeast point of the rectangle
      // viewport. `rectangle.low()` must be the southwest point of the
      // rectangle viewport. `rectangle.low().latitude()` cannot be greater than
      // `rectangle.high().latitude()`. This will result in an empty latitude
      // range. A rectangle viewport cannot be wider than 180 degrees.
      google.geo.type.Viewport rectangle = 1;
    }
  }

  // Searchable EV options of a place search request.
  message EVOptions {
    // Optional. Minimum required charging rate in kilowatts. A place with a
    // charging rate less than the specified rate is filtered out.
    double minimum_charging_rate_kw = 1
        [(google.api.field_behavior) = OPTIONAL];

    // Optional. The list of preferred EV connector types. A place that does not
    // support any of the listed connector types is filtered out.
    repeated EVConnectorType connector_types = 2
        [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The text query for textual search.
  string text_query = 1 [(google.api.field_behavior) = REQUIRED];

  // Place details will be displayed with the preferred language if available.
  // If the language code is unspecified or unrecognized, place details of any
  // language may be returned, with a preference for English if such details
  // exist.
  //
  // Current list of supported languages:
  // https://developers.google.com/maps/faq#languagesupport.
  string language_code = 2;

  // The Unicode country/region code (CLDR) of the location where the
  // request is coming from. This parameter is used to display the place
  // details, like region-specific place name, if available. The parameter can
  // affect results based on applicable law.
  //
  // For more information, see
  // https://www.unicode.org/cldr/charts/latest/supplemental/territory_language_information.html.
  //
  //
  // Note that 3-digit region codes are not currently supported.
  string region_code = 3;

  // How results will be ranked in the response.
  RankPreference rank_preference = 4;

  // The requested place type. Full list of types supported:
  // https://developers.google.com/maps/documentation/places/web-service/place-types.
  // Only support one included type.
  string included_type = 6;

  // Used to restrict the search to places that are currently open.  The default
  // is false.
  bool open_now = 7;

  // Filter out results whose average user rating is strictly less than this
  // limit. A valid value must be a float between 0 and 5 (inclusively) at a
  // 0.5 cadence i.e. [0, 0.5, 1.0, ... , 5.0] inclusively. The input rating
  // will round up to the nearest 0.5(ceiling). For instance, a rating of 0.6
  // will eliminate all results with a less than 1.0 rating.
  double min_rating = 9;

  // Maximum number of results to return. It must be between 1 and 20,
  // inclusively. The default is 20.  If the number is unset, it falls back to
  // the upper limit. If the number is set to negative or exceeds the upper
  // limit, an INVALID_ARGUMENT error is returned.
  int32 max_result_count = 10;

  // Used to restrict the search to places that are marked as certain price
  // levels. Users can choose any combinations of price levels. Default to
  // select all price levels.
  repeated PriceLevel price_levels = 11;

  // Used to set strict type filtering for included_type. If set to true, only
  // results of the same type will be returned. Default to false.
  bool strict_type_filtering = 12;

  // The region to search. This location serves as a bias which means results
  // around given location might be returned. Cannot be set along with
  // location_restriction.
  LocationBias location_bias = 13;

  // The region to search. This location serves as a restriction which means
  // results outside given location will not be returned. Cannot be set along
  // with location_bias.
  LocationRestriction location_restriction = 14;

  // Optional. Set the searchable EV options of a place search request.
  EVOptions ev_options = 15 [(google.api.field_behavior) = OPTIONAL];
}

// Response proto for SearchText.
//
message SearchTextResponse {
  // A list of places that meet the user's text search criteria.
  repeated Place places = 1;

  // Experimental: See
  // https://developers.google.com/maps/documentation/places/web-service/experimental/places-generative
  // for more details.
  //
  // A list of contextual contents where each entry associates to the
  // corresponding place in the same index in the places field. The contents
  // that are relevant to the `text_query` in the request are preferred. If the
  // contextual content is not available for one of the places, it will return
  // non-contextual content. It will be empty only when the content is
  // unavailable for this place. This list should have as many entries as the
  // list of places if requested.
  repeated ContextualContent contextual_contents = 3;
}

// Request for fetching a photo of a place using a photo resource name.
message GetPhotoMediaRequest {
  // Required. The resource name of a photo media in the format:
  // `places/{place_id}/photos/{photo_reference}/media`.
  //
  // The resource name of a photo as returned in a Place object's `photos.name`
  // field comes with the format
  // `places/{place_id}/photos/{photo_reference}`. You need to append `/media`
  // at the end of the photo resource to get the photo media resource name.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "places.googleapis.com/PhotoMedia"
    }
  ];

  // Optional. Specifies the maximum desired width, in pixels, of the image. If
  // the image is smaller than the values specified, the original image will be
  // returned. If the image is larger in either dimension, it will be scaled to
  // match the smaller of the two dimensions, restricted to its original aspect
  // ratio. Both the max_height_px and max_width_px properties accept an integer
  // between 1 and 4800, inclusively. If the value is not within the allowed
  // range, an INVALID_ARGUMENT error will be returned.
  //
  // At least one of max_height_px or max_width_px needs to be specified. If
  // neither max_height_px nor max_width_px is specified, an INVALID_ARGUMENT
  // error will be returned.
  int32 max_width_px = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specifies the maximum desired height, in pixels, of the image. If
  // the image is smaller than the values specified, the original image will be
  // returned. If the image is larger in either dimension, it will be scaled to
  // match the smaller of the two dimensions, restricted to its original aspect
  // ratio. Both the max_height_px and max_width_px properties accept an integer
  // between 1 and 4800, inclusively. If the value is not within the allowed
  // range, an INVALID_ARGUMENT error will be returned.
  //
  // At least one of max_height_px or max_width_px needs to be specified. If
  // neither max_height_px nor max_width_px is specified, an INVALID_ARGUMENT
  // error will be returned.
  int32 max_height_px = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If set, skip the default HTTP redirect behavior and render a text
  // format (for example, in JSON format for HTTP use case) response. If not
  // set, an HTTP redirect will be issued to redirect the call to the image
  // media. This option is ignored for non-HTTP requests.
  bool skip_http_redirect = 4 [(google.api.field_behavior) = OPTIONAL];
}

// A photo media from Places API.
message PhotoMedia {
  option (google.api.resource) = {
    type: "places.googleapis.com/PhotoMedia"
    pattern: "places/{place_id}/photos/{photo_reference}/media"
    plural: "photoMedias"
    singular: "photoMedia"
  };

  // The resource name of a photo media in the format:
  // `places/{place_id}/photos/{photo_reference}/media`.
  string name = 1;

  // A short-lived uri that can be used to render the photo.
  string photo_uri = 2;
}

// Request for fetching a Place based on its resource name, which is a string in
// the `places/{place_id}` format.
message GetPlaceRequest {
  // Required. The resource name of a place, in the `places/{place_id}` format.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = { type: "places.googleapis.com/Place" }
  ];

  // Optional. Place details will be displayed with the preferred language if
  // available.
  //
  // Current list of supported languages:
  // https://developers.google.com/maps/faq#languagesupport.
  string language_code = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The Unicode country/region code (CLDR) of the location where the
  // request is coming from. This parameter is used to display the place
  // details, like region-specific place name, if available. The parameter can
  // affect results based on applicable law.
  // For more information, see
  // https://www.unicode.org/cldr/charts/latest/supplemental/territory_language_information.html.
  //
  //
  // Note that 3-digit region codes are not currently supported.
  string region_code = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A string which identifies an Autocomplete session for billing
  // purposes. Must be a URL and filename safe base64 string with at most 36
  // ASCII characters in length. Otherwise an INVALID_ARGUMENT error is
  // returned.
  //
  // The session begins when the user starts typing a query, and concludes when
  // they select a place and a call to Place Details or Address Validation is
  // made. Each session can have multiple queries, followed by one Place Details
  // or Address Validation request. The credentials used for each request within
  // a session must belong to the same Google Cloud Console project. Once a
  // session has concluded, the token is no longer valid; your app must generate
  // a fresh token for each session. If the `session_token` parameter is
  // omitted, or if you reuse a session token, the session is charged as if no
  // session token was provided (each request is billed separately).
  //
  // We recommend the following guidelines:
  //
  // * Use session tokens for all Place Autocomplete calls.
  // * Generate a fresh token for each session. Using a version 4 UUID is
  //   recommended.
  // * Ensure that the credentials used for all Place Autocomplete, Place
  //   Details, and Address Validation requests within a session belong to the
  //   same Cloud Console project.
  // * Be sure to pass a unique session token for each new session. Using the
  //   same token for more than one session will result in each request being
  //   billed individually.
  string session_token = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Request proto for AutocompletePlaces.
message AutocompletePlacesRequest {
  // The region to search. The results may be biased around the specified
  // region.
  message LocationBias {
    oneof type {
      // A viewport defined by a northeast and a southwest corner.
      google.geo.type.Viewport rectangle = 1;

      // A circle defined by a center point and radius.
      Circle circle = 2;
    }
  }

  // The region to search. The results will be restricted to the specified
  // region.
  message LocationRestriction {
    oneof type {
      // A viewport defined by a northeast and a southwest corner.
      google.geo.type.Viewport rectangle = 1;

      // A circle defined by a center point and radius.
      Circle circle = 2;
    }
  }

  // Required. The text string on which to search.
  string input = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Bias results to a specified location.
  //
  // At most one of `location_bias` or `location_restriction` should be set. If
  // neither are set, the results will be biased by IP address, meaning the IP
  // address will be mapped to an imprecise location and used as a biasing
  // signal.
  LocationBias location_bias = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Restrict results to a specified location.
  //
  // At most one of `location_bias` or `location_restriction` should be set. If
  // neither are set, the results will be biased by IP address, meaning the IP
  // address will be mapped to an imprecise location and used as a biasing
  // signal.
  LocationRestriction location_restriction = 3
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Included primary Place type (for example, "restaurant" or
  // "gas_station") in Place Types
  // (https://developers.google.com/maps/documentation/places/web-service/place-types),
  // or only `(regions)`, or only `(cities)`. A Place is only returned if its
  // primary type is included in this list. Up to 5 values can be specified. If
  // no types are specified, all Place types are returned.
  repeated string included_primary_types = 4
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Only include results in the specified regions, specified as up to
  // 15 CLDR two-character region codes. An empty set will not restrict the
  // results. If both `location_restriction` and `included_region_codes` are
  // set, the results will be located in the area of intersection.
  repeated string included_region_codes = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. The language in which to return results. Defaults to en-US. The
  // results may be in mixed languages if the language used in `input` is
  // different from `language_code` or if the returned Place does not have a
  // translation from the local language to `language_code`.
  string language_code = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The region code, specified as a CLDR two-character region code.
  // This affects address formatting, result ranking, and may influence what
  // results are returned. This does not restrict results to the specified
  // region. To restrict results to a region, use `region_code_restriction`.
  string region_code = 7 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The origin point from which to calculate geodesic distance to the
  // destination (returned as `distance_meters`). If this value is omitted,
  // geodesic distance will not be returned.
  google.type.LatLng origin = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A zero-based Unicode character offset of `input` indicating the
  // cursor position in `input`. The cursor position may influence what
  // predictions are returned.
  //
  // If empty, defaults to the length of `input`.
  int32 input_offset = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. If true, the response will include both Place and query
  // predictions. Otherwise the response will only return Place predictions.
  bool include_query_predictions = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A string which identifies an Autocomplete session for billing
  // purposes. Must be a URL and filename safe base64 string with at most 36
  // ASCII characters in length. Otherwise an INVALID_ARGUMENT error is
  // returned.
  //
  // The session begins when the user starts typing a query, and concludes when
  // they select a place and a call to Place Details or Address Validation is
  // made. Each session can have multiple queries, followed by one Place Details
  // or Address Validation request. The credentials used for each request within
  // a session must belong to the same Google Cloud Console project. Once a
  // session has concluded, the token is no longer valid; your app must generate
  // a fresh token for each session. If the `session_token` parameter is
  // omitted, or if you reuse a session token, the session is charged as if no
  // session token was provided (each request is billed separately).
  //
  // We recommend the following guidelines:
  //
  // * Use session tokens for all Place Autocomplete calls.
  // * Generate a fresh token for each session. Using a version 4 UUID is
  //   recommended.
  // * Ensure that the credentials used for all Place Autocomplete, Place
  //   Details, and Address Validation requests within a session belong to the
  //   same Cloud Console project.
  // * Be sure to pass a unique session token for each new session. Using the
  //   same token for more than one session will result in each request being
  //   billed individually.
  string session_token = 11 [(google.api.field_behavior) = OPTIONAL];
}

// Response proto for AutocompletePlaces.
message AutocompletePlacesResponse {
  // An Autocomplete suggestion result.
  message Suggestion {
    // Identifies a substring within a given text.
    message StringRange {
      // Zero-based offset of the first Unicode character of the string
      // (inclusive).
      int32 start_offset = 1;

      // Zero-based offset of the last Unicode character (exclusive).
      int32 end_offset = 2;
    }

    // Text representing a Place or query prediction. The text may be used as is
    // or formatted.
    message FormattableText {
      // Text that may be used as is or formatted with `matches`.
      string text = 1;

      // A list of string ranges identifying where the input request matched in
      // `text`. The ranges can be used to format specific parts of `text`. The
      // substrings may not be exact matches of `input` if the matching was
      // determined by criteria other than string matching (for example, spell
      // corrections or transliterations).
      //
      // These values are Unicode character offsets of `text`. The ranges are
      // guaranteed to be ordered in increasing offset values.
      repeated StringRange matches = 2;
    }

    // Contains a breakdown of a Place or query prediction into main text
    // and secondary text.
    //
    // For Place predictions, the main text contains the specific name of the
    // Place. For query predictions, the main text contains the query.
    //
    // The secondary text contains additional disambiguating features (such as a
    // city or region) to further identify the Place or refine the query.
    message StructuredFormat {
      // Represents the name of the Place or query.
      FormattableText main_text = 1;

      // Represents additional disambiguating features (such as a city or
      // region) to further identify the Place or refine the query.
      FormattableText secondary_text = 2;
    }

    // Prediction results for a Place Autocomplete prediction.
    message PlacePrediction {
      // The resource name of the suggested Place. This name can be used in
      // other APIs that accept Place names.
      string place = 1 [(google.api.resource_reference) = {
        type: "places.googleapis.com/Place"
      }];

      // The unique identifier of the suggested Place. This identifier can be
      // used in other APIs that accept Place IDs.
      string place_id = 2;

      // Contains the human-readable name for the returned result. For
      // establishment results, this is usually the business name and address.
      //
      // `text` is recommended for developers who wish to show a single UI
      // element. Developers who wish to show two separate, but related, UI
      // elements may want to use `structured_format` instead. They are two
      // different ways to represent a Place prediction. Users should not try to
      // parse `structured_format` into `text` or vice versa.
      //
      // This text may be different from the `display_name` returned by
      // GetPlace.
      //
      // May be in mixed languages if the request `input` and `language_code`
      // are in different languages or if the Place does not have a translation
      // from the local language to `language_code`.
      FormattableText text = 3;

      // A breakdown of the Place prediction into main text containing the name
      // of the Place and secondary text containing additional disambiguating
      // features (such as a city or region).
      //
      // `structured_format` is recommended for developers who wish to show two
      // separate, but related, UI elements. Developers who wish to show a
      // single UI element may want to use `text` instead. They are two
      // different ways to represent a Place prediction. Users should not try to
      // parse `structured_format` into `text` or vice versa.
      StructuredFormat structured_format = 4;

      // List of types that apply to this Place from Table A or Table B in
      // https://developers.google.com/maps/documentation/places/web-service/place-types.
      //
      // A type is a categorization of a Place. Places with shared types will
      // share similar characteristics.
      repeated string types = 5;

      // The length of the geodesic in meters from `origin` if `origin` is
      // specified. Certain predictions such as routes may not populate this
      // field.
      int32 distance_meters = 6;
    }

    // Prediction results for a Query Autocomplete prediction.
    message QueryPrediction {
      // The predicted text. This text does not represent a Place, but rather a
      // text query that could be used in a search endpoint (for example,
      // Text Search).
      //
      // `text` is recommended for developers who wish to show a single UI
      // element. Developers who wish to show two separate, but related, UI
      // elements may want to use `structured_format` instead. They are two
      // different ways to represent a query prediction. Users should not try to
      // parse `structured_format` into `text` or vice versa.
      //
      // May be in mixed languages if the request `input` and `language_code`
      // are in different languages or if part of the query does not have a
      // translation from the local language to `language_code`.
      FormattableText text = 1;

      // A breakdown of the query prediction into main text containing the query
      // and secondary text containing additional disambiguating features (such
      // as a city or region).
      //
      // `structured_format` is recommended for developers who wish to show two
      // separate, but related, UI elements. Developers who wish to show a
      // single UI element may want to use `text` instead. They are two
      // different ways to represent a query prediction. Users should not try to
      // parse `structured_format` into `text` or vice versa.
      StructuredFormat structured_format = 2;
    }

    oneof kind {
      // A prediction for a Place.
      PlacePrediction place_prediction = 1;

      // A prediction for a query.
      QueryPrediction query_prediction = 2;
    }
  }

  // Contains a list of suggestions, ordered in descending order of relevance.
  repeated Suggestion suggestions = 1;
}
