*/
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 com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
import org.opendaylight.yangtools.concepts.Mutable;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-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.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;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
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);
}
- return current.substatementBuilder(def,ref);
+ return current.substatementBuilder(def, ref);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
if(root == null) {
root = new RootStatementContext(this, SourceSpecificContext.this);
} else {
- Preconditions.checkState(root.getIdentifier().equals(getIdentifier()), "Root statement was already defined.");
+ Preconditions.checkState(root.getIdentifier().equals(getIdentifier()), "Root statement was already defined as %s.", root.getIdentifier());
}
root.resetLists();
return root;
return root.buildDeclared();
}
- EffectiveStatement<?,?> build() {
+ EffectiveStatement<?,?> buildEffective() {
return root.buildEffective();
}
@Override
public StorageNodeType getStorageNodeType() {
- return StorageNodeType.SourceLocalSpecial;
+ return StorageNodeType.SOURCE_LOCAL_SPECIAL;
}
@Override
PhaseCompletionProgress tryToCompletePhase(ModelProcessingPhase phase) throws SourceException {
Collection<ModifierImpl> currentPhaseModifiers = modifiers.get(phase);
+
+ boolean hasProgressed = hasProgress(currentPhaseModifiers);
+
+ boolean phaseCompleted = root.tryToCompletePhase(phase);
+
+ hasProgressed = (hasProgress(currentPhaseModifiers) | hasProgressed);
+
+ if(phaseCompleted && (currentPhaseModifiers.isEmpty())) {
+ finishedPhase = phase;
+ return PhaseCompletionProgress.FINISHED;
+
+ }
+ if(hasProgressed) {
+ return PhaseCompletionProgress.PROGRESS;
+ }
+ return PhaseCompletionProgress.NO_PROGRESS;
+ }
+
+
+ private boolean hasProgress(Collection<ModifierImpl> currentPhaseModifiers) {
+
Iterator<ModifierImpl> modifier = currentPhaseModifiers.iterator();
boolean hasProgressed = false;
while(modifier.hasNext()) {
hasProgressed = true;
}
}
- if(root.tryToCompletePhase(phase) && currentPhaseModifiers.isEmpty()) {
- finishedPhase = phase;
- return PhaseCompletionProgress.FINISHED;
- }
- if(hasProgressed) {
- return PhaseCompletionProgress.PROGRESS;
- }
- return PhaseCompletionProgress.NO_PROGRESS;
+ return hasProgressed;
+
}
ModelActionBuilder newInferenceAction(ModelProcessingPhase phase) {
void loadStatements() throws SourceException {
switch (inProgressPhase) {
- case SourceLinkage:
+ case SOURCE_LINKAGE:
source.writeLinkage(new StatementContextWriter(this, inProgressPhase),stmtDef());
break;
- case StatementDefinition:
+ case STATEMENT_DEFINITION:
source.writeLinkageAndStatementDefinitions(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes());
- case FullDeclaration:
+ break;
+ case FULL_DECLARATION:
source.writeFull(new StatementContextWriter(this, inProgressPhase), stmtDef(), prefixes());
-
+ break;
default:
break;
}
}
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() {
- // TODO Auto-generated method stub
- return null;
- }
+ //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;
+ }
}