This is an automated email from the ASF dual-hosted git repository.

aradzinski pushed a commit to branch NLPCRAFT-13
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/NLPCRAFT-13 by this push:
     new 85d47aa  WIP.
85d47aa is described below

commit 85d47aa4891ef3412e3ad97bef36735a341aa7c1
Author: Aaron Radzinzski <aradzin...@datalingvo.com>
AuthorDate: Mon Mar 23 03:40:11 2020 -0700

    WIP.
---
 .../apache/nlpcraft/examples/sql/SqlModel.scala    |  6 +-
 .../nlpcraft/examples/sql/db/SqlValueLoader.scala  |  9 +--
 .../scala/org/apache/nlpcraft/model/NCElement.java | 13 +++++
 .../scala/org/apache/nlpcraft/model/NCToken.java   |  2 +-
 .../model/tools/sqlgen/NCSqlAggregate.java         |  7 ++-
 .../nlpcraft/model/tools/sqlgen/NCSqlColumn.java   | 66 ++++++++++++++++++++--
 .../model/tools/sqlgen/NCSqlCondition.java         |  3 +
 .../model/tools/sqlgen/NCSqlDateRange.java         |  6 +-
 .../model/tools/sqlgen/NCSqlExtractor.java         | 28 ++++++---
 .../model/tools/sqlgen/NCSqlSchemaBuilder.java     |  9 ++-
 .../tools/sqlgen/impl/NCSqlExtractorImpl.scala     | 44 +++++++++------
 11 files changed, 146 insertions(+), 47 deletions(-)

diff --git a/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModel.scala 
b/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModel.scala
index ad4eead..5232364 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModel.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModel.scala
@@ -37,7 +37,7 @@ class SqlModel extends 
NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
 
         m.put("columns", res.columns.asJava)
         m.put("rows", res.rows.map(_.asJava).asJava)
-        // Added to result fo debug reasons.
+        // Added to result for debug reasons.
         m.put("sql", sql)
         m.put("parameters", params)
 
