import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
+import javax.annotation.concurrent.Immutable;
+
+@Immutable
public class YangStatementParserListenerImpl extends YangStatementParserBaseListener {
private StatementWriter writer;
try {
QName identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE,
((YangStatementParser.KeywordContext) child).children.get(0).getText());
- if (stmtDef != null && stmtDef.get(identifier) != null && toBeSkipped.isEmpty()) {
+ if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) && toBeSkipped.isEmpty()) {
writer.startStatement(identifier, ref);
} else {
action = false;
try {
String statementName = ((YangStatementParser.KeywordContext) child).children.get(0).getText();
QName identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE, statementName);
- if (stmtDef != null && stmtDef.get(identifier) != null && toBeSkipped.isEmpty()) {
+ if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) && toBeSkipped.isEmpty()) {
writer.endStatement(ref);
}
--- /dev/null
+/*
+ * 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.parser.spi.source;
+
+import org.opendaylight.yangtools.yang.common.QNameModule;
+
+import javax.annotation.Nullable;
+import java.util.HashMap;
+import java.util.Map;
+
+public class PrefixToModuleMap implements PrefixToModule {
+
+ private Map<String, QNameModule> prefixToModuleMap = new HashMap<>();
+
+ public void put(String prefix, QNameModule qNameModule) {
+ prefixToModuleMap.put(prefix, qNameModule);
+ }
+
+ @Nullable
+ @Override
+ public QNameModule get(String prefix) {
+ return prefixToModuleMap.get(prefix);
+ }
+
+ @Nullable
+ @Override
+ public QNameModule getByNamespace(String namespace) {
+ return null;
+ }
+}
+/*
+ * 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.parser.spi.source;
import org.opendaylight.yangtools.yang.common.QName;
import java.util.HashMap;
import java.util.Map;
-public class QNameToStatementDefinitionMap implements QNameToStatementDefinition{
+public class QNameToStatementDefinitionMap implements QNameToStatementDefinition {
private Map<QName, StatementDefinition> qNameToStmtDefMap = new HashMap<>();
- public void put(QName qName, StatementDefinition stDef ) {
+ public void put(QName qName, StatementDefinition stDef) {
qNameToStmtDefMap.put(qName, stDef);
}
- @Nullable @Override
+ @Nullable
+ @Override
public StatementDefinition get(@Nonnull QName identifier) {
return qNameToStmtDefMap.get(identifier);
}
*/
package org.opendaylight.yangtools.yang.parser.stmt.reactor;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.YangConstants;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import com.google.common.base.Preconditions;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.ImportedNamespaceContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
+import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModuleMap;
import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinitionMap;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase.ContextBuilder;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.UnknownStatementImpl;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBehaviour.Registry, Mutable {
private ModelProcessingPhase inProgressPhase;
private ModelProcessingPhase finishedPhase;
private QNameToStatementDefinitionMap qNameToStmtDefMap = new QNameToStatementDefinitionMap();
+ private PrefixToModuleMap prefixToModuleMap = new PrefixToModuleMap();
SourceSpecificContext(BuildGlobalContext currentContext,StatementStreamSource source) {
ContextBuilder<?, ?, ?> createDeclaredChild(StatementContextBase<?, ?, ?> current, QName name, StatementSourceReference ref) {
StatementDefinitionContext<?,?,?> def = getDefinition(name);
- Preconditions.checkArgument(def != null, "Statement %s does not have type mapping defined.",name);
+
+ //extensions
+ if (def == null) {
+ if (Utils.isValidStatementDefinition(prefixToModuleMap, qNameToStmtDefMap, name)) {
+ def = new StatementDefinitionContext<>(new UnknownStatementImpl.Definition(qNameToStmtDefMap.get(Utils.trimPrefix(name))));
+ }
+ }
+
+ Preconditions.checkArgument(def != null, "Statement %s does not have type mapping defined.", name);
if(current == null) {
return createDeclaredRoot(def,ref);
}
void loadStatements() throws SourceException {
switch (inProgressPhase) {
- case SOURCE_LINKAGE:
+ case SOURCE_LINKAGE:
source.writeLinkage(new StatementContextWriter(this, inProgressPhase),stmtDef());
break;
- case STATEMENT_DEFINITION:
+ case STATEMENT_DEFINITION:
source.writeLinkageAndStatementDefinitions(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes());
break;
- case FULL_DECLARATION:
+ case FULL_DECLARATION:
source.writeFull(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes());
break;
default:
}
private PrefixToModule prefixes() {
- // TODO Auto-generated method stub
- return null;
+ Map<String, QNameModule> prefixes = (Map<String, QNameModule>) currentContext.getAllFromNamespace(PrefixToModule.class);
+ for (Map.Entry<String, QNameModule> prefix : prefixes.entrySet()) {
+ prefixToModuleMap.put(prefix.getKey(), prefix.getValue());
+ }
+ return prefixToModuleMap;
}
private QNameToStatementDefinition stmtDef() {
+ //regular YANG statements added
ImmutableMap<QName, StatementSupport<?, ?, ?>> definitions = currentContext.getSupportsForPhase(
inProgressPhase).getDefinitions();
for (Map.Entry<QName, StatementSupport<?,?,?>> entry : definitions.entrySet()) {
qNameToStmtDefMap.put(entry.getKey(), entry.getValue());
}
+
+ //extensions added
+ if (inProgressPhase.equals(ModelProcessingPhase.FULL_DECLARATION)) {
+ Map<QName, SubstatementContext<?, ?, ?>> extensions = (Map<QName, SubstatementContext<?, ?, ?>>) currentContext.getAllFromNamespace(ExtensionNamespace.class);
+ if (extensions != null) {
+ for (Map.Entry<QName, SubstatementContext<?, ?, ?>> extension : extensions.entrySet()) {
+ qNameToStmtDefMap.put(new QName(YangConstants.RFC6020_YIN_NAMESPACE, extension.getKey().getLocalName()), (StatementDefinition) extension.getValue().definition().getFactory());
+ }
+ }
+ }
return qNameToStmtDefMap;
}
}
package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ExtensionEffectiveStatementImpl;
-
-import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement;
+import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
public class ExtensionStatementImpl extends AbstractDeclaredStatement<QName> implements ExtensionStatement {
@Override
public QName parseArgumentValue(StmtContext<?,?,?> ctx, String value) {
- return Utils.qNameFromArgument(ctx,value);
+ return Utils.qNameFromArgument(ctx, value);
}
@Override
return new ExtensionEffectiveStatementImpl(ctx);
}
+ @Override
+ public void onStatementDefinitionDeclared(final StmtContext.Mutable<QName, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>> stmt) throws InferenceException, SourceException {
+ stmt.addContext(ExtensionNamespace.class, stmt.getStatementArgument(), stmt);
+ }
}
@Override
--- /dev/null
+/*
+ * 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.parser.stmt.rfc6020;
+
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+import javax.annotation.Nullable;
+
+public class UnknownStatementImpl extends AbstractDeclaredStatement<String> implements UnknownStatement<String> {
+
+ protected UnknownStatementImpl(StmtContext<String, ?, ?> context) {
+ super(context);
+ }
+
+ public static class Definition extends AbstractStatementSupport<String, UnknownStatement<String>, EffectiveStatement<String, UnknownStatement<String>>> {
+
+
+ public Definition(StatementDefinition publicDefinition) {
+ super(publicDefinition);
+ }
+
+ @Override
+ public String parseArgumentValue(StmtContext<?, ?, ?> ctx, String value) throws SourceException {
+ return value;
+ }
+
+ @Override
+ public UnknownStatement createDeclared(StmtContext<String, UnknownStatement<String>, ?> ctx) {
+ return new UnknownStatementImpl(ctx);
+ }
+
+ @Override
+ public EffectiveStatement<String, UnknownStatement<String>> createEffective(StmtContext<String, UnknownStatement<String>, EffectiveStatement<String, UnknownStatement<String>>> ctx) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Nullable
+ @Override
+ public String getArgument() {
+ return rawArgument();
+ }
+}
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
-
import javax.annotation.Nullable;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
-
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Splitter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Splitter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
public final class Utils {
private static final Logger LOG = LoggerFactory.getLogger(Utils.class);
import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.sourceLocal;
import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.treeScoped;
+import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
+import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
public final class YangInferencePipeline {
.addSupport(sourceLocal(IncludedModuleContext.class))
.addSupport(sourceLocal(ImpPrefixToModuleIdentifier.class))
.addSupport(sourceLocal(BelongsToPrefixToModuleName.class))
- //.addSupport(global(ImpPrefixToModuleIdentifier.class))
- .build();
+ .addSupport(sourceLocal(QNameToStatementDefinition.class))
+ .build();
private static final StatementSupportBundle STMT_DEF_BUNDLE = StatementSupportBundle.
derivedFrom(LINKAGE_BUNDLE)
.addSupport(new YinElementStatementImpl.Definition())
.addSupport(new ArgumentStatementImpl.Definition())
.addSupport(new ExtensionStatementImpl.Definition())
- //TODO: implement extension support in SourceSpecificContext
- // in order to prepare statements for full declaration phase,
- // when those ones are read.
+ .addSupport(global(ExtensionNamespace.class))
.build();
private static final StatementSupportBundle FULL_DECL_BUNDLE = StatementSupportBundle.
+/*
+ * 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.parser.stmt.rfc6020;
import org.antlr.v4.runtime.ANTLRInputStream;
-/**
+/*
* Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
import static org.junit.Assert.assertNotNull;
public class YangFileStmtTest {
- private static final YangStatementSourceImpl YANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/test.yang");
- private static final YangStatementSourceImpl IMPORTEDYANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/importedtest.yang");
- private static final YangStatementSourceImpl SIMPLENODES = new YangStatementSourceImpl("/semantic-statement-parser/simple-nodes-semantic.yang");
- private static final YangStatementSourceImpl FOO = new YangStatementSourceImpl("/semantic-statement-parser/foo.yang");
- private static final YangStatementSourceImpl FILE1 = new YangStatementSourceImpl("/model/bar.yang");
- private static final YangStatementSourceImpl FILE2 = new YangStatementSourceImpl("/model/baz.yang");
- private static final YangStatementSourceImpl FILE3 = new YangStatementSourceImpl("/model/foo.yang");
- private static final YangStatementSourceImpl FILE4 = new YangStatementSourceImpl("/model/subfoo.yang");
- private static final YangStatementSourceImpl EXTFILE = new YangStatementSourceImpl("/semantic-statement-parser/ext-typedef.yang");
- private static final YangStatementSourceImpl EXTUSE = new YangStatementSourceImpl("/semantic-statement-parser/ext-use.yang");
+ //basic statements to parse and write
+ private static final YangStatementSourceImpl YANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/test.yang");
+ private static final YangStatementSourceImpl IMPORTEDYANGFILE = new YangStatementSourceImpl("/semantic-statement-parser/importedtest.yang");
+ private static final YangStatementSourceImpl SIMPLENODES = new YangStatementSourceImpl("/semantic-statement-parser/simple-nodes-semantic.yang");
+ private static final YangStatementSourceImpl FOOBAR = new YangStatementSourceImpl("/semantic-statement-parser/foobar.yang");
+ //extension statement to parse and write
+ private static final YangStatementSourceImpl EXTFILE = new YangStatementSourceImpl("/semantic-statement-parser/ext-typedef.yang");
+ private static final YangStatementSourceImpl EXTUSE = new YangStatementSourceImpl("/semantic-statement-parser/ext-use.yang");
- @Test
- public void readAndParseYangFileTest1() throws SourceException, ReactorException {
- CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
- addSources(reactor, YANGFILE, SIMPLENODES, IMPORTEDYANGFILE, FOO);
- EffectiveModelContext result = reactor.build();
- assertNotNull(result);
- }
-
- // TODO uncomment when Augment in Uses implemented
-// @Test
-// public void readAndParseYangFileTest2() throws SourceException, ReactorException {
-// CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-// addSources(reactor, FILE1, FILE2, FILE3, FILE4);
-// EffectiveModelContext result = reactor.build();
-// assertNotNull(result);
-// }
-
- @Test
- public void readAndParseYangFileTest3() throws SourceException, ReactorException {
- CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
- addSources(reactor, EXTFILE, EXTUSE);
- EffectiveModelContext result = reactor.build();
- assertNotNull(result);
- }
+ @Test
+ public void readAndParseYangFileTest() throws SourceException, ReactorException {
+ CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+ addSources(reactor, YANGFILE, SIMPLENODES, IMPORTEDYANGFILE, FOOBAR);
+ addSources(reactor, EXTFILE, EXTUSE);
+ EffectiveModelContext result = reactor.build();
+ assertNotNull(result);
+ }
- private void addSources(CrossSourceStatementReactor.BuildAction reactor, StatementStreamSource... sources) {
- for (StatementStreamSource source : sources) {
- reactor.addSource(source);
- }
+ private void addSources(CrossSourceStatementReactor.BuildAction reactor, StatementStreamSource... sources) {
+ for (StatementStreamSource source : sources) {
+ reactor.addSource(source);
}
+ }
}
\ No newline at end of file
-module foo {
+module foobar {
yang-version 1;
- namespace "urn:opendaylight.foo";
- prefix "foo";
+ namespace "urn:opendaylight.foobar";
+ prefix "foobar";
revision "2015-07-08" {
}
anyxml data {
- config false;
+ config false;
description "anyxml desc";
if-feature has-name;
mandatory true;