changeset 75393 | 87ebf5a50283 |
parent 73838 | 0e6a5a6cc767 |
child 75394 | 42267c650205 |
75388:b3ca4a6ed74b | 75393:87ebf5a50283 |
---|---|
5 */ |
5 */ |
6 |
6 |
7 package isabelle |
7 package isabelle |
8 |
8 |
9 |
9 |
10 object Protocol |
10 object Protocol { |
11 { |
|
12 /* markers for inlined messages */ |
11 /* markers for inlined messages */ |
13 |
12 |
14 val Loading_Theory_Marker = Protocol_Message.Marker("loading_theory") |
13 val Loading_Theory_Marker = Protocol_Message.Marker("loading_theory") |
15 val Meta_Info_Marker = Protocol_Message.Marker("meta_info") |
14 val Meta_Info_Marker = Protocol_Message.Marker("meta_info") |
16 val Command_Timing_Marker = Protocol_Message.Marker("command_timing") |
15 val Command_Timing_Marker = Protocol_Message.Marker("command_timing") |
21 val Error_Message_Marker = Protocol_Message.Marker("error_message") |
20 val Error_Message_Marker = Protocol_Message.Marker("error_message") |
22 |
21 |
23 |
22 |
24 /* batch build */ |
23 /* batch build */ |
25 |
24 |
26 object Loading_Theory |
25 object Loading_Theory { |
27 { |
|
28 def unapply(props: Properties.T): Option[(Document.Node.Name, Document_ID.Exec)] = |
26 def unapply(props: Properties.T): Option[(Document.Node.Name, Document_ID.Exec)] = |
29 (props, props, props) match { |
27 (props, props, props) match { |
30 case (Markup.Name(name), Position.File(file), Position.Id(id)) |
28 case (Markup.Name(name), Position.File(file), Position.Id(id)) |
31 if Path.is_wellformed(file) => |
29 if Path.is_wellformed(file) => |
32 val master_dir = Path.explode(file).dir.implode |
30 val master_dir = Path.explode(file).dir.implode |
36 } |
34 } |
37 |
35 |
38 |
36 |
39 /* document editing */ |
37 /* document editing */ |
40 |
38 |
41 object Commands_Accepted |
39 object Commands_Accepted { |
42 { |
|
43 def unapply(text: String): Option[List[Document_ID.Command]] = |
40 def unapply(text: String): Option[List[Document_ID.Command]] = |
44 try { Some(space_explode(',', text).map(Value.Long.parse)) } |
41 try { Some(space_explode(',', text).map(Value.Long.parse)) } |
45 catch { case ERROR(_) => None } |
42 catch { case ERROR(_) => None } |
46 |
43 |
47 val message: XML.Elem = XML.elem(Markup.STATUS, List(XML.elem(Markup.ACCEPTED))) |
44 val message: XML.Elem = XML.elem(Markup.STATUS, List(XML.elem(Markup.ACCEPTED))) |
48 } |
45 } |
49 |
46 |
50 object Assign_Update |
47 object Assign_Update { |
51 { |
48 def unapply( |
52 def unapply(text: String) |
49 text: String |
53 : Option[(Document_ID.Version, List[String], Document.Assign_Update)] = |
50 ) : Option[(Document_ID.Version, List[String], Document.Assign_Update)] = { |
54 { |
|
55 try { |
51 try { |
56 import XML.Decode._ |
52 import XML.Decode._ |
57 def decode_upd(body: XML.Body): (Long, List[Long]) = |
53 def decode_upd(body: XML.Body): (Long, List[Long]) = |
58 space_explode(',', string(body)).map(Value.Long.parse) match { |
54 space_explode(',', string(body)).map(Value.Long.parse) match { |
59 case a :: bs => (a, bs) |
55 case a :: bs => (a, bs) |
66 case _: XML.Error => None |
62 case _: XML.Error => None |
67 } |
63 } |
68 } |
64 } |
69 } |
65 } |
70 |
66 |
71 object Removed |
67 object Removed { |
72 { |
|
73 def unapply(text: String): Option[List[Document_ID.Version]] = |
68 def unapply(text: String): Option[List[Document_ID.Version]] = |
74 try { |
69 try { |
75 import XML.Decode._ |
70 import XML.Decode._ |
76 Some(list(long)(Symbol.decode_yxml(text))) |
71 Some(list(long)(Symbol.decode_yxml(text))) |
77 } |
72 } |
82 } |
77 } |
83 |
78 |
84 |
79 |
85 /* command timing */ |
80 /* command timing */ |
86 |
81 |
87 object Command_Timing |
82 object Command_Timing { |
88 { |
|
89 def unapply(props: Properties.T): Option[(Properties.T, Document_ID.Generic, isabelle.Timing)] = |
83 def unapply(props: Properties.T): Option[(Properties.T, Document_ID.Generic, isabelle.Timing)] = |
90 props match { |
84 props match { |
91 case Markup.Command_Timing(args) => |
85 case Markup.Command_Timing(args) => |
92 (args, args) match { |
86 (args, args) match { |
93 case (Position.Id(id), Markup.Timing_Properties(timing)) => Some((args, id, timing)) |
87 case (Position.Id(id), Markup.Timing_Properties(timing)) => Some((args, id, timing)) |
98 } |
92 } |
99 |
93 |
100 |
94 |
101 /* theory timing */ |
95 /* theory timing */ |
102 |
96 |
103 object Theory_Timing |
97 object Theory_Timing { |
104 { |
|
105 def unapply(props: Properties.T): Option[(String, isabelle.Timing)] = |
98 def unapply(props: Properties.T): Option[(String, isabelle.Timing)] = |
106 props match { |
99 props match { |
107 case Markup.Theory_Timing(args) => |
100 case Markup.Theory_Timing(args) => |
108 (args, args) match { |
101 (args, args) match { |
109 case (Markup.Name(name), Markup.Timing_Properties(timing)) => Some((name, timing)) |
102 case (Markup.Name(name), Markup.Timing_Properties(timing)) => Some((name, timing)) |
180 def message_text(elem: XML.Elem, |
173 def message_text(elem: XML.Elem, |
181 heading: Boolean = false, |
174 heading: Boolean = false, |
182 pos: Position.T = Position.none, |
175 pos: Position.T = Position.none, |
183 margin: Double = Pretty.default_margin, |
176 margin: Double = Pretty.default_margin, |
184 breakgain: Double = Pretty.default_breakgain, |
177 breakgain: Double = Pretty.default_breakgain, |
185 metric: Pretty.Metric = Pretty.Default_Metric): String = |
178 metric: Pretty.Metric = Pretty.Default_Metric |
186 { |
179 ): String = { |
187 val text1 = |
180 val text1 = |
188 if (heading) { |
181 if (heading) { |
189 val h = |
182 val h = |
190 if (is_warning(elem) || is_legacy(elem)) "Warning" |
183 if (is_warning(elem) || is_legacy(elem)) "Warning" |
191 else if (is_error(elem)) "Error" |
184 else if (is_error(elem)) "Error" |
210 } |
203 } |
211 |
204 |
212 |
205 |
213 /* ML profiling */ |
206 /* ML profiling */ |
214 |
207 |
215 object ML_Profiling |
208 object ML_Profiling { |
216 { |
|
217 def unapply(msg: XML.Tree): Option[isabelle.ML_Profiling.Report] = |
209 def unapply(msg: XML.Tree): Option[isabelle.ML_Profiling.Report] = |
218 msg match { |
210 msg match { |
219 case XML.Elem(_, List(tree)) if is_tracing(msg) => |
211 case XML.Elem(_, List(tree)) if is_tracing(msg) => |
220 Markup.ML_Profiling.unapply_report(tree) |
212 Markup.ML_Profiling.unapply_report(tree) |
221 case _ => None |
213 case _ => None |
223 } |
215 } |
224 |
216 |
225 |
217 |
226 /* export */ |
218 /* export */ |
227 |
219 |
228 object Export |
220 object Export { |
229 { |
|
230 sealed case class Args( |
221 sealed case class Args( |
231 id: Option[String] = None, |
222 id: Option[String] = None, |
232 serial: Long = 0L, |
223 serial: Long = 0L, |
233 theory_name: String, |
224 theory_name: String, |
234 name: String, |
225 name: String, |
235 executable: Boolean = false, |
226 executable: Boolean = false, |
236 compress: Boolean = true, |
227 compress: Boolean = true, |
237 strict: Boolean = true) |
228 strict: Boolean = true |
238 { |
229 ) { |
239 def compound_name: String = isabelle.Export.compound_name(theory_name, name) |
230 def compound_name: String = isabelle.Export.compound_name(theory_name, name) |
240 } |
231 } |
241 |
232 |
242 def unapply(props: Properties.T): Option[Args] = |
233 def unapply(props: Properties.T): Option[Args] = |
243 props match { |
234 props match { |
257 } |
248 } |
258 |
249 |
259 |
250 |
260 /* breakpoints */ |
251 /* breakpoints */ |
261 |
252 |
262 object ML_Breakpoint |
253 object ML_Breakpoint { |
263 { |
|
264 def unapply(tree: XML.Tree): Option[Long] = |
254 def unapply(tree: XML.Tree): Option[Long] = |
265 tree match { |
255 tree match { |
266 case XML.Elem(Markup(Markup.ML_BREAKPOINT, Markup.Serial(breakpoint)), _) => Some(breakpoint) |
256 case XML.Elem(Markup(Markup.ML_BREAKPOINT, Markup.Serial(breakpoint)), _) => Some(breakpoint) |
267 case _ => None |
257 case _ => None |
268 } |
258 } |
269 } |
259 } |
270 |
260 |
271 |
261 |
272 /* dialogs */ |
262 /* dialogs */ |
273 |
263 |
274 object Dialog_Args |
264 object Dialog_Args { |
275 { |
|
276 def unapply(props: Properties.T): Option[(Document_ID.Generic, Long, String)] = |
265 def unapply(props: Properties.T): Option[(Document_ID.Generic, Long, String)] = |
277 (props, props, props) match { |
266 (props, props, props) match { |
278 case (Position.Id(id), Markup.Serial(serial), Markup.Result(result)) => |
267 case (Position.Id(id), Markup.Serial(serial), Markup.Result(result)) => |
279 Some((id, serial, result)) |
268 Some((id, serial, result)) |
280 case _ => None |
269 case _ => None |
281 } |
270 } |
282 } |
271 } |
283 |
272 |
284 object Dialog |
273 object Dialog { |
285 { |
|
286 def unapply(tree: XML.Tree): Option[(Document_ID.Generic, Long, String)] = |
274 def unapply(tree: XML.Tree): Option[(Document_ID.Generic, Long, String)] = |
287 tree match { |
275 tree match { |
288 case XML.Elem(Markup(Markup.DIALOG, Dialog_Args(id, serial, result)), _) => |
276 case XML.Elem(Markup(Markup.DIALOG, Dialog_Args(id, serial, result)), _) => |
289 Some((id, serial, result)) |
277 Some((id, serial, result)) |
290 case _ => None |
278 case _ => None |
291 } |
279 } |
292 } |
280 } |
293 |
281 |
294 object Dialog_Result |
282 object Dialog_Result { |
295 { |
283 def apply(id: Document_ID.Generic, serial: Long, result: String): XML.Elem = { |
296 def apply(id: Document_ID.Generic, serial: Long, result: String): XML.Elem = |
|
297 { |
|
298 val props = Position.Id(id) ::: Markup.Serial(serial) |
284 val props = Position.Id(id) ::: Markup.Serial(serial) |
299 XML.Elem(Markup(Markup.RESULT, props), List(XML.Text(result))) |
285 XML.Elem(Markup(Markup.RESULT, props), List(XML.Text(result))) |
300 } |
286 } |
301 |
287 |
302 def unapply(tree: XML.Tree): Option[String] = |
288 def unapply(tree: XML.Tree): Option[String] = |
306 } |
292 } |
307 } |
293 } |
308 } |
294 } |
309 |
295 |
310 |
296 |
311 trait Protocol |
297 trait Protocol { |
312 { |
|
313 /* protocol commands */ |
298 /* protocol commands */ |
314 |
299 |
315 def protocol_command_raw(name: String, args: List[Bytes]): Unit |
300 def protocol_command_raw(name: String, args: List[Bytes]): Unit |
316 def protocol_command_args(name: String, args: List[String]): Unit |
301 def protocol_command_args(name: String, args: List[String]): Unit |
317 def protocol_command(name: String, args: String*): Unit |
302 def protocol_command(name: String, args: String*): Unit |
332 /* interned items */ |
317 /* interned items */ |
333 |
318 |
334 def define_blob(digest: SHA1.Digest, bytes: Bytes): Unit = |
319 def define_blob(digest: SHA1.Digest, bytes: Bytes): Unit = |
335 protocol_command_raw("Document.define_blob", List(Bytes(digest.toString), bytes)) |
320 protocol_command_raw("Document.define_blob", List(Bytes(digest.toString), bytes)) |
336 |
321 |
337 private def encode_command(resources: Resources, command: Command) |
322 private def encode_command( |
338 : (String, String, String, String, String, List[String]) = |
323 resources: Resources, |
339 { |
324 command: Command |
325 ) : (String, String, String, String, String, List[String]) = { |
|
340 import XML.Encode._ |
326 import XML.Encode._ |
341 |
327 |
342 val parents = command.theory_parents(resources).map(name => File.standard_url(name.node)) |
328 val parents = command.theory_parents(resources).map(name => File.standard_url(name.node)) |
343 val parents_yxml = Symbol.encode_yxml(list(string)(parents)) |
329 val parents_yxml = Symbol.encode_yxml(list(string)(parents)) |
344 |
330 |
345 val blobs_yxml = |
331 val blobs_yxml = { |
346 { |
|
347 val encode_blob: T[Exn.Result[Command.Blob]] = |
332 val encode_blob: T[Exn.Result[Command.Blob]] = |
348 variant(List( |
333 variant(List( |
349 { case Exn.Res(Command.Blob(a, b, c)) => |
334 { case Exn.Res(Command.Blob(a, b, c)) => |
350 (Nil, triple(string, string, option(string))( |
335 (Nil, triple(string, string, option(string))( |
351 (a.node, b.implode, c.map(p => p._1.toString)))) }, |
336 (a.node, b.implode, c.map(p => p._1.toString)))) }, |
352 { case Exn.Exn(e) => (Nil, string(Exn.message(e))) })) |
337 { case Exn.Exn(e) => (Nil, string(Exn.message(e))) })) |
353 |
338 |
354 Symbol.encode_yxml(pair(list(encode_blob), int)(command.blobs, command.blobs_index)) |
339 Symbol.encode_yxml(pair(list(encode_blob), int)(command.blobs, command.blobs_index)) |
355 } |
340 } |
356 |
341 |
357 val toks_yxml = |
342 val toks_yxml = { |
358 { |
|
359 val encode_tok: T[Token] = (tok => pair(int, int)((tok.kind.id, Symbol.length(tok.source)))) |
343 val encode_tok: T[Token] = (tok => pair(int, int)((tok.kind.id, Symbol.length(tok.source)))) |
360 Symbol.encode_yxml(list(encode_tok)(command.span.content)) |
344 Symbol.encode_yxml(list(encode_tok)(command.span.content)) |
361 } |
345 } |
362 val toks_sources = command.span.content.map(tok => Symbol.encode(tok.source)) |
346 val toks_sources = command.span.content.map(tok => Symbol.encode(tok.source)) |
363 |
347 |
364 (Document_ID(command.id), Symbol.encode(command.span.name), parents_yxml, |
348 (Document_ID(command.id), Symbol.encode(command.span.name), parents_yxml, |
365 blobs_yxml, toks_yxml, toks_sources) |
349 blobs_yxml, toks_yxml, toks_sources) |
366 } |
350 } |
367 |
351 |
368 def define_command(resources: Resources, command: Command): Unit = |
352 def define_command(resources: Resources, command: Command): Unit = { |
369 { |
|
370 val (command_id, name, parents_yxml, blobs_yxml, toks_yxml, toks_sources) = |
353 val (command_id, name, parents_yxml, blobs_yxml, toks_yxml, toks_sources) = |
371 encode_command(resources, command) |
354 encode_command(resources, command) |
372 protocol_command_args( |
355 protocol_command_args( |
373 "Document.define_command", command_id :: name :: parents_yxml :: blobs_yxml :: |
356 "Document.define_command", command_id :: name :: parents_yxml :: blobs_yxml :: |
374 toks_yxml :: toks_sources) |
357 toks_yxml :: toks_sources) |
375 } |
358 } |
376 |
359 |
377 def define_commands(resources: Resources, commands: List[Command]): Unit = |
360 def define_commands(resources: Resources, commands: List[Command]): Unit = { |
378 { |
|
379 protocol_command_args("Document.define_commands", |
361 protocol_command_args("Document.define_commands", |
380 commands.map(command => |
362 commands.map(command => { |
381 { |
|
382 import XML.Encode._ |
363 import XML.Encode._ |
383 val (command_id, name, parents_yxml, blobs_yxml, toks_yxml, toks_sources) = |
364 val (command_id, name, parents_yxml, blobs_yxml, toks_yxml, toks_sources) = |
384 encode_command(resources, command) |
365 encode_command(resources, command) |
385 val body = |
366 val body = |
386 pair(string, pair(string, pair(string, pair(string, pair(string, list(string))))))( |
367 pair(string, pair(string, pair(string, pair(string, pair(string, list(string))))))( |
387 command_id, (name, (parents_yxml, (blobs_yxml, (toks_yxml, toks_sources))))) |
368 command_id, (name, (parents_yxml, (blobs_yxml, (toks_yxml, toks_sources))))) |
388 YXML.string_of_body(body) |
369 YXML.string_of_body(body) |
389 })) |
370 })) |
390 } |
371 } |
391 |
372 |
392 def define_commands_bulk(resources: Resources, commands: List[Command]): Unit = |
373 def define_commands_bulk(resources: Resources, commands: List[Command]): Unit = { |
393 { |
|
394 val (irregular, regular) = commands.partition(command => YXML.detect(command.source)) |
374 val (irregular, regular) = commands.partition(command => YXML.detect(command.source)) |
395 irregular.foreach(define_command(resources, _)) |
375 irregular.foreach(define_command(resources, _)) |
396 regular match { |
376 regular match { |
397 case Nil => |
377 case Nil => |
398 case List(command) => define_command(resources, command) |
378 case List(command) => define_command(resources, command) |
410 protocol_command("Document.cancel_exec", Document_ID(id)) |
390 protocol_command("Document.cancel_exec", Document_ID(id)) |
411 |
391 |
412 |
392 |
413 /* document versions */ |
393 /* document versions */ |
414 |
394 |
415 def update(old_id: Document_ID.Version, new_id: Document_ID.Version, |
395 def update( |
416 edits: List[Document.Edit_Command], consolidate: List[Document.Node.Name]): Unit = |
396 old_id: Document_ID.Version, |
417 { |
397 new_id: Document_ID.Version, |
418 val consolidate_yxml = |
398 edits: List[Document.Edit_Command], |
419 { |
399 consolidate: List[Document.Node.Name] |
400 ): Unit = { |
|
401 val consolidate_yxml = { |
|
420 import XML.Encode._ |
402 import XML.Encode._ |
421 Symbol.encode_yxml(list(string)(consolidate.map(_.node))) |
403 Symbol.encode_yxml(list(string)(consolidate.map(_.node))) |
422 } |
404 } |
423 val edits_yxml = |
405 val edits_yxml = { |
424 { |
|
425 import XML.Encode._ |
406 import XML.Encode._ |
426 def id: T[Command] = (cmd => long(cmd.id)) |
407 def id: T[Command] = (cmd => long(cmd.id)) |
427 def encode_edit(name: Document.Node.Name) |
408 def encode_edit(name: Document.Node.Name) |
428 : T[Document.Node.Edit[Command.Edit, Command.Perspective]] = |
409 : T[Document.Node.Edit[Command.Edit, Command.Perspective]] = |
429 variant(List( |
410 variant(List( |
444 } |
425 } |
445 protocol_command_args("Document.update", |
426 protocol_command_args("Document.update", |
446 Document_ID(old_id) :: Document_ID(new_id) :: consolidate_yxml :: edits_yxml) |
427 Document_ID(old_id) :: Document_ID(new_id) :: consolidate_yxml :: edits_yxml) |
447 } |
428 } |
448 |
429 |
449 def remove_versions(versions: List[Document.Version]): Unit = |
430 def remove_versions(versions: List[Document.Version]): Unit = { |
450 { |
|
451 val versions_yxml = |
431 val versions_yxml = |
452 { import XML.Encode._ |
432 { import XML.Encode._ |
453 Symbol.encode_yxml(list(long)(versions.map(_.id))) } |
433 Symbol.encode_yxml(list(long)(versions.map(_.id))) } |
454 protocol_command("Document.remove_versions", versions_yxml) |
434 protocol_command("Document.remove_versions", versions_yxml) |
455 } |
435 } |