return exports as result for Isabelle server;
authorwenzelm
Mon, 07 May 2018 19:40:55 +0200
changeset 68106 a514e29db980
parent 68105 577072a0ceed
child 68107 3687109009c4
return exports as result for Isabelle server;
src/Doc/System/Server.thy
src/Pure/General/bytes.scala
src/Pure/Thy/thy_resources.scala
src/Pure/Tools/server_commands.scala
--- a/src/Doc/System/Server.thy	Mon May 07 18:25:26 2018 +0200
+++ b/src/Doc/System/Server.thy	Mon May 07 19:40:55 2018 +0200
@@ -897,10 +897,14 @@
   \end{tabular}
 
   \begin{tabular}{ll}
+  \<^bold>\<open>type\<close> \<open>export =\<close> \\
+  \quad~~\<open>{name: string, base64: bool, body: string}\<close> \\
+  \<^bold>\<open>type\<close> \<open>node_results =\<close> \\
+  \quad~~\<open>{status: node_status, messages: [message], exports: [export]}\<close> \\
   \<^bold>\<open>type\<close> \<open>use_theories_results =\<close> \\
   \quad\<open>{ok: bool,\<close> \\
   \quad~~\<open>errors: [message],\<close> \\
-  \quad~~\<open>nodes: [node \<oplus> {status: node_status, messages: [message]}]}\<close> \\
+  \quad~~\<open>nodes: [node \<oplus> node_results]}\<close> \\
   \end{tabular}
 
   \<^medskip>
@@ -916,6 +920,14 @@
   invocations of \<^verbatim>\<open>use_theories\<close> are idempotent: it could make sense to do
   that with different values for \<open>pretty_margin\<close> or \<open>unicode_symbols\<close> to get
   different formatting for \<open>errors\<close> or \<open>messages\<close>.
+
+  The \<open>exports\<close> can be arbitrary binary resources produced by a theory. An
+  \<open>export\<close> \<open>name\<close> roughly follows file-system standards: ``\<^verbatim>\<open>/\<close>'' separated
+  list of base names (excluding special names like ``\<^verbatim>\<open>.\<close>'' or ``\<^verbatim>\<open>..\<close>''). The
+  \<open>base64\<close> field specifies the format of the \<open>body\<close> string: it is true for a
+  byte vector that cannot be represented as plain text in UTF-8 encoding,
+  which means the string needs to be decoded as in
+  \<^verbatim>\<open>java.util.Base64.getDecoder.decode(String)\<close>.
 \<close>
 
 
--- a/src/Pure/General/bytes.scala	Mon May 07 18:25:26 2018 +0200
+++ b/src/Pure/General/bytes.scala	Mon May 07 19:40:55 2018 +0200
@@ -160,6 +160,12 @@
     Base64.getEncoder.encodeToString(b)
   }
 
+  def maybe_base64: (Boolean, String) =
+  {
+    val s = text
+    if (this == Bytes(s)) (false, s) else (true, base64)
+  }
+
   override def toString: String =
   {
     val str = text
--- a/src/Pure/Thy/thy_resources.scala	Mon May 07 18:25:26 2018 +0200
+++ b/src/Pure/Thy/thy_resources.scala	Mon May 07 19:40:55 2018 +0200
@@ -72,6 +72,16 @@
         (_, tree) <- state.command_results(version, command).iterator
        } yield (tree, pos)).toList
     }
+
+    def exports(node_name: Document.Node.Name): List[Export.Entry] =
+    {
+      val node = version.nodes(node_name)
+      Command.Exports.merge(
+        for {
+          command <- node.commands.iterator
+          st <- state.command_states(version, command).iterator
+        } yield st.exports).iterator.map(_._2).toList
+    }
   }
 
   class Session private[Thy_Resources](
--- a/src/Pure/Tools/server_commands.scala	Mon May 07 18:25:26 2018 +0200
+++ b/src/Pure/Tools/server_commands.scala	Mon May 07 19:40:55 2018 +0200
@@ -212,7 +212,13 @@
                 ("messages" ->
                   (for {
                     (tree, pos) <- result.messages(name) if Protocol.is_exported(tree)
-                  } yield output_message(tree, pos)))))
+                  } yield output_message(tree, pos))) +
+                ("exports" ->
+                  (for { entry <- result.exports(name) }
+                   yield {
+                     val (base64, body) = entry.body.join.maybe_base64
+                     JSON.Object("name" -> entry.name, "base64" -> base64, "body" -> body)
+                   }))))
 
       (result_json, result)
     }