@@ -246,4 +246,235 @@ object TopLevelParser:
246246 Right (mapped)
247247 end match
248248 end mapTextAndToken
249+
250+ /** Parse content as if it were inside a Domain body.
251+ *
252+ * Wraps the input in a synthetic `domain SyntheticScope is { ... }`
253+ * declaration, parses it, and returns the resulting Domain.
254+ *
255+ * @param input The RiddlParserInput containing domain-level content
256+ * @param withVerboseFailures Enable verbose parse failure messages
257+ * @return Either error messages or the parsed Domain
258+ */
259+ def parseAsDomain (
260+ input : RiddlParserInput ,
261+ withVerboseFailures : Boolean = false
262+ )(using PlatformContext ): Either [Messages , Domain ] =
263+ val wrapped = RiddlParserInput (
264+ s " domain SyntheticScope is { \n ${input.data}\n } " ,
265+ input.root
266+ )
267+ val tlp = new TopLevelParser (wrapped, withVerboseFailures)
268+ tlp.parseDomainContents
269+ end parseAsDomain
270+
271+ /** Parse content as if it were inside a Context body.
272+ *
273+ * Wraps the input in a synthetic `context SyntheticScope is { ... }`
274+ * declaration, parses it, and returns the resulting Context.
275+ *
276+ * @param input The RiddlParserInput containing context-level content
277+ * @param withVerboseFailures Enable verbose parse failure messages
278+ * @return Either error messages or the parsed Context
279+ */
280+ def parseAsContext (
281+ input : RiddlParserInput ,
282+ withVerboseFailures : Boolean = false
283+ )(using PlatformContext ): Either [Messages , Context ] =
284+ val wrapped = RiddlParserInput (
285+ s " context SyntheticScope is { \n ${input.data}\n } " ,
286+ input.root
287+ )
288+ val tlp = new TopLevelParser (wrapped, withVerboseFailures)
289+ tlp.parseContextContents
290+ end parseAsContext
291+
292+ /** Parse content as if it were inside an Entity body.
293+ *
294+ * Wraps the input in a synthetic `entity SyntheticScope is { ... }`
295+ * declaration, parses it, and returns the resulting Entity.
296+ *
297+ * @param input The RiddlParserInput containing entity-level content
298+ * @param withVerboseFailures Enable verbose parse failure messages
299+ * @return Either error messages or the parsed Entity
300+ */
301+ def parseAsEntity (
302+ input : RiddlParserInput ,
303+ withVerboseFailures : Boolean = false
304+ )(using PlatformContext ): Either [Messages , Entity ] =
305+ val wrapped = RiddlParserInput (
306+ s " entity SyntheticScope is { \n ${input.data}\n } " ,
307+ input.root
308+ )
309+ val tlp = new TopLevelParser (wrapped, withVerboseFailures)
310+ tlp.parseEntityContents
311+ end parseAsEntity
312+
313+ /** Parse content as if it were inside a Module body.
314+ *
315+ * Wraps the input in a synthetic `module SyntheticScope is { ... }`
316+ * declaration, parses it, and returns the resulting Module.
317+ */
318+ def parseAsModule (
319+ input : RiddlParserInput ,
320+ withVerboseFailures : Boolean = false
321+ )(using PlatformContext ): Either [Messages , Module ] =
322+ val wrapped = RiddlParserInput (
323+ s " module SyntheticScope is { \n ${input.data}\n } " ,
324+ input.root
325+ )
326+ val tlp = new TopLevelParser (wrapped, withVerboseFailures)
327+ tlp.parseModuleContents
328+ end parseAsModule
329+
330+ /** Parse content as if it were inside an Adaptor body.
331+ *
332+ * Wraps the input in a synthetic adaptor declaration using
333+ * the caller-provided direction and context reference, then
334+ * parses it and returns the resulting Adaptor.
335+ *
336+ * @param input The RiddlParserInput containing adaptor body content
337+ * @param direction The AdaptorDirection (InboundAdaptor or OutboundAdaptor)
338+ * @param contextRef The ContextRef the adaptor adapts from/to
339+ * @param withVerboseFailures Enable verbose parse failure messages
340+ * @return Either error messages or the parsed Adaptor
341+ */
342+ def parseAsAdaptor (
343+ input : RiddlParserInput ,
344+ direction : AdaptorDirection ,
345+ contextRef : ContextRef ,
346+ withVerboseFailures : Boolean = false
347+ )(using PlatformContext ): Either [Messages , Adaptor ] =
348+ val dirStr = direction match
349+ case _ : InboundAdaptor => " from"
350+ case _ : OutboundAdaptor => " to"
351+ val ctxPath = contextRef.pathId.value.mkString(" ." )
352+ val wrapped = RiddlParserInput (
353+ s " adaptor SyntheticScope $dirStr context $ctxPath is { \n ${input.data}\n } " ,
354+ input.root
355+ )
356+ val tlp = new TopLevelParser (wrapped, withVerboseFailures)
357+ tlp.parseAdaptorContents
358+ end parseAsAdaptor
359+
360+ /** Parse content as if it were inside a Projector body.
361+ *
362+ * Wraps the input in a synthetic `projector SyntheticScope is { ... }`
363+ * declaration, parses it, and returns the resulting Projector.
364+ */
365+ def parseAsProjector (
366+ input : RiddlParserInput ,
367+ withVerboseFailures : Boolean = false
368+ )(using PlatformContext ): Either [Messages , Projector ] =
369+ val wrapped = RiddlParserInput (
370+ s " projector SyntheticScope is { \n ${input.data}\n } " ,
371+ input.root
372+ )
373+ val tlp = new TopLevelParser (wrapped, withVerboseFailures)
374+ tlp.parseProjectorContents
375+ end parseAsProjector
376+
377+ /** Parse content as if it were inside a Repository body.
378+ *
379+ * Wraps the input in a synthetic `repository SyntheticScope is { ... }`
380+ * declaration, parses it, and returns the resulting Repository.
381+ */
382+ def parseAsRepository (
383+ input : RiddlParserInput ,
384+ withVerboseFailures : Boolean = false
385+ )(using PlatformContext ): Either [Messages , Repository ] =
386+ val wrapped = RiddlParserInput (
387+ s " repository SyntheticScope is { \n ${input.data}\n } " ,
388+ input.root
389+ )
390+ val tlp = new TopLevelParser (wrapped, withVerboseFailures)
391+ tlp.parseRepositoryContents
392+ end parseAsRepository
393+
394+ /** Parse content as if it were inside a Saga body.
395+ *
396+ * Parses the input for saga body content (saga steps,
397+ * functions, inlets, outlets) and assembles a Saga using
398+ * the caller-provided input/output aggregations.
399+ *
400+ * @param input The RiddlParserInput containing saga body content
401+ * @param sagaInput Optional input aggregation from the parent Saga
402+ * @param sagaOutput Optional output aggregation from the parent Saga
403+ * @param withVerboseFailures Enable verbose parse failure messages
404+ * @return Either error messages or the parsed Saga
405+ */
406+ def parseAsSaga (
407+ input : RiddlParserInput ,
408+ sagaInput : Option [Aggregation ] = None ,
409+ sagaOutput : Option [Aggregation ] = None ,
410+ withVerboseFailures : Boolean = false
411+ )(using PlatformContext ): Either [Messages , Saga ] =
412+ val tlp = new TopLevelParser (input, withVerboseFailures)
413+ tlp.parseSagaDefinitions.map { contents =>
414+ val loc =
415+ if contents.nonEmpty then contents.head.loc
416+ else At .empty
417+ Saga (loc, Identifier .empty, sagaInput, sagaOutput,
418+ contents.toContents)
419+ }
420+ end parseAsSaga
421+
422+ /** Parse content as if it were inside an Epic body.
423+ *
424+ * Parses the input for epic body content (use cases, types,
425+ * etc.) and assembles an Epic using the caller-provided
426+ * UserStory.
427+ *
428+ * @param input The RiddlParserInput containing epic-level content
429+ * @param userStory The UserStory from the parent Epic definition
430+ * @param withVerboseFailures Enable verbose parse failure messages
431+ * @return Either error messages or the parsed Epic
432+ */
433+ def parseAsEpic (
434+ input : RiddlParserInput ,
435+ userStory : UserStory ,
436+ withVerboseFailures : Boolean = false
437+ )(using PlatformContext ): Either [Messages , Epic ] =
438+ val tlp = new TopLevelParser (input, withVerboseFailures)
439+ tlp.parseEpicDefinitions.map { contents =>
440+ val loc =
441+ if contents.nonEmpty then contents.head.loc
442+ else At .empty
443+ Epic (loc, Identifier .empty, userStory, contents.toContents)
444+ }
445+ end parseAsEpic
446+
447+ /** Parse content as if it were inside a Streamlet body.
448+ *
449+ * Parses the input for processor content (handlers, types,
450+ * functions, etc.) and assembles a Streamlet using the
451+ * caller-provided shape, inlets, and outlets.
452+ *
453+ * @param input The RiddlParserInput containing streamlet body content
454+ * @param shape The StreamletShape from the parent Streamlet definition
455+ * @param inlets The Inlet definitions from the parent Streamlet
456+ * @param outlets The Outlet definitions from the parent Streamlet
457+ * @param withVerboseFailures Enable verbose parse failure messages
458+ * @return Either error messages or the parsed Streamlet
459+ */
460+ def parseAsStreamlet (
461+ input : RiddlParserInput ,
462+ shape : StreamletShape ,
463+ inlets : Seq [Inlet ],
464+ outlets : Seq [Outlet ],
465+ withVerboseFailures : Boolean = false
466+ )(using PlatformContext ): Either [Messages , Streamlet ] =
467+ val tlp = new TopLevelParser (input, withVerboseFailures)
468+ tlp.parseStreamletDefinitions.map { contents =>
469+ val allContents =
470+ (inlets.asInstanceOf [Seq [StreamletContents ]] ++
471+ outlets.asInstanceOf [Seq [StreamletContents ]] ++
472+ contents)
473+ val loc =
474+ if allContents.nonEmpty then allContents.head.loc
475+ else At .empty
476+ Streamlet (loc, Identifier .empty, shape, allContents.toContents)
477+ }
478+ end parseAsStreamlet
479+
249480end TopLevelParser
0 commit comments