import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
-import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
-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.StatementDefinitionNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleIdentifier;
import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToNamespace;
this.source = Preconditions.checkNotNull(source);
}
- public boolean isEnabledSemanticVersioning(){
+ boolean isEnabledSemanticVersioning(){
return currentContext.isEnabledSemanticVersioning();
}
return inProgressPhase;
}
- StatementDefinitionContext<?, ?, ?> getDefinition(final QName name) {
- return currentContext.getStatementDefinition(name);
- }
-
ContextBuilder<?, ?, ?> createDeclaredChild(final StatementContextBase<?, ?, ?> current, final QName name,
final StatementSourceReference ref) {
- StatementDefinitionContext<?, ?, ?> def = getDefinition(name);
+ StatementDefinitionContext<?, ?, ?> def = currentContext.getStatementDefinition(name);
if (def == null) {
- // unknown-stmts (from import, include or local-scope)
- if (qNameToStmtDefMap.get(name) != null) {
- final StatementDefinition extension = currentContext.getFromNamespace(
- StatementDefinitionNamespace.class, name);
- SourceException.throwIfNull(extension, current.getStatementSourceReference(), "Extension %s not found",
- name);
-
- def = new StatementDefinitionContext<>(new UnknownStatementImpl.Definition(extension));
+ final StatementSupport<?, ?, ?> extension = qNameToStmtDefMap.get(name);
+ if (extension != null) {
+ def = new StatementDefinitionContext<>(extension);
} else {
// type-body-stmts
def = resolveTypeBodyStmts(name.getLocalName());
}
} else if (current != null && current.definition().getRepresentingClass().equals(UnknownStatementImpl.class)) {
- // FIXME: What's going on here?
+ /*
+ * This code wraps statements encountered inside an extension so they do not get confused with regular
+ * statements.
+ *
+ * FIXME: BUG-7037: re-evaluate whether this is really needed, as this is a very expensive way of making
+ * this work. We really should be peeking into the extension definition to find these nodes,
+ * as otherwise we are not reusing definitions nor support for these nodes.
+ */
final QName qName = Utils.qNameFromArgument(current, name.getLocalName());
-
def = new StatementDefinitionContext<>(new UnknownStatementImpl.Definition(
new ModelDefinedStatementDefinition(qName)));
}
if (potentialLocal != null) {
return potentialLocal;
}
+
for (final NamespaceStorageNode importedSource : importedNamespaces) {
final V potential = importedSource.getFromLocalStorage(type, key);
if (potential != null) {
@Override
public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromLocalStorage(final Class<N> type) {
final Map<K, V> potentialLocal = getRoot().getAllFromLocalStorage(type);
-
if (potentialLocal != null) {
return potentialLocal;
}
return hasProgressed ? PhaseCompletionProgress.PROGRESS : PhaseCompletionProgress.NO_PROGRESS;
}
-
private static boolean tryToProgress(final Collection<ModifierImpl> currentPhaseModifiers) {
boolean hasProgressed = false;
}
return hasProgressed;
-
}
ModelActionBuilder newInferenceAction(final ModelProcessingPhase phase) {
private QNameToStatementDefinition stmtDef() {
// regular YANG statements and extension supports added
- final ImmutableMap<QName, StatementSupport<?, ?, ?>> definitions = currentContext.getSupportsForPhase(
- inProgressPhase).getDefinitions();
+ final Map<QName, StatementSupport<?, ?, ?>> definitions = currentContext.getSupportsForPhase(inProgressPhase)
+ .getDefinitions();
for (final Entry<QName, StatementSupport<?, ?, ?>> entry : definitions.entrySet()) {
qNameToStmtDefMap.put(entry.getKey(), entry.getValue());
}
// extensions added
if (inProgressPhase.equals(ModelProcessingPhase.FULL_DECLARATION)) {
- final Map<QName, StmtContext<?, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>>> extensions =
- currentContext.getAllFromNamespace(ExtensionNamespace.class);
+ final Map<QName, StatementSupport<?, ?, ?>> extensions = currentContext.getAllFromNamespace(
+ StatementDefinitionNamespace.class);
if (extensions != null) {
- for (final Entry<QName, StmtContext<?, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>>> extension :
- extensions.entrySet()) {
- if(qNameToStmtDefMap.get(extension.getKey()) == null) {
- qNameToStmtDefMap.put((extension.getKey()),
- (StatementDefinition) ((StatementContextBase<?, ?, ?>) extension.getValue()).definition()
- .getFactory());
+ for (final Entry<QName, StatementSupport<?, ?, ?>> e : extensions.entrySet()) {
+ final StatementDefinition previous = qNameToStmtDefMap.get(e.getKey());
+ if (previous != null) {
+ LOG.debug("Source {} already defines statement {} as {}", source, e.getKey(), previous);
+ if (!(previous instanceof StatementSupport)) {
+ LOG.warn("Source {} statement for {} definition {} is not a StatementSupport", source,
+ e.getKey(), previous);
+ }
+ } else {
+ qNameToStmtDefMap.put(e.getKey(), e.getValue());
+ LOG.debug("Source {} defined statement {} as {}", source, e.getKey(), e.getValue());
}
}
}
--- /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.stmt.UnknownStatement;
+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;
+
+/**
+ * StatementSupport for statements defined via YANG extensions. This is implemented by piggy-backing
+ * to a {@link UnknownStatementImpl.Definition}.
+ *
+ * @author Robert Varga
+ */
+public final class ModelDefinedStatementSupport extends AbstractStatementSupport<String,
+ UnknownStatement<String>, EffectiveStatement<String, UnknownStatement<String>>> {
+ private final UnknownStatementImpl.Definition definition;
+
+ ModelDefinedStatementSupport(final ModelDefinedStatementDefinition publicDefinition) {
+ super(publicDefinition);
+ this.definition = new UnknownStatementImpl.Definition(publicDefinition);
+ }
+
+ @Override
+ public UnknownStatement<String> createDeclared(final StmtContext<String, UnknownStatement<String>, ?> ctx) {
+ return definition.createDeclared(ctx);
+ }
+
+ @Override
+ public EffectiveStatement<String, UnknownStatement<String>> createEffective(
+ final StmtContext<String, UnknownStatement<String>, EffectiveStatement<String, UnknownStatement<String>>> ctx) {
+ return definition.createEffective(ctx);
+ }
+
+ @Override
+ public String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) throws SourceException {
+ return definition.parseArgumentValue(ctx, value);
+ }
+}
package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import java.util.List;
import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
public abstract class UnknownEffectiveStatementBase<A> extends AbstractEffectiveDocumentedNode<A, UnknownStatement<A>>
implements UnknownSchemaNode {
private final QName nodeType;
private final String nodeParameter;
- public UnknownEffectiveStatementBase(final StmtContext<A, UnknownStatement<A>, ?> ctx) {
+ protected UnknownEffectiveStatementBase(final StmtContext<A, UnknownStatement<A>, ?> ctx) {
super(ctx);
final StmtContext<?, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>> extensionInit = ctx
extension = null;
nodeType = ctx.getPublicDefinition().getArgumentName();
} else {
- extension = (ExtensionEffectiveStatementImpl) extensionInit.buildEffective();
+ final EffectiveStatement<QName, ExtensionStatement> effective = extensionInit.buildEffective();
+ Preconditions.checkState(effective instanceof ExtensionDefinition,
+ "Statement %s is not an ExtensionDefinition", effective);
+ extension = (ExtensionDefinition) extensionInit.buildEffective();
nodeType = null;
}