def get_pids_in_revision_chain(client, did):
    """Args: client: d1_client.cnclient.CoordinatingNodeClient or
    d1_client.mnclient.MemberNodeClient.

      did : str
        SID or a PID of any object in a revision chain.

    Returns:
      list of str:
        All PIDs in the chain. The returned list is in the same order as the chain. The
        initial PID is typically obtained by resolving a SID. If the given PID is not in
        a chain, a list containing the single object is returned.

    """

    def _req(p):
        return d1_common.xml.get_req_val(p)

    def _opt(p, a):
        return d1_common.xml.get_opt_val(p, a)

    sysmeta_pyxb = client.getSystemMetadata(did)
    # Walk to tail
    while _opt(sysmeta_pyxb, 'obsoletes'):
        sysmeta_pyxb = client.getSystemMetadata(_opt(sysmeta_pyxb, 'obsoletes'))
    chain_pid_list = [_req(sysmeta_pyxb.identifier)]
    # Walk from tail to head, recording traversed PIDs
    while _opt(sysmeta_pyxb, 'obsoletedBy'):
        sysmeta_pyxb = client.getSystemMetadata(_opt(sysmeta_pyxb, 'obsoletedBy'))
        chain_pid_list.append(_req(sysmeta_pyxb.identifier))
    return chain_pid_list