Skip to content

Commit

Permalink
Implement support for named function refs for metaschema-framework#283
Browse files Browse the repository at this point in the history
In order to implement functions that look up names, arity, and other
details for Metapath functions, we must implement processing to support
named function references found from the tokenizer and lexer.
  • Loading branch information
aj-stein-gsa committed Dec 23, 2024
1 parent f457b9f commit 5f44dac
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import gov.nist.secauto.metaschema.core.configuration.IConfiguration;
import gov.nist.secauto.metaschema.core.configuration.IMutableConfiguration;
import gov.nist.secauto.metaschema.core.metapath.function.CalledContext;
import gov.nist.secauto.metaschema.core.metapath.function.IFunction;
import gov.nist.secauto.metaschema.core.metapath.function.IFunction.FunctionProperty;
import gov.nist.secauto.metaschema.core.metapath.item.ISequence;
import gov.nist.secauto.metaschema.core.metapath.item.node.IDocumentNodeItem;
Expand Down Expand Up @@ -279,6 +280,11 @@ public ISequence<?> getVariableValue(@NonNull IEnhancedQName name) {
return retval;
}

@NonNull
public IFunction getFunction(@NonNull IEnhancedQName name, int arity) {
return StaticContext.lookupFunction(name, arity);
}

/**
* Bind the variable {@code name} to the sequence {@code value}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,11 @@ public RESULT visitVariableReference(VariableReference expr, CONTEXT context) {
return visitChildren(expr, context);
}

@Override
public RESULT visitNamedFunctionReference(NamedFunctionReference expr, CONTEXT context) {
return visitChildren(expr, context);
}

@Override
public RESULT visitEmptySequence(EmptySequence<?> expr, CONTEXT context) {
return defaultResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import gov.nist.secauto.metaschema.core.metapath.StaticContext;
import gov.nist.secauto.metaschema.core.metapath.StaticMetapathException;
import gov.nist.secauto.metaschema.core.metapath.antlr.Metapath10;
import gov.nist.secauto.metaschema.core.metapath.antlr.Metapath10.EqnameContext;
import gov.nist.secauto.metaschema.core.metapath.antlr.Metapath10.ParamContext;
import gov.nist.secauto.metaschema.core.metapath.antlr.Metapath10Lexer;
import gov.nist.secauto.metaschema.core.metapath.cst.items.ArraySequenceConstructor;
Expand Down Expand Up @@ -393,7 +394,11 @@ protected IExpression handleFunctioncall(Metapath10.FunctioncallContext ctx) {

@Override
public IExpression visitNamedfunctionref(Metapath10.NamedfunctionrefContext ctx) {
throw new UnsupportedOperationException("expression not supported");
IEnhancedQName eqname =
getContext().parseVariableName(
ObjectUtils.notNull(ctx.eqname().getText()));
int arity = Integer.parseInt(ObjectUtils.notNull(ctx.IntegerLiteral().getText()));
return new NamedFunctionReference(eqname, arity);
}

// ==============================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,11 @@ public String visitLet(Let expr, State context) {
return appendNode(expr, super.visitLet(expr, context), context);
}

@Override
public String visitNamedFunctionReference(NamedFunctionReference expr, State context) {
return appendNode(expr, super.visitNamedFunctionReference(expr, context), context);
}

@Override
public String visitVariableReference(VariableReference expr, State context) {
return appendNode(expr, super.visitVariableReference(expr, context), context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,17 @@ public interface IExpressionVisitor<RESULT, CONTEXT> {
*/
RESULT visitVariableReference(@NonNull VariableReference expr, @NonNull CONTEXT context);

/**
* Visit the CST node.
*
* @param expr
* the CST node to visit
* @param context
* the processing context
* @return the visitation result or {@code null} if no result was produced
*/
RESULT visitNamedFunctionReference(@NonNull NamedFunctionReference expr, @NonNull CONTEXT context);

/**
* Visit the CST node.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/

package gov.nist.secauto.metaschema.core.metapath.cst;

import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
import gov.nist.secauto.metaschema.core.metapath.function.IFunction;
import gov.nist.secauto.metaschema.core.metapath.item.IItem;
import gov.nist.secauto.metaschema.core.metapath.item.ISequence;
import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
import gov.nist.secauto.metaschema.core.util.CollectionUtil;

import java.util.List;

import edu.umd.cs.findbugs.annotations.NonNull;

/**
* The CST node for a Metapath
* <a href="https://www.w3.org/TR/xpath-31/#id-named-function-ref">variable
* reference</a>.
*/
public class NamedFunctionReference implements IExpression {
@NonNull
private IEnhancedQName eqname;
@NonNull
private final int arity;

/**
* Construct a new Metapath variable reference CST node.
*
* @param name
* the variable name
*/
public NamedFunctionReference(@NonNull IEnhancedQName eqname, @NonNull int arity) {
this.eqname = eqname;
this.arity = arity;
}

/**
* Get the variable name.
*
* @return the variable name
*/
@NonNull
public IEnhancedQName getName() {
return eqname;
}

public int getArity() {
return arity;
}

@Override
public List<? extends IExpression> getChildren() {
return CollectionUtil.emptyList();
}

@SuppressWarnings("null")
@Override
public String toASTString() {
return String.format("%s[name=%s, arity=%d]", getClass().getName(), eqname, arity);
}

@Override
public <RESULT, CONTEXT> RESULT accept(IExpressionVisitor<RESULT, CONTEXT> visitor, CONTEXT context) {
return visitor.visitNamedFunctionReference(this, context);
}

@Override
public ISequence<? extends IItem> accept(DynamicContext dynamicContext, ISequence<?> focus) {
IFunction function = dynamicContext.getFunction(eqname, arity);
return ISequence.of(function);
}
}

0 comments on commit 5f44dac

Please sign in to comment.