public void handleDenseSubspace(List<ExpressionNode> nodes) {
        if (labels.size() < meta.mappedDims().size()) {
            throw new IllegalArgumentException("At " + address() + ": Missing label for dimension '" +
                                               meta.mappedDims().get(labels.size()) + "'");
        }
        if (! meta.type().hasIndexedDimensions()) {
            throw new IllegalArgumentException("At " + address() + ": Need a single value");
        }
        TensorType denseSubtype = meta.type().indexedSubtype();
        IndexedTensor.Indexes indexes = IndexedTensor.Indexes.of(denseSubtype, meta.indexedDims());
        if (indexes.size() != nodes.size()) {
            throw new IllegalArgumentException("At " + address() +
                                               ": Need " + indexes.size() +
                                               " values to fill a dense subspace of " + meta.type() +
                                               " but got " + nodes.size());
        }
        var addr = new TensorAddress.Builder(meta.type());
        for (int idx = 0; idx < labels.size(); idx++) {
            addr.add(meta.mappedDims().get(idx), labels.get(idx));
        }
        for (ExpressionNode node : nodes) {
            indexes.next();
            int indexedDimensionsIndex = 0;
            for (TensorType.Dimension dimension : meta.type().dimensions()) {
                if (dimension.isIndexed()) {
                    addr.add(dimension.name(), indexes.indexesForReading()[indexedDimensionsIndex++]);
                }
            }
            meta.receivingMap().put(addr.build(), TensorFunctionNode.wrapScalar(node));
        }
    }
Helper to incrementally build addresses and insert values (expression nodes) into a map.
Only used as an internal component of the RankingExpression parser.
@author arnej
searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/parser/CellMapHelper.java