Return a location point by address.

        :param str query: The address or query you wish to geocode. Optional,
            if ``components`` param is set::

                >>> g.geocode(components={"city": "Paris", "country": "FR"})
                Location(France, (46.227638, 2.213749, 0.0))

            .. versionchanged:: 1.14.0
               Now ``query`` is optional if ``components`` param is set.

        :param bool exactly_one: Return one result or a list of results, if
            available.

        :param int timeout: Time, in seconds, to wait for the geocoding service
            to respond before raising a :class:`geopy.exc.GeocoderTimedOut`
            exception. Set this only if you wish to override, on this call
            only, the value set during the geocoder's initialization.

        :type bounds: list or tuple of 2 items of :class:`geopy.point.Point` or
            ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``.
        :param bounds: The bounding box of the viewport within which
            to bias geocode results more prominently.
            Example: ``[Point(22, 180), Point(-22, -180)]``.

            .. versionchanged:: 1.17.0
                Previously the only supported format for bounds was a
                list like ``[latitude, longitude, latitude, longitude]``.
                This format is now deprecated in favor of a list/tuple
                of a pair of geopy Points and will be removed in geopy 2.0.

        :param str region: The region code, specified as a ccTLD
            ("top-level domain") two-character value.

        :param dict components: Restricts to an area. Can use any combination
            of: route, locality, administrative_area, postal_code, country.

        :param str place_id: Retrieve a Location using a Place ID.
            Cannot be not used with ``query`` or ``bounds`` parameters.

                >>> g.geocode(place_id='ChIJOcfP0Iq2j4ARDrXUa7ZWs34')

            .. versionadded:: 1.19.0

        :param str language: The language in which to return results.

        :param bool sensor: Whether the geocoding request comes from a
            device with a location sensor.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.

def geocode(
            self,
            query=None,
            exactly_one=True,
            timeout=DEFAULT_SENTINEL,
            bounds=None,
            region=None,
            components=None,
            place_id=None,
            language=None,
            sensor=False,
    ):
        """
        Return a location point by address.

        :param str query: The address or query you wish to geocode. Optional,
            if ``components`` param is set::

                >>> g.geocode(components={"city": "Paris", "country": "FR"})
                Location(France, (46.227638, 2.213749, 0.0))

            .. versionchanged:: 1.14.0
               Now ``query`` is optional if ``components`` param is set.

        :param bool exactly_one: Return one result or a list of results, if
            available.

        :param int timeout: Time, in seconds, to wait for the geocoding service
            to respond before raising a :class:`geopy.exc.GeocoderTimedOut`
            exception. Set this only if you wish to override, on this call
            only, the value set during the geocoder's initialization.

        :type bounds: list or tuple of 2 items of :class:`geopy.point.Point` or
            ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``.
        :param bounds: The bounding box of the viewport within which
            to bias geocode results more prominently.
            Example: ``[Point(22, 180), Point(-22, -180)]``.

            .. versionchanged:: 1.17.0
                Previously the only supported format for bounds was a
                list like ``[latitude, longitude, latitude, longitude]``.
                This format is now deprecated in favor of a list/tuple
                of a pair of geopy Points and will be removed in geopy 2.0.

        :param str region: The region code, specified as a ccTLD
            ("top-level domain") two-character value.

        :param dict components: Restricts to an area. Can use any combination
            of: route, locality, administrative_area, postal_code, country.

        :param str place_id: Retrieve a Location using a Place ID.
            Cannot be not used with ``query`` or ``bounds`` parameters.

                >>> g.geocode(place_id='ChIJOcfP0Iq2j4ARDrXUa7ZWs34')

            .. versionadded:: 1.19.0

        :param str language: The language in which to return results.

        :param bool sensor: Whether the geocoding request comes from a
            device with a location sensor.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.
        """
        params = {
            'sensor': str(sensor).lower()
        }
        if place_id and (bounds or query):
            raise ValueError(
                'Only one of the `query` or `place id` or `bounds` '
                ' parameters must be entered.')

        if place_id is not None:
            params['place_id'] = place_id

        if query is not None:
            params['address'] = self.format_string % query

        if query is None and place_id is None and not components:
            raise ValueError('Either `query` or `components` or `place_id` '
                             'must be set.')

        if self.api_key:
            params['key'] = self.api_key
        if bounds:
            if len(bounds) == 4:
                warnings.warn(
                    'GoogleV3 `bounds` format of '
                    '`[latitude, longitude, latitude, longitude]` is now '
                    'deprecated and will not be supported in geopy 2.0. '
                    'Use `[Point(latitude, longitude), Point(latitude, longitude)]` '
                    'instead.',
                    DeprecationWarning,
                    stacklevel=2
                )
                lat1, lon1, lat2, lon2 = bounds
                bounds = [[lat1, lon1], [lat2, lon2]]
            params['bounds'] = self._format_bounding_box(
                bounds, "%(lat1)s,%(lon1)s|%(lat2)s,%(lon2)s")
        if region:
            params['region'] = region
        if components:
            params['components'] = self._format_components_param(components)
        if language:
            params['language'] = language

        if self.premier:
            url = self._get_signed_url(params)
        else:
            url = "?".join((self.api, urlencode(params)))

        logger.debug("%s.geocode: %s", self.__class__.__name__, url)
        return self._parse_json(
            self._call_geocoder(url, timeout=timeout), exactly_one
        )