// 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/geo/type/viewport.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 = "GeocodeServiceProto";
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 performing geocoding.
service GeocodeService {
  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.geocode,"
      "https://www.googleapis.com/auth/maps-platform.geocode.address,"
      "https://www.googleapis.com/auth/maps-platform.geocode.location,"
      "https://www.googleapis.com/auth/maps-platform.geocode.place";

  // This method performs an address geocode, which maps an address to a
  // LatLng. It also provides structured information about the address.
  rpc GeocodeAddress(GeocodeAddressRequest) returns (GeocodeAddressResponse) {
    option (google.api.http) = {
      get: "/v4/geocode/address"
      additional_bindings { get: "/v4/geocode/address/{address_query}" }
    };
  }

  // This method performs a location geocode, which maps a LatLng to an
  // address. It also provides structured information about the address.
  rpc GeocodeLocation(GeocodeLocationRequest)
      returns (GeocodeLocationResponse) {
    option (google.api.http) = {
      get: "/v4/geocode/location"
      additional_bindings { get: "/v4/geocode/location/{location_query}" }
    };
  }

  // This method performs a geocode lookup using a place ID.
  rpc GeocodePlace(GeocodePlaceRequest) returns (GeocodeResult) {
    option (google.api.http) = {
      get: "/v4/geocode/{place=places/*}"
    };
  }
}

// Request message for GeocodeService.GeocodeAddress.
message GeocodeAddressRequest {
  // The region to search. This location serves as a bias which means results
  // around the given location are preferred.
  message LocationBias {
    // Types of location bias.
    oneof type {
      // A rectangular 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;
    }
  }

  // The address to geocode.
  oneof address_input {
    // The unstructured address to geocode.
    string address_query = 1;

    // The structured address to geocode in postal address format.
    google.type.PostalAddress address = 2;
  }

  // Optional. The region to search. This location serves as a bias which means
  // results around the given location are preferred.
  LocationBias location_bias = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Language in which the results should be returned.
  string language_code = 4 [(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 will also influence, but not fully restrict,
  // results from the service.
  string region_code = 5 [(google.api.field_behavior) = OPTIONAL];
}

// Request message for GeocodeService.GeocodeLocation.
message GeocodeLocationRequest {
  // The location to geocode.
  oneof location_input {
    // The location in the format of "lat,lng" string. For example,
    // "64.7611872,-18.4705364".
    string location_query = 1;

    // The location in the structured format.
    google.type.LatLng location = 2;
  }

  // Optional. Language in which the results should be returned.
  string language_code = 3 [(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.
  string region_code = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A set of type tags to restrict the results. Results that do not
  // have any of the specified types are removed.
  //
  // For the complete list of possible values, see Table A and Table B at
  // https://developers.google.com/maps/documentation/places/web-service/place-types.
  repeated string types = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A filter of one or more location granularity enums.
  repeated GeocodeResult.Granularity granularity = 6
      [(google.api.field_behavior) = OPTIONAL];
}

// Request message for GeocodeService.GeocodePlace.
message GeocodePlaceRequest {
  // Required. Place identifier to geocode in the format of places/{place}.
  string place = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. Language in which the results should be returned.
  string language_code = 2 [(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.
  string region_code = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Plus code (http://plus.codes) is a location reference with two formats:
// global code defining a 14mx14m (1/8000th of a degree) or smaller rectangle,
// and compound code, replacing the prefix with a reference location.
message PlusCode {
  // Place's global (full) code, such as "9FWM33GV+HQ", representing an
  // 1/8000 by 1/8000 degree area (~14 by 14 meters).
  string global_code = 1;

  // Place's compound code, such as "33GV+HQ, Ramberg, Norway", containing
  // the suffix of the global code and replacing the prefix with a formatted
  // name of a reference entity.
  string compound_code = 2;
}

// A geocode result contains geographic information about a place.
message GeocodeResult {
  // The structured components that form the formatted address, if this
  // information is available.
  message AddressComponent {
    // The full text description or name of the address component. For example,
    // an address component for the country Australia may have a long name of
    // "Australia".
    string long_text = 1;

    // An abbreviated textual name for the address component, if available. For
    // example, an address component for the country of Australia may have a
    // short name of "AU".
    string short_text = 2;

    // An array indicating the type(s) of the address component.
    //
    // See
    // https://developers.google.com/maps/documentation/geocoding/requests-geocoding#Types
    // for more details.
    repeated string types = 3;

    // The language used to format this component, in CLDR notation.
    string language_code = 4;
  }

  // The granularity of the location.
  enum Granularity {
    // Do not use.
    GRANULARITY_UNSPECIFIED = 0;

    // The non-interpolated location of an actual plot of land corresponding
    // to the matched address.
    ROOFTOP = 1;

    // Interpolated from a range of street numbers. For example, if we know
    // that a segment of Amphitheatre Pkwy contains numbers 1600 - 1699, then
    // 1650 might be placed halfway between its endpoints.
    RANGE_INTERPOLATED = 2;

    // The geometric center of a feature for which we have polygonal data.
    GEOMETRIC_CENTER = 3;

    // Everything else.
    APPROXIMATE = 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;

  // The latlng of this address.
  google.type.LatLng location = 3;

  // The granularity of the location.
  Granularity granularity = 4;

  // A viewport suitable for displaying the geocode result.
  google.geo.type.Viewport viewport = 5;

  // A bounding box for the address.
  google.geo.type.Viewport bounds = 6;

  // The one line formatted address.
  string formatted_address = 7;

  // The address in postal address format.
  google.type.PostalAddress postal_address = 8;

  // Repeated components for each locality level.
  repeated AddressComponent address_components = 9;

  // Complete list of localities contained in the postal code.
  //
  // This is only populated when the result is of type "postal_code".
  repeated google.type.LocalizedText postal_code_localities = 11;

  // A set of type tags for this result. For
  // example, "political" and "administrative_area".
  //
  // For the complete list of possible values, see Table A and Table B at
  // https://developers.google.com/maps/documentation/places/web-service/place-types.
  repeated string types = 12;

  // Plus code of the location in this geocode.
  PlusCode plus_code = 13;
}

// Response message for
// [GeocodeService.GeocodeAddress][google.maps.geocode.v4.GeocodeService.GeocodeAddress].
message GeocodeAddressResponse {
  // The geocoding result.
  repeated GeocodeResult results = 1;
}

// Response message for
// [GeocodeService.GeocodeLocation][google.maps.geocode.v4.GeocodeService.GeocodeLocation].
message GeocodeLocationResponse {
  // The geocoding result.
  repeated GeocodeResult results = 1;

  // Plus code of the location in the request.
  PlusCode plus_code = 2;
}
