def deserialize(self, proto: v2.program_pb2.Program) -> cirq.Circuit:
        """Deserialize a Circuit from a cirq_google.api.v2.Program.

        Args:
            proto: A dictionary representing a cirq_google.api.v2.Program proto.

        Returns:
            The deserialized Circuit

        Raises:
            ValueError: If the given proto has no language or the language gate set mismatches
                that specified in as the name of this serialized gate set. Also if deserializing
                a schedule is attempted.
            NotImplementedError: If the program proto does not contain a circuit or schedule.
        """
        which = proto.WhichOneof('program')

        if which == 'circuit':
            deserialized_constants: list[Any] = []
            for constant in proto.constants:
                which_const = constant.WhichOneof('const_value')
                if which_const == 'string_value':
                    deserialized_constants.append(constant.string_value)
                elif which_const == 'circuit_value':
                    circuit = self._deserialize_circuit(
                        constant.circuit_value,
                        constants=proto.constants,
                        deserialized_constants=deserialized_constants,
                    )
                    deserialized_constants.append(circuit.freeze())
                elif which_const == 'qubit':
                    deserialized_constants.append(v2.qubit_from_proto_id(constant.qubit.id))
                elif which_const == 'operation_value':
                    if self.op_deserializer and self.op_deserializer.can_deserialize_proto(
                        constant.operation_value
                    ):
                        op_pb = self.op_deserializer.from_proto(
                            constant.operation_value,
                            constants=proto.constants,
                            deserialized_constants=deserialized_constants,
                        )
                    elif self.stimcirq_deserializer.can_deserialize_proto(constant.operation_value):
                        op_pb = self.stimcirq_deserializer.from_proto(
                            constant.operation_value,
                            constants=proto.constants,
                            deserialized_constants=deserialized_constants,
                        )
                    else:
                        op_pb = self._deserialize_gate_op(
                            constant.operation_value,
                            constants=proto.constants,
                            deserialized_constants=deserialized_constants,
                        )
                    deserialized_constants.append(op_pb)
                elif which_const == 'moment_value':
                    deserialized_constants.append(
                        self._deserialize_moment(
                            constant.moment_value,
                            constants=proto.constants,
                            deserialized_constants=deserialized_constants,
                        )
                    )
                elif which_const == 'tag_value':
                    if self.tag_deserializer and self.tag_deserializer.can_deserialize_proto(
                        constant.tag_value
                    ):
                        deserialized_constants.append(
                            self.tag_deserializer.from_proto(
                                constant.tag_value,
                                constants=proto.constants,
                                deserialized_constants=deserialized_constants,
                            )
                        )
                    else:
                        deserialized_constants.append(self._deserialize_tag(constant.tag_value))
                else:
                    msg = f'Unrecognized constant type {which_const}, ignoring.'  # pragma: no cover
                    warnings.warn(msg)  # pragma: no cover
                    deserialized_constants.append(None)  # pragma: no cover
            circuit = self._deserialize_circuit(
                proto.circuit,
                constants=proto.constants,
                deserialized_constants=deserialized_constants,
            )
            return circuit
        if which == 'schedule':
            raise ValueError('Deserializing a schedule is no longer supported.')

        raise NotImplementedError('Program proto does not contain a circuit.')
Deserialize a Circuit from a cirq_google.api.v2.Program.

        Args:
            proto: A dictionary representing a cirq_google.api.v2.Program proto.

        Returns:
            The deserialized Circuit

        Raises:
            ValueError: If the given proto has no language or the language gate set mismatches
                that specified in as the name of this serialized gate set. Also if deserializing
                a schedule is attempted.
            NotImplementedError: If the program proto does not contain a circuit or schedule.
        
cirq-google/cirq_google/serialization/circuit_serializer.py