override def exitFrag()

in nlpcraft/src/main/scala/org/apache/nlpcraft/internal/intent/compiler/NCIDLCompiler.scala [270:422]


        override def exitFrag(ctx: IDP.FragContext): Unit =
            val frag = NCIDLFragment(fragId, terms.toList)

            fragCache.get(frag.id) match
                case Some(_) =>
                    if isMethodLevel then
                        logger.warn(s"Fragment '${frag.id}' was overridden just for the scope of: '${this.origin}'")
                    else
                        logger.warn(s"Fragment '${frag.id}' was overridden in origin: '${this.origin}'")
                case None => // No-op.

            fragCache += frag.id -> frag

            terms.clear()
            fragId = null

        /**
          *
          * @param intent
          * @param ctx
          */
        private def addIntent(intent: NCIDLIntent)(implicit ctx: ParserRuleContext): Unit =
            val intentId = intent.id
            if intents.exists(_.id == intentId) then SE(s"Duplicate intent ID: $intentId")
            intents += intent

        override def exitIntent(ctx: IDP.IntentContext): Unit =
            addIntent(
                NCIDLIntent(
                    origin,
                    idl,
                    intentId,
                    intentOpts,
                    if intentMeta == null then Map.empty else intentMeta,
                    flowRegex,
                    terms.toList
                )
            )(ctx.intentId())

            intentMeta = null
            intentOpts = new NCIDLIntentOptions()
            terms.clear()

        override def exitImprt(ctx: IDP.ImprtContext): Unit =
                val x = NCUtils.trimQuotes(ctx.qstring().getText)

                if importCache.contains(x) then logger.warn(s"Ignoring already processed IDL import '$x' in: $origin")
                else
                   importCache += x

                    var imports: Set[NCIDLIntent] = null
                    val file = new File(x)

                    // First, try absolute path.
                    if file.exists() then
                        val idl = NCUtils.readLines(file).mkString("\n")
                        imports = compile(idl, x)

                    // Second, try as a classloader resource.
                    if imports == null then
                        val in = cfg.getClass.getClassLoader.getResourceAsStream(x)
                        if in != null then
                            val idl = NCUtils.readLines(in).mkString("\n")
                            imports = compile(idl, x)

                    // Finally, try as URL resource.
                    if imports == null then
                        try
                            val idl = NCUtils.readLines(new URL(x).openStream()).mkString("\n")
                            imports = compile(idl,  x)
                        catch case _: Exception => throw newRuntimeError(s"Invalid or unknown import location: $x")(ctx.qstring())

                    require(imports != null)
                    imports.foreach(addIntent(_)(ctx.qstring()))

        override def syntaxError(errMsg: String, srcName: String, line: Int, pos: Int): NCException =
            throw new NCException(mkSyntaxError(errMsg, srcName, line, pos, idl, origin, cfg))

        override def runtimeError(errMsg: String, srcName: String, line: Int, pos: Int, cause: Exception = null): NCException =
            throw new NCException(mkRuntimeError(errMsg, srcName, line, pos, idl, origin, cfg), cause)

    /**
      *
      * @param msg
      * @param srcName
      * @param line
      * @param charPos
      * @param idl
      * @param origin IDL origin.
      * @param mdlCfg
      */
    private def mkSyntaxError(
        msg: String,
        srcName: String,
        line: Int, // 1, 2, ...
        charPos: Int, // 0, 1, 2, ...
        idl: String,
        origin: String,
        mdlCfg: NCModelConfig): String = mkError("syntax", msg, srcName, line, charPos, idl, origin, mdlCfg)

    /**
      *
      * @param msg
      * @param srcName
      * @param line
      * @param charPos
      * @param idl
      * @param origin IDL origin.
      * @param mdlCfg
      */
    private def mkRuntimeError(
        msg: String,
        srcName: String,
        line: Int, // 1, 2, ...
        charPos: Int, // 0, 1, 2, ...
        idl: String,
        origin: String,
        mdlCfg: NCModelConfig): String = mkError("runtime", msg, srcName, line, charPos, idl, origin, mdlCfg)

    /**
      *
      * @param kind
      * @param msg
      * @param srcName
      * @param line
      * @param charPos
      * @param idl
      * @param origin IDL origin.
      * @param mdlCfg
      */
    private def mkError(
        kind: String,
        msg: String,
        srcName: String,
        line: Int,
        charPos: Int,
        idl: String,
        origin: String,
        mdlCfg: NCModelConfig): String = {
        val idlLine = idl.split("\n")(line - 1)
        val hold = NCCompilerUtils.mkErrorHolder(idlLine, charPos)
        val aMsg = NCUtils.decapitalize(msg) match
            case s: String if s.last == '.' => s
            case s: String => s"$s."

        s"""IDL $kind error in '$srcName' at line $line - $aMsg
          |-- Model ID: ${mdlCfg.getId}
          |-- Model origin: ${mdlCfg.getOrigin}
          |-- Intent origin: $origin
          |--
          |-- Line:  ${hold.origStr}
          +-- Error: ${hold.ptrStr}"""
    }