@@ -114,8 +114,8 @@ class SqlModel extends 
NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
         try {
             query =
                 SqlBuilder(SCHEMA).
-                    withTables(tabs.map(t ⇒ ext.extractTable(t)): _*).
-                    withColumns(cols.map(col ⇒ ext.extractColumn(col)): _*).
+                    withTables(tabs.map(ext.extractTable): _*).
+                    withColumns(cols.map(ext.extractColumn): _*).
                     withAndConditions(ext.extractInConditions(condVals: 
_*).asScala: _*).
                     withAndConditions(
                         condDates.map(t ⇒ extractColumnAndCondition(t, 
"nlpcraft:date")).flatMap(h ⇒
diff --git 
a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlValueLoader.scala 
b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlValueLoader.scala
index b8b673b..1b14539 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlValueLoader.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlValueLoader.scala
@@ -31,14 +31,11 @@ import scala.language.implicitConversions
  */
 class SqlValueLoader extends NCValueLoader with LazyLogging {
     override def load(e: NCElement): java.util.Set[NCValue] = {
-        if (!e.getGroups.contains("column"))
+        if (!e.isMemberOf("column"))
             throw new IllegalArgumentException(s"Unexpected element: 
${e.getId}")
 
-        val tab: String = e.meta("sql:tablename")
-        val col: String = e.meta("sql:name")
-
-        if (tab == null || col == null)
-            throw new IllegalArgumentException(s"Missed required metadata for 
element: ${e.getId}")
+        val tab: String = e.metax("sql:tablename")
+        val col: String = e.metax("sql:name")
 
         SqlAccess.select(new SqlQuery {
             override def getSql: String = s"SELECT $col FROM $tab WHERE $col 
IS NOT NULL"
diff --git a/src/main/scala/org/apache/nlpcraft/model/NCElement.java 
b/src/main/scala/org/apache/nlpcraft/model/NCElement.java
index d853ea5..880ee33 100644
--- a/src/main/scala/org/apache/nlpcraft/model/NCElement.java
+++ b/src/main/scala/org/apache/nlpcraft/model/NCElement.java
@@ -113,6 +113,19 @@ public interface NCElement extends NCMetadata, 
Serializable {
     }
 
     /**
+     * Shortcut method to test if this element is a member of given group. It 
is equivalent to:
+     * <pre class="brush: java">
+     *     return getGroups().contains(grp);
+     * </pre>
+     *
+     * @param grp Token group to test.
+     * @return {@code True} if this element belongs to the given group, {@code 
false} otherwise.
+     */
+    default boolean isMemberOf(String grp) {
+        return getGroups().contains(grp);
+    }
+
+    /**
      * Gets optional user-defined element's metadata. When a {@link NCToken 
token} for this element
      * is detected in the input this metadata is merged into {@link 
NCToken#getMetadata()} method returned metadata.
      * <p>
diff --git a/src/main/scala/org/apache/nlpcraft/model/NCToken.java 
b/src/main/scala/org/apache/nlpcraft/model/NCToken.java
index 9b59723..2b97664 100644
--- a/src/main/scala/org/apache/nlpcraft/model/NCToken.java
+++ b/src/main/scala/org/apache/nlpcraft/model/NCToken.java
@@ -201,7 +201,7 @@ public interface NCToken extends NCMetadata {
      * @param grp Group to test.
      * @return <code>True</code> if this token belongs to the group 
<code>grp</code>, {@code false} otherwise.
      */
-    default boolean isOfGroup(String grp) {
+    default boolean isMemberOf(String grp) {
         return getGroups().contains(grp);
     }
 
diff --git 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlAggregate.java 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlAggregate.java
index 71b0446..7cb44b8 100644
--- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlAggregate.java
+++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlAggregate.java
@@ -18,12 +18,15 @@
 package org.apache.nlpcraft.model.tools.sqlgen;
 
 import org.apache.nlpcraft.model.*;
-import java.util.List;
+import java.util.*;
 
 /**
- * Object presentation of SQL aggregate.
+ * Object presentation of SQL aggregate. You can get an instance of this 
interface by
+ * using {@link NCSqlExtractor#extractAggregate(NCToken, NCToken)} method.
  *
  * @see NCSqlSchemaBuilder#makeSchema(NCModel)
+ * @see NCSqlExtractorBuilder#build(NCSqlSchema, NCVariant)
+ * @see NCSqlExtractor#extractAggregate(NCToken, NCToken)
  */
 public interface NCSqlAggregate {
     /**
diff --git 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlColumn.java 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlColumn.java
index 2b4d0fb..3968bb3 100644
--- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlColumn.java
+++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlColumn.java
@@ -21,8 +21,42 @@ import org.apache.nlpcraft.model.*;
 
 /**
  * Object presentation of SQL column.
+ * <p>
+ * In JSON/YAML generated model SQL column is represented by the model element 
(example):
+ * <pre class="brush: js">
+ *   elements:
+ *     - id: "col:orders_customer_id"
+ *     groups:
+ *     - "column"
+ *     synonyms:
+ *     - "{customer_id|customer &lt;ID&gt;}"
+ *     - "orders {customer_id|customer &lt;ID&gt;}"
+ *     - "{customer_id|customer &lt;ID&gt;} &lt;OF&gt; orders"
+ *     metadata:
+ *       sql:name: "customer_id"
+ *       sql:tablename: "orders"
+ *       sql:datatype: 12
+ *       sql:isnullable: true
+ *       sql:ispk: false
+ *     description: "Auto-generated from 'orders.customer_id' column."
+ *     valueLoader: "org.apache.nlpcraft.examples.sql.db.SqlValueLoader"
+ * </pre>
+ * Few notes:
+ * <ul>
+ *     <li>All model elements representing SQL column have ID in a form of 
<code>col:sql_table_name</code>.</li>
+ *     <li>All model elements representing SQL column belong to 
<code>column</code> group.</li>
+ *     <li>
+ *         These model elements have auto-generated synonyms and set of 
mandatory metadata.
+ *     </li>
+ *     <li>
+ *         User can freely add group membership, change synonyms, add new 
metadata, add or change value loader.
+ *     </li>
+ * </ul>
  *
  * @see NCSqlSchemaBuilder#makeSchema(NCModel)
+ * @see NCSqlExtractorBuilder#build(NCSqlSchema, NCVariant) 
+ * @see NCSqlExtractor#extractColumn(NCToken)
+ * @see NCSqlTable#getColumns() 
  */
 public interface NCSqlColumn {
     /**
@@ -31,9 +65,7 @@ public interface NCSqlColumn {
      * In JSON/YAML generated model the table name is declared with the 
following element
      * metadata (example):
      * <pre class="brush: js">
-     *     sql:extratables:
-     *     - "other_part_table"
-     *     - "another_part_table"
+     *     sql:tablename: "customer_id"
      * </pre>
      *
      * @return Name of the table this column belongs to.
@@ -41,7 +73,13 @@ public interface NCSqlColumn {
     String getTable();
 
     /**
-     * Gets name of this column.
+     * Gets native name of this column.
+     * <p>
+     * In JSON/YAML generated model the native column name is declared with 
the following element
+     * metadata (example):
+     * <pre class="brush: js">
+     *     sql:name: "customer_id"
+     * </pre>
      *
      * @return Name of this column.
      */
@@ -50,6 +88,12 @@ public interface NCSqlColumn {
     /**
      * Gets JDBC <a target="new" 
href="https://docs.oracle.com/javase/8/docs/api/java/sql/Types.html";>data 
type</a>
      * for this column.
+     * <p>
+     * In JSON/YAML generated model the data type is declared with the 
following element
+     * metadata (example):
+     * <pre class="brush: js">
+     *     sql:datatype: 12
+     * </pre>
      *
      * @return JDBC <a target="new" 
href="https://docs.oracle.com/javase/8/docs/api/java/sql/Types.html";>data 
type</a>
      *      for this column.
@@ -58,13 +102,25 @@ public interface NCSqlColumn {
 
     /**
      * Tests whether or not this column is a primary key column.
-     * 
+     * <p>
+     * In JSON/YAML generated model the primary key flag is declared with the 
following element
+     * metadata (example):
+     * <pre class="brush: js">
+     *     sql:ispk: false
+     * </pre>
+     *
      * @return Whether or not this column is a primary key column.
      */
     boolean isPk();
 
     /**
      * Tests whether or not this column is nullable.
+     * <p>
+     * In JSON/YAML generated model the nullable flag is declared with the 
following element
+     * metadata (example):
+     * <pre class="brush: js">
+     *     sql:isnullable: false
+     * </pre>
      *
      * @return Whether or not this column is nullable.
      */
diff --git 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlCondition.java 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlCondition.java
index 2b90f61..f0f4490 100644
--- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlCondition.java
+++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlCondition.java
@@ -23,6 +23,9 @@ import org.apache.nlpcraft.model.*;
  * Object presentation of the base SQL condition.
  *
  * @see NCSqlSchemaBuilder#makeSchema(NCModel)
+ * @see NCSqlExtractorBuilder#build(NCSqlSchema, NCVariant)
+ * @see NCSqlInCondition
+ * @see NCSqlSimpleCondition
  */
 public interface NCSqlCondition {
     /**
diff --git 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlDateRange.java 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlDateRange.java
index c214d24..660fc4b 100644
--- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlDateRange.java
+++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlDateRange.java
@@ -24,19 +24,21 @@ import java.sql.Timestamp;
  * Object presentation of SQL date range.
  *
  * @see NCSqlSchemaBuilder#makeSchema(NCModel)
+ * @see NCSqlExtractorBuilder#build(NCSqlSchema, NCVariant)
+ * @see NCSqlExtractor#extractDateRange(NCToken) 
  */
 public interface NCSqlDateRange {
     /**
      * Gets 'from' timestamp.
      *
-     * @return From timestamp.
+     * @return The 'from' timestamp.
      */
     Timestamp getFrom();
 
     /**
      * Gets 'to' timestamp.
      *
-     * @return To timestamp.
+     * @return The 'to' timestamp.
      */
     Timestamp getTo();
 }
diff --git 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractor.java 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractor.java
index 1c74e31..20c5262 100644
--- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractor.java
+++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractor.java
@@ -27,7 +27,10 @@ import java.util.*;
  * <p>
  * Note that {@link NCSqlExtractorBuilder} builder requires {@link 
NCSqlSchema} and {@link NCVariant}
  * objects when creating an instance of SQL extractor. Many methods in this 
interface will search
- * that parsing variant ans schema to find necessary referenced tokens.
+ * that parsing variant and schema to find necessary referenced tokens.
+ * <p>
+ * Note also that wherever necessary the implementation will scan part 
(constituent) tokens as well
+ * (see {@link NCToken#findPartTokens(String...)} for more information).
  *
  * @see NCSqlExtractorBuilder
  */
@@ -42,29 +45,38 @@ public interface NCSqlExtractor {
     NCSqlLimit extractLimit(NCToken limitTok);
 
     /**
-     * Extracts date range conditions object from given tokens.
+     * Extracts date range conditions object from given tokens. Result list 
will have multiple conditions that
+     * all will have to be AND-combined to make <code>colTok</code> to be 
within a date range
+     * defined by <code>dateTok</code> parameter.
      *
      * @param colTok Token representing detected SQL column (i.e. detected 
model element that belongs
      *      to <code>column</code> group).
      * @param dateTok Date range token with ID <code>nlpcraft:date</code>.
-     * @return List of date range conditions extracted from given parameters.
+     * @return List of conditions extracted from given parameters that have to 
be AND-combined.
      * @throws NCException Thrown in case of any errors.
      */
     List<NCSqlSimpleCondition> extractDateRangeConditions(NCToken colTok, 
NCToken dateTok);
 
     /**
+     * Extracts numeric conditions object from given tokens. Result list will 
have multiple conditions that
+     * all will have to be AND-combined to make <code>colTok</code> act as an 
operand to the numeric
+     * condition defined by <code>numTok</code> parameter.
      *
-     * @param colTok
-     * @param numTok
-     * @return
+     * @param colTok Token representing detected SQL column (i.e. detected 
model element that belongs
+     *      to <code>column</code> group).
+     * @param numTok Numeric token with ID <code>nlpcraft:num</code>. This 
token provides numeric value
+     *      as well as type of logical condition on that numeric value.
+     * @return List of conditions extracted from given parameters that have to 
be AND-combined.
      * @throws NCException Thrown in case of any errors.
      */
     List<NCSqlSimpleCondition> extractNumConditions(NCToken colTok, NCToken 
numTok);
 
     /**
      *
-     * @param valToks
-     * @return
+     * @param valToks Zero or more tokens representing values for the SQL IN 
condition. Note that only
+     *      those token that have non-{@code null} values (see {@link 
NCToken#getValue()} method) will
+     *      be used in the result conditions.
+     * @return List of conditions extracted from given parameters that have to 
be AND-combined.
      * @throws NCException Thrown in case of any errors.
      */
     List<NCSqlInCondition> extractInConditions(NCToken... valToks);
diff --git 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java
index 7321959..86b8db4 100644
--- 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java
+++ 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java
@@ -22,20 +22,23 @@ import org.apache.nlpcraft.model.*;
 import org.apache.nlpcraft.model.tools.sqlgen.impl.*;
 
 /**
- * Builder for {@link NCSqlSchema} instances.
+ * Builder for {@link NCSqlSchema} instances. Once you have {@link NCSqlSchema}
+ * you can also use utility methods from {@link NCSqlExtractor}.
  *
  * @see NCSqlModelGenerator
  * @see NCSqlExtractor
  */
 public class NCSqlSchemaBuilder {
     /**
-     * Builds object presentation for SQL schema from given data model.
+     * Builds object presentation for SQL schema from given data model. Note 
that the model must be
+     * generated by {@link NCSqlModelGenerator} class.
      *
-     * @param model Data model to generate object SQL schema presentation. 
Note that the model must be
+     * @param model Data model to generate object SQL schema presentation. 
Data model must be
      *      generated by {@link NCSqlModelGenerator} class.
      * @return Object presentation of the SQL schema for a given data model.
      * @throws NCException Thrown in case of any errors.
      * @see NCSqlModelGenerator
+     * @see NCSqlExtractor
      */
     public static NCSqlSchema makeSchema(NCModel model) {
         return NCSqlSchemaBuilderImpl.makeSchema(model);
diff --git 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala
 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala
index 7956554..2eb470d 100644
--- 
a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala
+++ 
b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala
@@ -48,7 +48,7 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
       * @param grp
       */
     private def checkGroup(tok: NCToken, grp: String): Unit =
-        if (!tok.isOfGroup(grp))
+        if (!tok.isMemberOf(grp))
             throw new NCException(s"Token does not belong to the group '$grp': 
$tok")
     
     /**
@@ -72,11 +72,19 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
     /**
       *
       * @param tok
-      * @param group
       * @return
       */
-    private def getWithGroup(tok: NCToken, group: String): Seq[NCToken] =
-        (Seq(tok) ++ tok.findPartTokens().asScala).flatMap(p ⇒ if 
(p.getGroups.contains(group)) Some(p) else None)
+    private def tree(tok: NCToken): Seq[NCToken] =
+        Seq(tok) ++ tok.findPartTokens().asScala
+    
+    /**
+      *
+      * @param tok
+      * @param grp
+      * @return
+      */
+    private def getWithGroup(tok: NCToken, grp: String): Seq[NCToken] =
+        tree(tok).flatMap(p ⇒ if (p.getGroups.contains(grp)) Some(p) else None)
     
     /**
       *
@@ -114,7 +122,7 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
       * @return
       */
     private def getReference(refTok: NCToken): Option[NCSqlColumn] = {
-        val tok = getLinkBySingleIndex(variant.asScala, refTok)
+        val tok = getLinkBySingleIndex(variant, refTok)
         
         findAnyColumnTokenOpt(tok) match {
             // If reference is column - sort by column.
@@ -167,12 +175,11 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
         val col = extractColumn(colTok)
         val range = extractDateRange(dateTok)
         
-        val seq: Seq[NCSqlSimpleCondition] = Seq(
+        Seq[NCSqlSimpleCondition](
             NCSqlSimpleConditionImpl(col, ">=", range.getFrom),
             NCSqlSimpleConditionImpl(col, "<=", range.getTo)
         )
-        
-        seq.asJava
+        .asJava
     }
     
     /**
@@ -227,14 +234,14 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
       */
     override def extractInConditions(allValsToks: NCToken*): 
util.List[NCSqlInCondition] = {
         allValsToks.map(tok ⇒ {
-            val valToks = (Seq(tok) ++ 
tok.findPartTokens().asScala).filter(_.getValue != null)
+            val valToks = tree(tok).filter(_.getValue != null)
             
             val valTok =
                 valToks.size match {
                     case 1 ⇒ valToks.head
                     
-                    case 0 ⇒ throw new NCException(s"Values column not found 
for token: $tok")
-                    case _ ⇒ throw new NCException(s"Too many values columns 
found token: $tok")
+                    case 0 ⇒ throw new NCException(s"Values column not found 
for: $tok")
+                    case _ ⇒ throw new NCException(s"Too many values columns 
found for: $tok")
                 }
             
             extractColumn(valTok) → valTok.getValue
@@ -277,7 +284,7 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
             case _ ⇒
                 Seq(
                     NCSqlFunctionImpl(
-                        
extractColumn(findAnyColumnToken(getLinkBySingleIndex(variant.asScala, 
aggrFun))),
+                        
extractColumn(findAnyColumnToken(getLinkBySingleIndex(variant, aggrFun))),
                         aggrFun.meta(s"${aggrFun.getId}:type")
                     )
                 )
@@ -287,7 +294,7 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
         val grpBy = aggrGrpTok match {
             case null ⇒ Seq.empty
             case aggrGrp ⇒
-                val grpTok = getLinkBySingleIndex(variant.asScala, aggrGrp)
+                val grpTok = getLinkBySingleIndex(variant, aggrGrp)
             
                 // If reference is column - group by column.
                 findAnyColumnTokenOpt(grpTok) match {
@@ -354,15 +361,18 @@ class NCSqlExtractorImpl(schema: NCSqlSchema, variant: 
NCVariant) extends NCSqlE
       * @param tok
       * @return
       */
-    private def getLinkBySingleIndex(variant: Seq[NCToken], tok: NCToken): 
NCToken = {
+    private def getLinkBySingleIndex(variant: NCVariant, tok: NCToken): 
NCToken = {
         val idxs: util.List[Integer] = tok.metax(s"${tok.getId}:indexes")
+        
+        if (idxs.isEmpty)
+            throw new NCException(s"Empty indexes for: $tok")
 
-        val idx = idxs.asScala.head
+        val idx = idxs.get(0)
 
-        if (idx < variant.length) {
+        if (idx < variant.size) {
             val note: String = tok.metax(s"${tok.getId}:note")
 
-            val link = variant(idx)
+            val link = variant.get(idx)
 
             if (link.getId != note)
                 throw new NCException(s"Unexpected token with index: $idx, 
type: $note")

Reply via email to