Retrieve the given key off of the object.

    If a default is specified, return it if the key is not found, otherwise
    raise KeyError.

    Args:
        pb_or_dict (Union[~google.protobuf.message.Message, Mapping]): the
            object.
        key (str): The key to retrieve from the object in question.
        default (Any): If the key is not present on the object, and a default
            is set, returns that default instead. A type-appropriate falsy
            default is generally recommended, as protobuf messages almost
            always have default values for unset values and it is not always
            possible to tell the difference between a falsy value and an
            unset one. If no default is set, raises KeyError for not found
            values.

    Returns:
        Any: The return value from the underlying message or dict.

    Raises:
        KeyError: If the key is not found. Note that, for unset values,
            messages and dictionaries may not have consistent behavior.
        TypeError: If pb_or_dict is not a Message or Mapping.

def get(pb_or_dict, key, default=_SENTINEL):
    """Retrieve the given key off of the object.

    If a default is specified, return it if the key is not found, otherwise
    raise KeyError.

    Args:
        pb_or_dict (Union[~google.protobuf.message.Message, Mapping]): the
            object.
        key (str): The key to retrieve from the object in question.
        default (Any): If the key is not present on the object, and a default
            is set, returns that default instead. A type-appropriate falsy
            default is generally recommended, as protobuf messages almost
            always have default values for unset values and it is not always
            possible to tell the difference between a falsy value and an
            unset one. If no default is set, raises KeyError for not found
            values.

    Returns:
        Any: The return value from the underlying message or dict.

    Raises:
        KeyError: If the key is not found. Note that, for unset values,
            messages and dictionaries may not have consistent behavior.
        TypeError: If pb_or_dict is not a Message or Mapping.
    """
    # We may need to get a nested key. Resolve this.
    key, subkey = _resolve_subkeys(key)

    # Attempt to get the value from the two types of objects we know baout.
    # If we get something else, complain.
    if isinstance(pb_or_dict, Message):
        answer = getattr(pb_or_dict, key, default)
    elif isinstance(pb_or_dict, collections.Mapping):
        answer = pb_or_dict.get(key, default)
    else:
        raise TypeError('Tried to fetch a key %s on an invalid object; '
                        'expected a dict or protobuf message.')

    # If the object we got back is our sentinel, raise KeyError; this is
    # a "not found" case.
    if answer is _SENTINEL:
        raise KeyError(key)

    # If a subkey exists, call this method recursively against the answer.
    if subkey and answer is not default:
        return get(answer, subkey, default=default)

    # Return the value.
    return answer