defmodule AbsinthePlugCache.Plug.DocumentProvider.Compiled.Writer do @moduledoc false defmacro write(env) do [ quoted_compiled_lookups(env), quoted_source_lookups(env), quoted_lookup_fallthrough(), quoted_pipeline_tools() ] end @doc false def error_message(id, module, messages) do messages = List.wrap(messages) "\n\n" <> """ Could not compile document provider #{module}. The following problems were found processing document "#{id}": """ <> Enum.join(Enum.map(messages, &" - #{&1}"), "\n") <> "\n" end @spec quoted_compiled_lookups(Macro.Env.t()) :: Macro.t() defp quoted_compiled_lookups(env) do docs = Module.get_attribute(env.module, :absinthe_documents_to_compile) compilation_pipeline = Module.get_attribute(env.module, :compilation_pipeline) for {id, document_text} <- docs do pipeline = compilation_pipeline ++ [ {AbsinthePlugCache.Plug.DocumentProvider.Compiled.Check, id: id, module: env.module} ] case Absinthe.Pipeline.run(document_text, pipeline) do {:ok, result, _} -> document = Macro.escape(result) quote do def __absinthe_plug_doc__(:compiled, unquote(id)), do: unquote(document) end {:error, message, _} -> raise error_message(id, env.module, message) end end end @spec quoted_source_lookups(Macro.Env.t()) :: Macro.t() defp quoted_source_lookups(env) do docs = Module.get_attribute(env.module, :absinthe_documents_to_compile) for {id, document_text} <- docs do quote do def __absinthe_plug_doc__(:source, unquote(id)), do: unquote(document_text) end end end @spec quoted_lookup_fallthrough() :: Macro.t() defp quoted_lookup_fallthrough() do quote do def __absinthe_plug_doc__(_, _), do: nil end end @spec quoted_pipeline_tools() :: Macro.t() defp quoted_pipeline_tools() do quote do def __absinthe_plug_doc__(:remaining_pipeline) do @compilation_pipeline |> List.last() |> case do {mod, _} -> mod mod -> mod end end end end end