import java.util.Set;
import java.util.SortedMap;
import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.util.RecursiveObjectLeaker;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
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.Registry;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules;
import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules.SupportedModules;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace;
import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
import org.opendaylight.yangtools.yang.parser.stmt.reactor.SourceSpecificContext.PhaseCompletionProgress;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.RecursiveObjectLeaker;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBehaviour.Registry {
+class BuildGlobalContext extends NamespaceStorageSupport implements Registry {
private static final Logger LOG = LoggerFactory.getLogger(BuildGlobalContext.class);
- private static final List<ModelProcessingPhase> PHASE_EXECUTION_ORDER = ImmutableList
- .<ModelProcessingPhase> builder().add(ModelProcessingPhase.SOURCE_PRE_LINKAGE)
+ private static final List<ModelProcessingPhase> PHASE_EXECUTION_ORDER =
+ ImmutableList.<ModelProcessingPhase>builder().add(ModelProcessingPhase.SOURCE_PRE_LINKAGE)
.add(ModelProcessingPhase.SOURCE_LINKAGE).add(ModelProcessingPhase.STATEMENT_DEFINITION)
.add(ModelProcessingPhase.FULL_DECLARATION).add(ModelProcessingPhase.EFFECTIVE_MODEL).build();
private final Table<YangVersion, QName, StatementDefinitionContext<?, ?, ?>> definitions = HashBasedTable.create();
+ private final Map<QName, StatementDefinitionContext<?, ?, ?>> modelDefinedStmtDefs = new HashMap<>();
private final Map<Class<?>, NamespaceBehaviourWithListeners<?, ?, ?>> supportedNamespaces = new HashMap<>();
private final List<MutableStatement> mutableStatementsToSeal = new ArrayList<>();
private final Map<ModelProcessingPhase, StatementSupportBundle> supports;
return potential;
}
+ StatementDefinitionContext<?, ?, ?> getModelDefinedStatementDefinition(final QName name) {
+ return modelDefinedStmtDefs.get(name);
+ }
+
+ void putModelDefinedStatementDefinition(final QName name, final StatementDefinitionContext<?, ?, ?> def) {
+ modelDefinedStmtDefs.put(name, def);
+ }
+
private void executePhases() throws ReactorException {
for (final ModelProcessingPhase phase : PHASE_EXECUTION_ORDER) {
startPhase(phase);
private SomeModifiersUnresolvedException propagateException(final SourceSpecificContext source,
final RuntimeException cause) throws SomeModifiersUnresolvedException {
- final SourceIdentifier sourceId = Utils.createSourceIdentifier(source.getRoot());
+ final SourceIdentifier sourceId = StmtContextUtils.createSourceIdentifier(source.getRoot());
if (!(cause instanceof SourceException)) {
/*
* This should not be happening as all our processing should provide SourceExceptions.
throw new SomeModifiersUnresolvedException(currentPhase, sourceId, cause);
}
+ @SuppressWarnings("checkstyle:illegalCatch")
private EffectiveSchemaContext transformEffective() throws ReactorException {
Preconditions.checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
final List<DeclaredStatement<?>> rootStatements = new ArrayList<>(sources.size());
}
sealMutableStatements();
- return new EffectiveSchemaContext(rootStatements, rootEffectiveStatements);
+ return EffectiveSchemaContext.create(rootStatements, rootEffectiveStatements);
}
private void startPhase(final ModelProcessingPhase phase) {
loadPhaseStatementsFor(libSources);
}
+ @SuppressWarnings("checkstyle:illegalCatch")
private void loadPhaseStatementsFor(final Set<SourceSpecificContext> sources) throws ReactorException {
for (final SourceSpecificContext source : sources) {
try {
if (suppressed.length > 0) {
LOG.error("{} additional errors reported:", suppressed.length);
- int i = 1;
+ int count = 1;
for (final Throwable t : suppressed) {
// FIXME: this should be configured in the appender, really
if (LOG.isDebugEnabled()) {
- LOG.error("Error {}: {}", i, t.getMessage(), t);
+ LOG.error("Error {}: {}", count, t.getMessage(), t);
} else {
- LOG.error("Error {}: {}", i, t.getMessage());
+ LOG.error("Error {}: {}", count, t.getMessage());
}
- i++;
+ count++;
}
}
if (!addedCause) {
addedCause = true;
- final SourceIdentifier sourceId = Utils.createSourceIdentifier(failedSource.getRoot());
+ final SourceIdentifier sourceId = StmtContextUtils.createSourceIdentifier(failedSource.getRoot());
buildFailure = new SomeModifiersUnresolvedException(currentPhase, sourceId, sourceEx);
} else {
buildFailure.addSuppressed(sourceEx);
return buildFailure;
}
+ @SuppressWarnings("checkstyle:illegalCatch")
private void completePhaseActions() throws ReactorException {
Preconditions.checkState(currentPhase != null);
final List<SourceSpecificContext> sourcesToProgress = Lists.newArrayList(sources);
switch (sourceProgress) {
case FINISHED:
currentSource.remove();
- // Fallback to progress, since we were able to make
- // progress in computation
+ // we were able to make progress in computation
+ progressing = true;
+ break;
case PROGRESS:
progressing = true;
break;
final Set<SourceSpecificContext> requiredLibs = new HashSet<>();
for (final SourceSpecificContext source : sources) {
collectRequiredSourcesFromLib(libSourcesTable, requiredLibs, source);
+ removeConflictingLibSources(source, requiredLibs);
}
return requiredLibs;
}
private static SourceSpecificContext getRequiredLibSource(final ModuleIdentifier requiredModule,
final TreeBasedTable<String, Date, SourceSpecificContext> libSourcesTable) {
- return requiredModule.getRevision() == SimpleDateFormatUtil.DEFAULT_DATE_IMP ? getLatestRevision(libSourcesTable
- .row(requiredModule.getName())) : libSourcesTable.get(requiredModule.getName(),
+ return requiredModule.getRevision() == SimpleDateFormatUtil.DEFAULT_DATE_IMP
+ || requiredModule.getRevision() == SimpleDateFormatUtil.DEFAULT_BELONGS_TO_DATE ? getLatestRevision(
+ libSourcesTable.row(requiredModule.getName())) : libSourcesTable.get(requiredModule.getName(),
requiredModule.getRevision());
}
return sourceMap != null && !sourceMap.isEmpty() ? sourceMap.get(sourceMap.lastKey()) : null;
}
+ // removes required library sources which would cause namespace/name conflict with one of the main sources
+ // later in the parsing process. this can happen if we add a parent module or a submodule as a main source
+ // and the same parent module or submodule is added as one of the library sources.
+ // such situation may occur when using the yang-system-test artifact - if a parent module/submodule is specified
+ // as its argument and the same dir is specified as one of the library dirs through -p option).
+ private static void removeConflictingLibSources(final SourceSpecificContext source,
+ final Set<SourceSpecificContext> requiredLibs) {
+ final Iterator<SourceSpecificContext> requiredLibsIter = requiredLibs.iterator();
+ while (requiredLibsIter.hasNext()) {
+ final SourceSpecificContext currentReqSource = requiredLibsIter.next();
+ if (source.getRootIdentifier().equals(currentReqSource.getRootIdentifier())) {
+ requiredLibsIter.remove();
+ }
+ }
+ }
+
private void endPhase(final ModelProcessingPhase phase) {
Preconditions.checkState(currentPhase == phase);
finishedPhase = currentPhase;