// 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.maps.geocode.v4;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/struct.proto";
import "google/type/latlng.proto";
import "google/type/localized_text.proto";
import "google/type/postal_address.proto";

option csharp_namespace = "Google.Maps.Geocode.V4";
option go_package = "cloud.google.com/go/maps/geocode/apiv4/geocodepb;geocodepb";
option java_multiple_files = true;
option java_outer_classname = "DestinationServiceProto";
option java_package = "com.google.maps.geocode.v4";
option objc_class_prefix = "GMPG";
option php_namespace = "Google\\Maps\\Geocode\\V4";
option ruby_package = "Google::Maps::Geocode::V4";

// A service for retrieving destinations.
//
// A destination provides hierarchical context about a place, which
// allows you to, for example, find apartment buildings within a larger
// apartment complex and vice versa. It also provides navigation points suitable
// for use cases such as ridesharing or delivery.
service DestinationService {
  option (google.api.default_host) = "geocoding-backend.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform,"
      "https://www.googleapis.com/auth/maps-platform.destinations,"
      "https://www.googleapis.com/auth/maps-platform.geocode";

  // This method performs a destination lookup and returns a list of
  // destinations.
  rpc SearchDestinations(SearchDestinationsRequest)
      returns (SearchDestinationsResponse) {
    option (google.api.http) = {
      post: "/v4/geocode/destinations"
      body: "*"
    };
  }
}

