| author | wenzelm |
| Fri, 17 Jan 2025 19:46:36 +0100 | |
| changeset 81864 | 17831ae5224d |
| parent 80300 | 152d6c58adb3 |
| child 83311 | 0e40bd617b6c |
| permissions | -rw-r--r-- |
| 65214 | 1 |
/* Title: Pure/PIDE/protocol_handlers.scala |
2 |
Author: Makarius |
|
3 |
||
4 |
Management of add-on protocol handlers for PIDE session. |
|
5 |
*/ |
|
6 |
||
7 |
package isabelle |
|
8 |
||
9 |
||
| 75393 | 10 |
object Protocol_Handlers {
|
| 72217 | 11 |
private def err_handler(exn: Throwable, name: String): Nothing = |
|
80300
152d6c58adb3
more informative exception output, with optional trace;
wenzelm
parents:
75393
diff
changeset
|
12 |
error("Failed to initialize protocol handler: " + quote(name) + "\n" + Exn.print(exn))
|
| 65214 | 13 |
|
14 |
sealed case class State( |
|
| 65215 | 15 |
session: Session, |
| 65214 | 16 |
handlers: Map[String, Session.Protocol_Handler] = Map.empty, |
| 75393 | 17 |
functions: Map[String, Session.Protocol_Function] = Map.empty |
18 |
) {
|
|
| 65214 | 19 |
def get(name: String): Option[Session.Protocol_Handler] = handlers.get(name) |
20 |
||
| 75393 | 21 |
def init(handler: Session.Protocol_Handler): State = {
|
| 65214 | 22 |
val name = handler.getClass.getName |
|
72156
065dcd80293e
provide protocol handlers via isabelle_system_service;
wenzelm
parents:
71970
diff
changeset
|
23 |
try {
|
|
065dcd80293e
provide protocol handlers via isabelle_system_service;
wenzelm
parents:
71970
diff
changeset
|
24 |
if (handlers.isDefinedAt(name)) error("Duplicate protocol handler: " + name)
|
|
065dcd80293e
provide protocol handlers via isabelle_system_service;
wenzelm
parents:
71970
diff
changeset
|
25 |
else {
|
|
065dcd80293e
provide protocol handlers via isabelle_system_service;
wenzelm
parents:
71970
diff
changeset
|
26 |
handler.init(session) |
|
065dcd80293e
provide protocol handlers via isabelle_system_service;
wenzelm
parents:
71970
diff
changeset
|
27 |
val dups = for ((a, _) <- handler.functions if functions.isDefinedAt(a)) yield a |
|
065dcd80293e
provide protocol handlers via isabelle_system_service;
wenzelm
parents:
71970
diff
changeset
|
28 |
if (dups.nonEmpty) error("Duplicate protocol functions: " + commas_quote(dups))
|
|
065dcd80293e
provide protocol handlers via isabelle_system_service;
wenzelm
parents:
71970
diff
changeset
|
29 |
copy(handlers = handlers + (name -> handler), functions = functions ++ handler.functions) |
| 65214 | 30 |
} |
|
72156
065dcd80293e
provide protocol handlers via isabelle_system_service;
wenzelm
parents:
71970
diff
changeset
|
31 |
} |
| 72217 | 32 |
catch { case exn: Throwable => err_handler(exn, name) }
|
| 65214 | 33 |
} |
34 |
||
| 75393 | 35 |
def init(name: String): State = {
|
| 72217 | 36 |
val handler = |
| 71734 | 37 |
try {
|
| 72217 | 38 |
Class.forName(name).getDeclaredConstructor().newInstance() |
39 |
.asInstanceOf[Session.Protocol_Handler] |
|
| 71734 | 40 |
} |
| 72217 | 41 |
catch { case exn: Throwable => err_handler(exn, name) }
|
42 |
init(handler) |
|
| 65214 | 43 |
} |
44 |
||
45 |
def invoke(msg: Prover.Protocol_Output): Boolean = |
|
46 |
msg.properties match {
|
|
| 71673 | 47 |
case (Markup.FUNCTION, a) :: _ if functions.isDefinedAt(a) => |
| 65214 | 48 |
try { functions(a)(msg) }
|
49 |
catch {
|
|
50 |
case exn: Throwable => |
|
51 |
Output.error_message( |
|
|
80300
152d6c58adb3
more informative exception output, with optional trace;
wenzelm
parents:
75393
diff
changeset
|
52 |
"Failed invocation of protocol function: " + quote(a) + "\n" + Exn.print(exn)) |
| 65214 | 53 |
false |
54 |
} |
|
55 |
case _ => false |
|
56 |
} |
|
57 |
||
| 75393 | 58 |
def exit(): State = {
|
| 65219 | 59 |
for ((_, handler) <- handlers) handler.exit() |
| 65215 | 60 |
copy(handlers = Map.empty, functions = Map.empty) |
| 65214 | 61 |
} |
62 |
} |
|
63 |
||
| 65215 | 64 |
def init(session: Session): Protocol_Handlers = |
65 |
new Protocol_Handlers(session) |
|
| 65214 | 66 |
} |
67 |
||
| 75393 | 68 |
class Protocol_Handlers private(session: Session) {
|
| 65215 | 69 |
private val state = Synchronized(Protocol_Handlers.State(session)) |
| 65214 | 70 |
|
| 72216 | 71 |
def prover_options(options: Options): Options = |
| 73359 | 72 |
state.value.handlers.foldLeft(options) {
|
73 |
case (opts, (_, handler)) => handler.prover_options(opts) |
|
74 |
} |
|
| 72216 | 75 |
|
| 65219 | 76 |
def get(name: String): Option[Session.Protocol_Handler] = state.value.get(name) |
| 65315 | 77 |
def init(handler: Session.Protocol_Handler): Unit = state.change(_.init(handler)) |
78 |
def init(name: String): Unit = state.change(_.init(name)) |
|
| 65219 | 79 |
def invoke(msg: Prover.Protocol_Output): Boolean = state.value.invoke(msg) |
80 |
def exit(): Unit = state.change(_.exit()) |
|
| 65214 | 81 |
} |