From f20062d98b7bfdf5e6f29810a8cdcd1f2eb38e11 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 25 Dec 2019 12:12:54 +0100 Subject: [PATCH] Rework LeafRefValidation This reworks LeafRefValidation in terms of interpreting XPathExpression via exposed parsed steps. This allows us to eliminate a chunk of parsing code, speeding the initialization process up. QNamePredicateImpl/AbstractQNameWithPredicate are losing their Serializable trait, as it is not really useful and tickles SpotBugs unnecessarily. JIRA: YANGTOOLS-1051 Change-Id: I502f54052ca8bb10e6595f41ba7aca6cef9550ce Signed-off-by: Robert Varga --- yang/yang-data-impl/pom.xml | 21 +- .../data/impl/leafref/LeafRefPathLexer.g4 | 16 -- .../data/impl/leafref/LeafRefPathParser.g4 | 30 --- .../leafref/AbstractQNameWithPredicate.java | 5 +- .../impl/leafref/LeafRefContextBuilder.java | 4 +- .../leafref/LeafRefContextTreeBuilder.java | 31 +-- .../leafref/LeafRefPathErrorListener.java | 67 ------ .../impl/leafref/LeafRefPathParserImpl.java | 191 +++++++++++++++--- .../LeafRefPathParserListenerImpl.java | 186 ----------------- .../LeafRefPathSyntaxErrorException.java | 23 --- .../data/impl/leafref/QNamePredicateImpl.java | 5 +- .../impl/leafref/QNameWithPredicateImpl.java | 3 - .../leafref/SimpleQNameWithPredicate.java | 2 - 13 files changed, 171 insertions(+), 413 deletions(-) delete mode 100644 yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathLexer.g4 delete mode 100644 yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParser.g4 delete mode 100644 yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathErrorListener.java delete mode 100644 yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserListenerImpl.java delete mode 100644 yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathSyntaxErrorException.java diff --git a/yang/yang-data-impl/pom.xml b/yang/yang-data-impl/pom.xml index 2c094a4531..1b0856bc7f 100644 --- a/yang/yang-data-impl/pom.xml +++ b/yang/yang-data-impl/pom.xml @@ -19,27 +19,12 @@ ${project.artifactId} - + false - - org.antlr - antlr4-maven-plugin - - - - antlr4 - - - - - true - true - - org.apache.felix maven-bundle-plugin @@ -96,10 +81,6 @@ com.google.guava guava - - org.antlr - antlr4-runtime - javax.xml.bind jaxb-api diff --git a/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathLexer.g4 b/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathLexer.g4 deleted file mode 100644 index 3d63ee9eea..0000000000 --- a/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathLexer.g4 +++ /dev/null @@ -1,16 +0,0 @@ -lexer grammar LeafRefPathLexer; - -COLON : ':' ; -SLASH : '/' ; -DOTS : '..' ; -EQUAL : '=' ; -LEFT_SQUARE_BRACKET : '[' ; -RIGHT_SQUARE_BRACKET : ']' ; -LEFT_PARENTHESIS : '(' ; -RIGHT_PARENTHESIS : ')' ; - -CURRENT_KEYWORD : 'current'; - -SEP: [ \n\r\t]+ ; -IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_\-.]*; - diff --git a/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParser.g4 b/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParser.g4 deleted file mode 100644 index 1ae7f9ef67..0000000000 --- a/yang/yang-data-impl/src/main/antlr4/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParser.g4 +++ /dev/null @@ -1,30 +0,0 @@ -parser grammar LeafRefPathParser; - -options { - tokenVocab = LeafRefPathLexer; -} - -path_arg : (absolute_path | relative_path) EOF; - -absolute_path : (SLASH node_identifier (path_predicate)*)+; - -relative_path : (DOTS SLASH)* descendant_path; - -descendant_path : node_identifier ((path_predicate)* absolute_path)?; - -path_predicate : LEFT_SQUARE_BRACKET SEP? path_equality_expr SEP? RIGHT_SQUARE_BRACKET; - -path_equality_expr : node_identifier SEP? EQUAL SEP? path_key_expr; - -path_key_expr : current_function_invocation SEP? SLASH SEP? rel_path_keyexpr; - -rel_path_keyexpr : (DOTS SEP? SLASH SEP?)* (node_identifier SEP? SLASH SEP?)* node_identifier; - -node_identifier : (prefix COLON)? identifier; - -current_function_invocation : CURRENT_KEYWORD SEP? LEFT_PARENTHESIS SEP? RIGHT_PARENTHESIS; - -prefix : identifier; - -identifier: IDENTIFIER | CURRENT_KEYWORD; - diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/AbstractQNameWithPredicate.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/AbstractQNameWithPredicate.java index 3c76548dee..0228cf71c9 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/AbstractQNameWithPredicate.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/AbstractQNameWithPredicate.java @@ -7,16 +7,13 @@ */ package org.opendaylight.yangtools.yang.data.impl.leafref; -import java.io.Serializable; import java.util.Objects; import java.util.Optional; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.Revision; -abstract class AbstractQNameWithPredicate implements Immutable, Serializable, QNameWithPredicate { - private static final long serialVersionUID = 1L; - +abstract class AbstractQNameWithPredicate implements Immutable, QNameWithPredicate { @Override public final boolean equals(final Object obj) { if (this == obj) { diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextBuilder.java index 47e9a6152a..b8036a474c 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextBuilder.java @@ -97,7 +97,7 @@ final class LeafRefContextBuilder implements Builder { } void setLeafRefTargetPath(final LeafRefPath leafRefPath) { - this.leafRefTargetPath = leafRefPath; + this.leafRefTargetPath = requireNonNull(leafRefPath); } String getLeafRefTargetPathString() { @@ -105,7 +105,7 @@ final class LeafRefContextBuilder implements Builder { } void setLeafRefTargetPathString(final String leafRefPathString) { - this.leafRefTargetPathString = leafRefPathString; + this.leafRefTargetPathString = requireNonNull(leafRefPathString); } QName getCurrentNodeQName() { diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextTreeBuilder.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextTreeBuilder.java index 19271b9841..08fb284f6f 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextTreeBuilder.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefContextTreeBuilder.java @@ -7,8 +7,6 @@ */ package org.opendaylight.yangtools.yang.data.impl.leafref; -import static com.google.common.base.Preconditions.checkNotNull; - import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -20,6 +18,7 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.PathExpression; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode; @@ -64,8 +63,7 @@ final class LeafRefContextTreeBuilder { return rootBuilder.build(); } - private LeafRefContext buildLeafRefContextReferencingTree(final DataSchemaNode node, final Module currentModule) - throws LeafRefYangSyntaxErrorException { + private LeafRefContext buildLeafRefContextReferencingTree(final DataSchemaNode node, final Module currentModule) { final LeafRefContextBuilder currentLeafRefContextBuilder = new LeafRefContextBuilder(node.getQName(), node.getPath(), schemaContext); @@ -88,18 +86,17 @@ final class LeafRefContextTreeBuilder { } } else if (node instanceof TypedDataSchemaNode) { - final TypeDefinition type = ((TypedDataSchemaNode) node).getType(); + final TypedDataSchemaNode typedNode = (TypedDataSchemaNode) node; + final TypeDefinition type = typedNode.getType(); // FIXME: fix case when type is e.g. typedef -> typedef -> leafref if (type instanceof LeafrefTypeDefinition) { final LeafrefTypeDefinition leafrefType = (LeafrefTypeDefinition) type; - final String leafRefPathString = leafrefType.getPathStatement().getOriginalString(); - final LeafRefPathParserImpl leafRefPathParser = new LeafRefPathParserImpl(schemaContext, - checkNotNull(getBaseTypeModule(leafrefType), "Unable to find base module for leafref %s", node), - node); - final LeafRefPath leafRefPath = leafRefPathParser.parseLeafRefPath(leafRefPathString); + final PathExpression path = leafrefType.getPathStatement(); + final LeafRefPathParserImpl leafRefPathParser = new LeafRefPathParserImpl(leafrefType, typedNode); + final LeafRefPath leafRefPath = leafRefPathParser.parseLeafRefPath(path); - currentLeafRefContextBuilder.setLeafRefTargetPathString(leafRefPathString); + currentLeafRefContextBuilder.setLeafRefTargetPathString(path.getOriginalString()); currentLeafRefContextBuilder.setReferencing(true); currentLeafRefContextBuilder.setLeafRefTargetPath(leafRefPath); @@ -112,18 +109,6 @@ final class LeafRefContextTreeBuilder { return currentLeafRefContextBuilder.build(); } - private Module getBaseTypeModule(final LeafrefTypeDefinition leafrefType) { - /* - * Find the first definition of supplied leafref type and return the - * module which contains this definition. - */ - LeafrefTypeDefinition baseLeafRefType = leafrefType; - while (baseLeafRefType.getBaseType() != null) { - baseLeafRefType = baseLeafRefType.getBaseType(); - } - return schemaContext.findModule(baseLeafRefType.getQName().getModule()).orElse(null); - } - private LeafRefContext buildLeafRefContextReferencedByTree(final DataSchemaNode node, final Module currentModule) throws LeafRefYangSyntaxErrorException { final LeafRefContextBuilder currentLeafRefContextBuilder = new LeafRefContextBuilder(node.getQName(), diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathErrorListener.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathErrorListener.java deleted file mode 100644 index 59476496cc..0000000000 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathErrorListener.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.yang.data.impl.leafref; - -import java.util.ArrayList; -import java.util.List; -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -class LeafRefPathErrorListener extends BaseErrorListener { - private static final Logger LOG = LoggerFactory.getLogger(LeafRefPathErrorListener.class); - - private final List exceptions = new ArrayList<>(1); - private final Module module; - - LeafRefPathErrorListener(final Module module) { - this.module = module; - } - - @Override - @SuppressWarnings("checkstyle:parameterName") - public void syntaxError(final Recognizer recognizer, final Object offendingSymbol, final int line, - final int charPositionInLine, final String msg, final RecognitionException e) { - LOG.debug("Syntax error in module {} at {}:{}: {}", module.getName(), line, charPositionInLine, msg, e); - - exceptions.add(new LeafRefPathSyntaxErrorException(module.getName(), line, charPositionInLine, msg, e)); - } - - public void validate() throws LeafRefPathSyntaxErrorException { - if (exceptions.isEmpty()) { - return; - } - - // Single exception: just throw it - if (exceptions.size() == 1) { - throw exceptions.get(0); - } - - final StringBuilder sb = new StringBuilder(); - String exceptionModule = null; - boolean first = true; - for (final LeafRefPathSyntaxErrorException e : exceptions) { - if (exceptionModule == null) { - exceptionModule = e.getModule(); - } - if (first) { - first = false; - } else { - sb.append('\n'); - } - - sb.append(e.getFormattedMessage()); - } - - throw new LeafRefPathSyntaxErrorException(exceptionModule, 0, 0, sb.toString()); - } - -} diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java index d781984325..2e763958b7 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserImpl.java @@ -7,48 +7,173 @@ */ package org.opendaylight.yangtools.yang.data.impl.leafref; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_argContext; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.collect.ImmutableList; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Set; +import org.opendaylight.yangtools.yang.common.AbstractQName; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.UnqualifiedQName; +import org.opendaylight.yangtools.yang.model.api.PathExpression; +import org.opendaylight.yangtools.yang.model.api.PathExpression.DerefSteps; +import org.opendaylight.yangtools.yang.model.api.PathExpression.LocationPathSteps; +import org.opendaylight.yangtools.yang.model.api.PathExpression.Steps; +import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition; +import org.opendaylight.yangtools.yang.xpath.api.YangBinaryExpr; +import org.opendaylight.yangtools.yang.xpath.api.YangBinaryOperator; +import org.opendaylight.yangtools.yang.xpath.api.YangExpr; +import org.opendaylight.yangtools.yang.xpath.api.YangFunction; +import org.opendaylight.yangtools.yang.xpath.api.YangFunctionCallExpr; +import org.opendaylight.yangtools.yang.xpath.api.YangLocationPath; +import org.opendaylight.yangtools.yang.xpath.api.YangLocationPath.QNameStep; +import org.opendaylight.yangtools.yang.xpath.api.YangLocationPath.Relative; +import org.opendaylight.yangtools.yang.xpath.api.YangLocationPath.Step; +import org.opendaylight.yangtools.yang.xpath.api.YangPathExpr; +import org.opendaylight.yangtools.yang.xpath.api.YangQNameExpr; final class LeafRefPathParserImpl { - private final SchemaContext schemaContext; - private final Module module; - private final SchemaNode node; - - LeafRefPathParserImpl(final SchemaContext schemaContext, final Module currentModule, final SchemaNode currentNode) { - this.schemaContext = schemaContext; - this.module = currentModule; - this.node = currentNode; + private final QNameModule leafrefModule; + private final QNameModule nodeModule; + + LeafRefPathParserImpl(final LeafrefTypeDefinition leafrefType, final TypedDataSchemaNode currentNode) { + // FIXME: these two namespaces look not quite right: + // - leafrefModule is used for absolute paths, irrespective of where they occur + // - nodeModule is used for relative paths, irrespective of where they occur + // + // There is little in RFC7950 which would hint at such a distinction and if even if it were true, it would be + // the job of YANG parser to ensure that absolute paths are bound during parsing. + // + // The only distinction is relative to where the leafref is defined, namely: + // + // 1) as per section 9.9.2: + // o If the "path" statement is defined within a typedef, the context + // node is the leaf or leaf-list node in the data tree that + // references the typedef. + // + // o Otherwise, the context node is the node in the data tree for which + // the "path" statement is defined. + // + // 2) as per section 6.4.1: + // o Names without a namespace prefix belong to the same namespace as + // the identifier of the current node. Inside a grouping, that + // namespace is affected by where the grouping is used (see + // Section 7.13). Inside a typedef, that namespace is affected by + // where the typedef is referenced. If a typedef is defined and + // referenced within a grouping, the namespace is affected by where + // the grouping is used (see Section 7.13). + this.leafrefModule = getBaseModule(leafrefType); + this.nodeModule = currentNode.getQName().getModule(); } - LeafRefPath parseLeafRefPath(final String path) throws LeafRefYangSyntaxErrorException { - final Path_argContext pathCtx = parseLeafRefPathSource(path); + LeafRefPath parseLeafRefPath(final PathExpression path) { + final Steps steps = path.getSteps(); + if (steps instanceof LocationPathSteps) { + return parseLocationPath(((LocationPathSteps) steps).getLocationPath()); + } else if (steps instanceof DerefSteps) { + throw new UnsupportedOperationException("deref() leafrefs are not implemented yet"); + } else { + throw new IllegalStateException("Unsupported steps " + steps); + } + } - final ParseTreeWalker walker = new ParseTreeWalker(); - final LeafRefPathParserListenerImpl leafRefPathParserListenerImpl = new LeafRefPathParserListenerImpl( - schemaContext, module, node); - walker.walk(leafRefPathParserListenerImpl, pathCtx); + private LeafRefPath parseLocationPath(final YangLocationPath locationPath) { + return LeafRefPath.create( + createPathSteps(locationPath.isAbsolute() ? leafrefModule : nodeModule, locationPath.getSteps()), + locationPath.isAbsolute()); + } - return leafRefPathParserListenerImpl.getLeafRefPath(); + private static Deque createPathSteps(final QNameModule localModule, + final ImmutableList steps) { + final Deque path = new ArrayDeque<>(steps.size()); + for (Step step : steps) { + switch (step.getAxis()) { + case CHILD: + checkState(step instanceof QNameStep, "Unsupported step %s", step); + path.add(adaptChildStep((QNameStep) step, localModule)); + break; + case PARENT: + path.add(QNameWithPredicate.UP_PARENT); + break; + default: + throw new IllegalStateException("Unsupported axis in step " + step); + } + } + return path; } - private Path_argContext parseLeafRefPathSource(final String path) throws LeafRefYangSyntaxErrorException { - final LeafRefPathLexer lexer = new LeafRefPathLexer(CharStreams.fromString(path)); - final LeafRefPathParser parser = new LeafRefPathParser(new CommonTokenStream(lexer)); + private static QNameWithPredicate adaptChildStep(final QNameStep step, final QNameModule localModule) { + final QName qname = resolve(step.getQName(), localModule); + final Set predicates = step.getPredicates(); + if (predicates.isEmpty()) { + return new SimpleQNameWithPredicate(qname); + } + + final QNameWithPredicateBuilder builder = new QNameWithPredicateBuilder(qname.getModule(), + qname.getLocalName()); + + for (YangExpr pred : predicates) { + final QNamePredicateBuilder predBuilder = new QNamePredicateBuilder(); + + if (pred instanceof YangBinaryExpr) { + final YangBinaryExpr eqPred = (YangBinaryExpr) pred; + checkState(eqPred.getOperator() == YangBinaryOperator.EQUALS); - final LeafRefPathErrorListener errorListener = new LeafRefPathErrorListener(module); - lexer.removeErrorListeners(); - lexer.addErrorListener(errorListener); - parser.removeErrorListeners(); - parser.addErrorListener(errorListener); + final YangExpr left = eqPred.getLeftExpr(); + checkState(left instanceof YangQNameExpr, "Unsupported left expression %s", left); + predBuilder.setIdentifier(resolve(((YangQNameExpr) left).getQName(), localModule)); + + final YangExpr right = eqPred.getRightExpr(); + if (right instanceof YangPathExpr) { + final YangPathExpr rightPath = (YangPathExpr) right; + final YangExpr filter = rightPath.getFilterExpr(); + if (filter instanceof YangFunctionCallExpr) { + checkState(YangFunction.CURRENT.getIdentifier().equals( + ((YangFunctionCallExpr) filter).getName())); + } else { + throw new IllegalStateException("Unhandled filter " + filter); + } + + final Relative location = rightPath.getLocationPath() + .orElseThrow(() -> new IllegalStateException("Missing locationPath in " + rightPath)); + predBuilder.setPathKeyExpression(LeafRefPath.create( + createPathSteps(localModule, location.getSteps()), false)); + } else { + throw new UnsupportedOperationException("Not implemented for " + right); + } + } + + builder.addQNamePredicate(predBuilder.build()); + } + + return builder.build(); + } + + private static QName resolve(final AbstractQName qname, final QNameModule localModule) { + if (qname instanceof QName) { + return (QName) qname; + } else if (qname instanceof UnqualifiedQName) { + // Bind to namespace. Note we expect to perform frequent matching, hence we are interning the result + return ((UnqualifiedQName) qname).bindTo(localModule).intern(); + } else { + throw new IllegalStateException("Unhandled unresolved QName " + qname); + } + } - final Path_argContext result = parser.path_arg(); - errorListener.validate(); - return result; + /** + * Find the first definition of supplied leafref type and return the module which contains this definition. + */ + private static QNameModule getBaseModule(final LeafrefTypeDefinition leafrefType) { + LeafrefTypeDefinition current = leafrefType; + while (true) { + final LeafrefTypeDefinition base = current.getBaseType(); + if (base == null) { + return current.getQName().getModule(); + } + current = base; + } } } diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserListenerImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserListenerImpl.java deleted file mode 100644 index 078abd2067..0000000000 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathParserListenerImpl.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.yang.data.impl.leafref; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.collect.Lists; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import org.antlr.v4.runtime.tree.TerminalNode; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.common.Revision; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.IdentifierContext; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Node_identifierContext; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_argContext; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_equality_exprContext; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_predicateContext; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.PrefixContext; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Rel_path_keyexprContext; -import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Relative_pathContext; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.ModuleImport; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; - -final class LeafRefPathParserListenerImpl extends LeafRefPathParserBaseListener { - - private final List leafRefPathQnameList = new ArrayList<>(); - private final SchemaContext schemaContext; - private final Module module; - private final Module leafrefModule; - // FIXME: use for identifier path completion - private final SchemaNode node; - - private ParsingState currentParsingState = ParsingState.LEAF_REF_PATH; - private List predicatePathKeyQnameList; - private QNameWithPredicateBuilder currentLeafRefPathQName; - private QNamePredicateBuilder currentPredicate; - private QNameModule currentQnameModule; - private String currentQNameLocalName; - private LeafRefPath leafRefPath; - private boolean relativePath = false; - - private enum ParsingState { - LEAF_REF_PATH, PATH_PREDICATE, PREDICATE_PATH_EQUALITY_EXPR, PATH_KEY_EXPR - } - - LeafRefPathParserListenerImpl(final SchemaContext schemaContext, final Module leafrefModule, - final SchemaNode currentNode) { - this.schemaContext = schemaContext; - this.module = schemaContext.findModule(currentNode.getQName().getModule()).get(); - this.leafrefModule = leafrefModule; - this.node = currentNode; - } - - @Override - public void enterPath_predicate(final Path_predicateContext ctx) { - currentParsingState = ParsingState.PATH_PREDICATE; - currentPredicate = new QNamePredicateBuilder(); - } - - @Override - public void exitPath_predicate(final Path_predicateContext ctx) { - currentLeafRefPathQName.addQNamePredicate(currentPredicate.build()); - currentPredicate = null; - currentParsingState = ParsingState.LEAF_REF_PATH; - } - - - @Override - public void enterRel_path_keyexpr(final Rel_path_keyexprContext ctx) { - currentParsingState = ParsingState.PATH_KEY_EXPR; - - final List dots = ctx.DOTS(); - predicatePathKeyQnameList = new ArrayList<>(dots.size()); - for (int i = 0; i < dots.size(); ++i) { - predicatePathKeyQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER); - } - } - - @Override - public void exitRel_path_keyexpr(final Rel_path_keyexprContext ctx) { - final LeafRefPath pathKeyExpression = LeafRefPath.create(Lists.transform(predicatePathKeyQnameList, - QNameWithPredicateBuilder::build), false); - currentPredicate.setPathKeyExpression(pathKeyExpression); - - currentParsingState = ParsingState.PREDICATE_PATH_EQUALITY_EXPR; - } - - @Override - public void enterRelative_path(final Relative_pathContext ctx) { - relativePath = true; - final List dots = ctx.DOTS(); - for (int i = 0; i < dots.size(); ++i) { - leafRefPathQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER); - } - } - - @Override - public void enterPath_equality_expr(final Path_equality_exprContext ctx) { - currentParsingState = ParsingState.PREDICATE_PATH_EQUALITY_EXPR; - } - - @Override - public void exitPath_equality_expr(final Path_equality_exprContext ctx) { - currentParsingState = ParsingState.PATH_PREDICATE; - } - - @Override - public void enterPrefix(final PrefixContext ctx) { - final String prefix = ctx.getText(); - if (!leafrefModule.getPrefix().equals(prefix)) { - final Optional qnameModuleOpt = getQNameModuleForImportPrefix(leafrefModule, prefix); - checkArgument(qnameModuleOpt.isPresent(), "No module import for prefix: %s in module: %s", prefix, - leafrefModule.getName()); - currentQnameModule = qnameModuleOpt.get(); - } else { - currentQnameModule = leafrefModule.getQNameModule(); - } - } - - @Override - public void exitPath_arg(final Path_argContext ctx) { - leafRefPath = LeafRefPath.create(Lists.transform(leafRefPathQnameList, QNameWithPredicateBuilder::build), - !relativePath); - } - - @Override - public void enterIdentifier(final IdentifierContext ctx) { - currentQNameLocalName = ctx.getText(); - } - - @Override - public void exitNode_identifier(final Node_identifierContext ctx) { - if (currentQnameModule == null) { - if (relativePath) { - currentQnameModule = module.getQNameModule(); - } else { - currentQnameModule = leafrefModule.getQNameModule(); - } - } - - if (currentParsingState == ParsingState.PREDICATE_PATH_EQUALITY_EXPR) { - currentPredicate.setIdentifier(QName.create(currentQnameModule, currentQNameLocalName)); - } else { - final QNameWithPredicateBuilder qnameBuilder = new QNameWithPredicateBuilder(currentQnameModule, - currentQNameLocalName); - - if (currentParsingState == ParsingState.PATH_KEY_EXPR) { - predicatePathKeyQnameList.add(qnameBuilder); - } else if (currentParsingState == ParsingState.LEAF_REF_PATH) { - currentLeafRefPathQName = qnameBuilder; - leafRefPathQnameList.add(qnameBuilder); - } - } - currentQnameModule = null; - currentQNameLocalName = null; - } - - public LeafRefPath getLeafRefPath() { - return leafRefPath; - } - - private Optional getQNameModuleForImportPrefix(final Module targetModule, final String prefix) { - final ModuleImport moduleImport = getModuleImport(targetModule, prefix); - if (moduleImport == null) { - return Optional.empty(); - } - - final String moduleName = moduleImport.getModuleName(); - final Optional revision = moduleImport.getRevision(); - return schemaContext.findModule(moduleName, revision).map(Module::getQNameModule); - } - - private static ModuleImport getModuleImport(final Module targetModule, final String prefix) { - return targetModule.getImports().stream() - .filter(imp -> prefix.equals(imp.getPrefix())).findFirst().orElse(null); - } -} diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathSyntaxErrorException.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathSyntaxErrorException.java deleted file mode 100644 index 6f2450a97a..0000000000 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefPathSyntaxErrorException.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.yang.data.impl.leafref; - -public class LeafRefPathSyntaxErrorException extends LeafRefYangSyntaxErrorException { - - private static final long serialVersionUID = 1L; - - public LeafRefPathSyntaxErrorException(final String module, final int line, final int charPositionInLine, - final String message) { - super(module, line, charPositionInLine, message, null); - } - - public LeafRefPathSyntaxErrorException(final String module, final int line, final int charPositionInLine, - final String message, final Throwable cause) { - super(module,line,charPositionInLine,message,cause); - } -} diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateImpl.java index 73e7bcd123..43d8baf19c 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateImpl.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNamePredicateImpl.java @@ -9,13 +9,10 @@ package org.opendaylight.yangtools.yang.data.impl.leafref; import static java.util.Objects.requireNonNull; -import java.io.Serializable; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.yang.common.QName; -class QNamePredicateImpl implements Immutable, Serializable, QNamePredicate { - private static final long serialVersionUID = 1L; - +class QNamePredicateImpl implements Immutable, QNamePredicate { private final QName identifier; private final LeafRefPath pathKeyExpression; diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateImpl.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateImpl.java index 390fe345d7..b1bed02754 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateImpl.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/QNameWithPredicateImpl.java @@ -13,9 +13,6 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; final class QNameWithPredicateImpl extends AbstractQNameWithPredicate { - - private static final long serialVersionUID = 1L; - private final ImmutableList qnamePredicates; private final QNameModule moduleQname; private final String localName; diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/SimpleQNameWithPredicate.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/SimpleQNameWithPredicate.java index 1e414df14a..e811ed2116 100644 --- a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/SimpleQNameWithPredicate.java +++ b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/SimpleQNameWithPredicate.java @@ -15,8 +15,6 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; public class SimpleQNameWithPredicate extends AbstractQNameWithPredicate { - private static final long serialVersionUID = 1L; - private final QName qname; SimpleQNameWithPredicate(final QName qname) { -- 2.36.6