Given a protobuf for a Value, get the correct value.

    The Cloud Datastore Protobuf API returns a Property Protobuf which
    has one value set and the rest blank.  This function retrieves the
    the one value provided.

    Some work is done to coerce the return value into a more useful type
    (particularly in the case of a timestamp value, or a key value).

    :type value_pb: :class:`.entity_pb2.Value`
    :param value_pb: The Value Protobuf.

    :rtype: object
    :returns: The value provided by the Protobuf.
    :raises: :class:`ValueError <exceptions.ValueError>` if no value type
             has been set.

def _get_value_from_value_pb(value_pb):
    """Given a protobuf for a Value, get the correct value.

    The Cloud Datastore Protobuf API returns a Property Protobuf which
    has one value set and the rest blank.  This function retrieves the
    the one value provided.

    Some work is done to coerce the return value into a more useful type
    (particularly in the case of a timestamp value, or a key value).

    :type value_pb: :class:`.entity_pb2.Value`
    :param value_pb: The Value Protobuf.

    :rtype: object
    :returns: The value provided by the Protobuf.
    :raises: :class:`ValueError <exceptions.ValueError>` if no value type
             has been set.
    """
    value_type = value_pb.WhichOneof("value_type")

    if value_type == "timestamp_value":
        result = _pb_timestamp_to_datetime(value_pb.timestamp_value)

    elif value_type == "key_value":
        result = key_from_protobuf(value_pb.key_value)

    elif value_type == "boolean_value":
        result = value_pb.boolean_value

    elif value_type == "double_value":
        result = value_pb.double_value

    elif value_type == "integer_value":
        result = value_pb.integer_value

    elif value_type == "string_value":
        result = value_pb.string_value

    elif value_type == "blob_value":
        result = value_pb.blob_value

    elif value_type == "entity_value":
        result = entity_from_protobuf(value_pb.entity_value)

    elif value_type == "array_value":
        result = [
            _get_value_from_value_pb(value) for value in value_pb.array_value.values
        ]

    elif value_type == "geo_point_value":
        result = GeoPoint(
            value_pb.geo_point_value.latitude, value_pb.geo_point_value.longitude
        )

    elif value_type == "null_value":
        result = None

    else:
        raise ValueError("Value protobuf did not have any value set")

    return result