// Request message for DestinationService.SearchDestinations.
message SearchDestinationsRequest {
  // The street address that you want to search for. Specify addresses in
  // accordance with the format used by the national postal service of the
  // country concerned.
  message AddressQuery {
    // The address query.
    oneof kind {
      // A street address in postal address format.
      google.type.PostalAddress address = 1;

      // A street address formatted as a single line.
      string address_query = 2;
    }
  }

  // A location query to identify a nearby primary destination.
  //
  // Note: if the location query is within a building that contains subpremises,
  // it is possible that the returned primary place is a subpremise. In these
  // cases, the `containing_places` field will include the building.
  message LocationQuery {
    // Filters to apply to destination candidates.
    message PlaceFilter {
      // Defines options for addressability filtering. New values may be added
      // in the future.
      enum Addressability {
        // When unspecified, the service will choose a sensible default.
        ADDRESSABILITY_UNSPECIFIED = 0;

        // Addressability is not a filtering criteria. Destinations are returned
        // regardless of their addressability.
        ANY = 1;

        // All destinations returned will have a primary place with a street
        // level address or name.
        PRIMARY = 2;

        // All destinations returned will have either a primary place or a
        // subdestination with a street level address or name.
        WEAK = 3;
      }

      // Optional. If specified, all destinations are guaranteed to have a
      // primary place with this structure type. This can result in filtering
      // out some destinations, or in coarsening/refining the returned
      // destinations.
      //
      // For example, if `GROUNDS` is specified, all returned destinations will
      // have a primary place with the `GROUNDS` structure type. This can
      // result in filtering out some destinations that are not part of a
      // grounds, or in coarsening the returned destinations to the grounds
      // level.
      //
      // Another use of this field is to more easily extract building display
      // polygons. For example, if `BUILDING` is specified, the primary place's
      // display polygon will be for the building at the specified location.
      PlaceView.StructureType structure_type = 2
          [(google.api.field_behavior) = OPTIONAL];

      // Optional. If specified, only returns destinations that meet the
      // corresponding addressability criteria.
      Addressability addressability = 3
          [(google.api.field_behavior) = OPTIONAL];
    }

    // The location query.
    oneof kind {
      // A precise LatLng location.
      google.type.LatLng location = 1;
    }

    // Optional. Filters to apply to destination candidates.
    PlaceFilter place_filter = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  // Query for the primary destination. This can be either a place, a fully
  // specified address, or a LatLng location. Some places and addresses with
  // minimal information won't be able to be turned into a destination.
  //
  // The destinations are built around the specified primary query.
  //
  // Note: only places and addresses that can have a navigational destination
  // are supported. For example, a place that represents a house or an apartment
  // complex can be used as the primary query, but places that represent a
  // locality or an administrative area cannot be used as the primary query.
  oneof primary_query {
    // The resource name of a place, in `places/{place_id}` format.
    string place = 1;

    // A street address.
    AddressQuery address_query = 2;

    // A precise location.
    LocationQuery location_query = 3;
  }

  // Optional. The travel modes to filter navigation points for. This influences
  // the `navigation_points` field returned in the response. If empty,
  // navigation points of all travel modes are returned.
  repeated NavigationPoint.TravelMode travel_modes = 5
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Language in which the results should be returned.
  string language_code = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Region code. The region code, specified as a ccTLD ("top-level
  // domain") two-character value. The parameter affects results based on
  // applicable law. This parameter also influences, but not fully restricts,
  // results from the service.
  string region_code = 7 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for DestinationService.SearchDestinations.
message SearchDestinationsResponse {
  // A list of destinations.
  //
  // The service returns one result if a primary destination can be
  // unambiguously identified from the primary query. Otherwise, the service
  // might return multiple results for disambiguation or zero results.
  repeated Destination destinations = 1;
}

// A destination. This includes the primary place, related places,
// entrances, and navigation points.
message Destination {
  // The primary place identified by the `primary_query` in the request.
  PlaceView primary = 1;

  // The less precise places that the primary place is contained by.
  // For example, the apartment complex that contains this building.
  repeated PlaceView containing_places = 2;

  // More precise sub-destinations of the primary place. For example, units
  // contained in a building.
  //
  // Note: compared to the
  // [SubDestination](/maps/documentation/places/web-service/reference/rest/v1/places#SubDestination)
  // returned by the Places API, this list of sub-destinations is more
  // exhaustive, and each sub-destination contains more information.
  repeated PlaceView sub_destinations = 3;

  // Landmarks that can be used to communicate where the destination is
  // or help with arrival.
  repeated Landmark landmarks = 4;

  // Entrances for this destination.
  repeated Entrance entrances = 5;

  // Navigation points for this destination.
  repeated NavigationPoint navigation_points = 6;
}

// Represents a view of a
// [Place](https://developers.google.com/maps/documentation/places/web-service/reference/rest/v1/places#resource:-place)
// in the Places API. It also provides additional information specific to
// destinations, such as the structure type and the display polygon.
//
// In some cases, a `PlaceView` with the same place ID might differ from what
// is being returned by the Places API for the `types` and
// `display_name` fields.
message PlaceView {
  // The type of structure that this place represents.
  enum StructureType {
    // Not used.
    STRUCTURE_TYPE_UNSPECIFIED = 0;

    // A point location.
    POINT = 1;

    // A sub-section of a building.
    SECTION = 2;

    // A building.
    BUILDING = 3;

    // A large area that typically contains multiple buildings, such as a
    // university campus, an apartment complex, or a shopping mall.
    GROUNDS = 4;
  }

  // This Place's resource name, in `places/{placeId}` format.  Can be used to
  // look up the Place.
  string place = 1;

  // The unique identifier of a place.
  string place_id = 2;

  // Human readable place description. For example, "Gate B", "McDonalds"
  google.type.LocalizedText display_name = 3;

  // The primary place type of this place. See
  // https://developers.google.com/maps/documentation/places/web-service/place-types
  // for the list of possible values.
  //
  // Note: This field is not always populated. Be prepared to use the `types`
  // field in such situations.
  string primary_type = 4;

  // All associated place types of this place. See
  // https://developers.google.com/maps/documentation/places/web-service/place-types
  // for the list of possible values.
  repeated string types = 5;

  // One line address.
  string formatted_address = 6;

  // Structured address.
  google.type.PostalAddress postal_address = 7;

  // The type of structure corresponding to this place.
  StructureType structure_type = 8;

  // The location of this place. For places with display polygons, this can
  // represent a good spot to put a marker on the map.
  google.type.LatLng location = 9;

  // The polygon outline of the place in GeoJSON format, using the RFC 7946
  // format: https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.6.
  //
  // Note: The RFC 7946 format supports MultiPolygons, so one `display_polygon`
  // object can represent multiple polygons.
  google.protobuf.Struct display_polygon = 10;
}

// An entrance is a single latitude/longitude coordinate pair that defines the
// location of an entry and exit point for a place.
message Entrance {
  // Characteristics that describe an entrance.
  enum Tag {
    // Not used.
    TAG_UNSPECIFIED = 0;

    // The entrance likely provides physical access to the primary place in
    // the returned destination. A place can have multiple preferred entrances.
    // If an entrance does not have this tag, it means the entrance is
    // physically on the same building as the primary place, but does not
    // necessarily provide access to the place.
    //
    // For example, if the primary place is a restaurant in a strip mall, the
    // "PREFERRED" entrances will be the ones that likely lead into the
    // restaurant itself, while the other returned entrances will be other
    // entrances for the building, such as entrances into other restaurants in
    // the strip mall.
    //
    // If the primary place is a building itself, the `PREFERRED` entrances
    // will be the ones that lead into the "main" part of the building. For
    // example, in a shopping center the `PREFERRED` entrances will be the ones
    // that allow access to the main foyer area, but if an entrance only
    // provides access to a store on the side of the building, it won't be a
    // `PREFERRED` entrance.
    //
    // Note: a `PREFERRED` entrance might not provide access to the primary
    // place, and a non-`PREFERRED` entrance might provide access to the
    // primary place.
    PREFERRED = 1;
  }

  // The location of the entrance.
  google.type.LatLng location = 2;

  // A list of tags that describe the entrance.
  repeated Tag tags = 3;

  // The structure this entrance is physically located on, in
  // `places/{place_id}` format.
  string place = 4;
}

// A navigation point is a location next to a road where navigation can end.
message NavigationPoint {
  // Travel modes that are appropriate for this navigation point.
  enum TravelMode {
    // Not used.
    TRAVEL_MODE_UNSPECIFIED = 0;

    // Suitable for driving.
    DRIVE = 1;

    // Suitable for walking.
    WALK = 2;
  }

  // Usages supported by this navigation point.
  // New values may be added in the future.
  enum Usage {
    // Not used.
    USAGE_UNSPECIFIED = 0;

    // Indicates that the usage type is unknown.
    UNKNOWN = 1;

    // Suitable for dropping off a passenger. For example, a rideshare drop off
    // location.
    DROPOFF = 2;

    // Suitable for picking up a passenger. For example, a rideshare pick up
    // location.
    PICKUP = 3;

    // Suitable for parking. For example, within a parking lot.
    PARKING = 4;
  }

  // Output only. A token that can be used to identify this navigation point.
  string navigation_point_token = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The display name of this navigation point. For example, "5th Ave" or "Gate
  // B".
  google.type.LocalizedText display_name = 2;

  // A point next to the road segment where navigation should end. The point is
  // intentionally slightly offset from the road's centerline to clearly mark
  // the side of the road where the place is located.
  google.type.LatLng location = 3;

  // Travel modes that are appropriate for this navigation point.
  repeated TravelMode travel_modes = 4;

  // Lists `usages` supported by this navigation point. If empty, it does not
  // necessarily mean its usage is restricted in any way. All navigation
  // points can be used for general navigation.
  repeated Usage usages = 5;
}

// Landmarks are used to communicate where the destination is or help with
// arriving at the destination.
message Landmark {
  // The list of all possible tags that describe how a landmark can be used in
  // the context of a destination.
  //
  // If an address has both the `ADDRESS` and `ARRIVAL` tags, it means the
  // landmark is both locally prominent and close to the destination.
  enum Tag {
    // Not used.
    TAG_UNSPECIFIED = 0;

    // A locally prominent place that can be used to identify the general
    // location of the destination. Typically within a few hundred meters of the
    // destination. These are similar to the landmarks returned by the
    // Address Descriptors feature of the Geocoding API:
    // https://developers.google.com/maps/documentation/geocoding/address-descriptors/requests-address-descriptors.
    ADDRESS = 1;

    // A place that can be used to help arrive at the destination. Useful for
    // navigation once you are close to the destination. For example, this
    // landmark might be a place that is across the street from the destination.
    // A landmark with this tag is typically closer to the destination than
    // landmarks with the `ADDRESS` tag.
    ARRIVAL = 2;
  }

  // The landmark.
  oneof landmark {
    // The place that represents this landmark.
    PlaceView place = 1;
  }

  // A human-readable description of how the destination relates to the
  // landmark. For example: "Near the Empire State Building" or "Across from
  // the White House".
  google.type.LocalizedText relational_description = 2;

  // Tags that describe how the landmark can be used in the context of the
  // destination.
  repeated Tag tags = 3;

  // Output only. The straight-line distance from this landmark to the
  // destination in meters.
  double straight_line_distance_meters = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The road-network distance from this landmark to the
  // destination in meters.
  double travel_distance_meters = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
}
