def qubit_from_proto_id(proto_id: str) -> cirq.Qid:
    """Return a `cirq.Qid` for a proto id.

    Proto IDs of the form {int}_{int} are parsed as GridQubits.

    Proto IDs of the form {int} are parsed as LineQubits.

    Proto IDs of the form c_{int}_{int} are parsed as Couplers
    between two LineQubits.

    Proto IDs of the form c_{int}_{int}_{int}_{int} are parsed as Couplers
    between two GridQubit.

    Proto IDs of the form c_{name}_{name} are parsed as Couplers
    between two NamedQubits.

    All other proto IDs are parsed as NamedQubits. Note that this will happily
    accept any string; for circuits which explicitly use Grid or LineQubits,
    prefer one of the specialized methods below.

    Args:
        proto_id: The id to convert.

    Returns:
        A `cirq.Qid` corresponding to the proto id.
    """
    qubit_field = proto_id.split('_')
    num_coords = len(qubit_field)
    if proto_id[:2] == 'c_':
        if num_coords == 5:
            # 2 grid qubits: c_2_1_4_3
            grid_qubit0_str = qubit_field[1] + '_' + qubit_field[2]
            grid_qubit1_str = qubit_field[3] + '_' + qubit_field[4]
            try:
                grid_qubit0 = grid_qubit_from_proto_id(grid_qubit0_str)
                grid_qubit1 = grid_qubit_from_proto_id(grid_qubit1_str)
                return Coupler(grid_qubit0, grid_qubit1)
            except ValueError:
                pass  # Not valid grid qubits.
        elif num_coords == 3:
            # 2 line qubits: c_2_4
            # Or two named qubits: c_qubita_qubitb
            line_qubit0 = qubit_from_proto_id(qubit_field[1])
            line_qubit1 = qubit_from_proto_id(qubit_field[2])
            return Coupler(line_qubit0, line_qubit1)
    elif num_coords == 2:
        try:
            grid_q = grid_qubit_from_proto_id(proto_id)
            return grid_q
        except ValueError:
            pass  # Not a grid qubit.
    elif num_coords == 1:
        try:
            line_q = line_qubit_from_proto_id(proto_id)
            return line_q
        except ValueError:
            pass  # Not a line qubit.

    # named_qubit_from_proto has no failure condition.
    named_q = named_qubit_from_proto_id(proto_id)
    return named_q
Return a `cirq.Qid` for a proto id.

    Proto IDs of the form {int}_{int} are parsed as GridQubits.

    Proto IDs of the form {int} are parsed as LineQubits.

    Proto IDs of the form c_{int}_{int} are parsed as Couplers
    between two LineQubits.

    Proto IDs of the form c_{int}_{int}_{int}_{int} are parsed as Couplers
    between two GridQubit.

    Proto IDs of the form c_{name}_{name} are parsed as Couplers
    between two NamedQubits.

    All other proto IDs are parsed as NamedQubits. Note that this will happily
    accept any string; for circuits which explicitly use Grid or LineQubits,
    prefer one of the specialized methods below.

    Args:
        proto_id: The id to convert.

    Returns:
        A `cirq.Qid` corresponding to the proto id.
    
cirq-google/cirq_google/api/v2/program.py