def _validate_device_specification(proto: v2.device_pb2.DeviceSpecification) -> None:
    """Raises a ValueError if the `DeviceSpecification` proto is invalid."""

    qubit_set = set()
    for q_name in proto.valid_qubits:
        # Qubit names must be unique.
        if q_name in qubit_set:
            raise ValueError(
                f"Invalid DeviceSpecification: valid_qubits contains duplicate qubit '{q_name}'."
            )
        # Qubit names must be in the form <int>_<int> to be parsed as cirq.GridQubits.
        if re.match(r'^[0-9]+\_[0-9]+$', q_name) is None:
            raise ValueError(
                f"Invalid DeviceSpecification: valid_qubits contains the qubit '{q_name}' which is"
                " not in the GridQubit form '<int>_<int>."
            )
        qubit_set.add(q_name)

    for target_set in proto.valid_targets:
        # Check for unknown qubits in targets.
        for target in target_set.targets:
            for target_id in target.ids:
                if target_id not in proto.valid_qubits:
                    raise ValueError(
                        f"Invalid DeviceSpecification: valid_targets contain qubit '{target_id}'"
                        " which is not in valid_qubits."
                    )

        # Symmetric targets should not have repeated qubits.
        if target_set.target_ordering == v2.device_pb2.TargetSet.SYMMETRIC:
            for target in target_set.targets:
                if len(target.ids) > len(set(target.ids)):
                    raise ValueError(
                        f"Invalid DeviceSpecification: the target set '{target_set.name}' is"
                        " SYMMETRIC but has a target which contains repeated qubits:"
                        f" {target.ids}."
                    )

        # Asymmetric target set type is not expected.
        # While this is allowed by the proto, it has never been set, so it's safe to raise an
        # exception if this is set unexpectedly.
        if target_set.target_ordering == v2.device_pb2.TargetSet.ASYMMETRIC:
            raise ValueError("Invalid DeviceSpecification: target_ordering cannot be ASYMMETRIC.")
Raises a ValueError if the `DeviceSpecification` proto is invalid.
cirq-google/cirq_google/devices/grid_device.py