import com.google.common.base.Verify;
import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.SetMultimap;
import com.google.common.collect.Table;
import com.google.common.collect.TreeBasedTable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.SortedMap;
-import javax.annotation.Nonnull;
-import org.opendaylight.yangtools.util.RecursiveObjectLeaker;
+import org.eclipse.jdt.annotation.NonNull;
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.common.YangVersion;
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.repo.api.RevisionSourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedNamespaceBehaviour;
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.ParserNamespace;
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.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class BuildGlobalContext extends NamespaceStorageSupport implements Registry {
+final 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)
- .add(ModelProcessingPhase.SOURCE_LINKAGE).add(ModelProcessingPhase.STATEMENT_DEFINITION)
- .add(ModelProcessingPhase.FULL_DECLARATION).add(ModelProcessingPhase.EFFECTIVE_MODEL).build();
+ private static final ModelProcessingPhase[] PHASE_EXECUTION_ORDER = {
+ ModelProcessingPhase.SOURCE_PRE_LINKAGE,
+ ModelProcessingPhase.SOURCE_LINKAGE,
+ ModelProcessingPhase.STATEMENT_DEFINITION,
+ ModelProcessingPhase.FULL_DECLARATION,
+ ModelProcessingPhase.EFFECTIVE_MODEL
+ };
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;
+ private final ImmutableMap<ModelProcessingPhase, StatementSupportBundle> supports;
private final Set<SourceSpecificContext> sources = new HashSet<>();
- private final Set<YangVersion> supportedVersions;
+ private final ImmutableSet<YangVersion> supportedVersions;
private final boolean enabledSemanticVersions;
private Set<SourceSpecificContext> libSources = new HashSet<>();
private ModelProcessingPhase currentPhase = ModelProcessingPhase.INIT;
private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT;
- BuildGlobalContext(final Map<ModelProcessingPhase, StatementSupportBundle> supports,
- final Map<ValidationBundleType, Collection<?>> supportedValidation,
+ BuildGlobalContext(final ImmutableMap<ModelProcessingPhase, StatementSupportBundle> supports,
+ final ImmutableMap<ValidationBundleType, Collection<?>> supportedValidation,
final StatementParserMode statementParserMode) {
this.supports = requireNonNull(supports, "BuildGlobalContext#supports cannot be null");
throw new IllegalArgumentException("Unhandled parser mode " + statementParserMode);
}
- for (final Entry<ValidationBundleType, Collection<?>> validationBundle : supportedValidation.entrySet()) {
- addToNs(ValidationBundlesNamespace.class, validationBundle.getKey(), validationBundle.getValue());
- }
+ addToNamespace(ValidationBundlesNamespace.class, supportedValidation);
this.supportedVersions = ImmutableSet.copyOf(supports.get(ModelProcessingPhase.INIT).getSupportedVersions());
}
return enabledSemanticVersions;
}
- StatementSupportBundle getSupportsForPhase(final ModelProcessingPhase currentPhase) {
- return supports.get(currentPhase);
+ StatementSupportBundle getSupportsForPhase(final ModelProcessingPhase phase) {
+ return supports.get(phase);
}
- void addSource(@Nonnull final StatementStreamSource source) {
+ void addSource(final @NonNull StatementStreamSource source) {
sources.add(new SourceSpecificContext(this, source));
}
- void addLibSource(@Nonnull final StatementStreamSource libSource) {
+ void addLibSource(final @NonNull StatementStreamSource libSource) {
checkState(!isEnabledSemanticVersioning(),
"Library sources are not supported in semantic version mode currently.");
checkState(currentPhase == ModelProcessingPhase.INIT,
}
void setSupportedFeatures(final Set<QName> supportedFeatures) {
- addToNs(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES,
+ addToNamespace(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES,
ImmutableSet.copyOf(supportedFeatures));
}
- void setModulesDeviatedByModules(final Map<QNameModule, Set<QNameModule>> modulesDeviatedByModules) {
- addToNs(ModulesDeviatedByModules.class, SupportedModules.SUPPORTED_MODULES,
- ImmutableMap.copyOf(modulesDeviatedByModules));
+ void setModulesDeviatedByModules(final SetMultimap<QNameModule, QNameModule> modulesDeviatedByModules) {
+ addToNamespace(ModulesDeviatedByModules.class, SupportedModules.SUPPORTED_MODULES,
+ ImmutableSetMultimap.copyOf(modulesDeviatedByModules));
}
@Override
}
@Override
- public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> getNamespaceBehaviour(
+ public <K, V, N extends ParserNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> getNamespaceBehaviour(
final Class<N> type) {
NamespaceBehaviourWithListeners<?, ?, ?> potential = supportedNamespaces.get(type);
if (potential == null) {
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- private <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> createNamespaceContext(
+ private <K, V, N extends ParserNamespace<K, V>> NamespaceBehaviourWithListeners<K, V, N> createNamespaceContext(
final NamespaceBehaviour<K, V, N> potentialRaw) {
if (potentialRaw instanceof DerivedNamespaceBehaviour) {
final VirtualNamespaceContext derivedContext = new VirtualNamespaceContext(
}
}
- EffectiveModelContext build() throws ReactorException {
+ ReactorDeclaredModel build() throws ReactorException {
executePhases();
return transform();
}
return transformEffective();
}
- private EffectiveModelContext transform() {
+ private ReactorDeclaredModel transform() {
checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
final List<DeclaredStatement<?>> rootStatements = new ArrayList<>(sources.size());
for (final SourceSpecificContext source : sources) {
- rootStatements.add(source.getRoot().buildDeclared());
+ rootStatements.add(source.getRoot().declared());
}
- return new EffectiveModelContext(rootStatements);
+ return new ReactorDeclaredModel(rootStatements);
}
private SomeModifiersUnresolvedException propagateException(final SourceSpecificContext source,
final RuntimeException cause) throws SomeModifiersUnresolvedException {
- final SourceIdentifier sourceId = StmtContextUtils.createSourceIdentifier(source.getRoot());
+ final SourceIdentifier sourceId = 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);
}
+ private static SourceIdentifier createSourceIdentifier(final StmtContext<?, ?, ?> root) {
+ final QNameModule qNameModule = root.getFromNamespace(ModuleCtxToModuleQName.class, root);
+ final String arg = root.getRawArgument();
+ if (qNameModule != null) {
+ // creates SourceIdentifier for a module
+ return RevisionSourceIdentifier.create(arg, qNameModule.getRevision());
+ }
+
+ // creates SourceIdentifier for a submodule
+ return RevisionSourceIdentifier.create(arg, StmtContextUtils.getLatestRevision(root.declaredSubstatements()));
+ }
+
@SuppressWarnings("checkstyle:illegalCatch")
private EffectiveSchemaContext transformEffective() throws ReactorException {
checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL);
final List<DeclaredStatement<?>> rootStatements = new ArrayList<>(sources.size());
final List<EffectiveStatement<?, ?>> rootEffectiveStatements = new ArrayList<>(sources.size());
- try {
- for (final SourceSpecificContext source : sources) {
- final RootStatementContext<?, ?, ?> root = source.getRoot();
- try {
- rootStatements.add(root.buildDeclared());
- rootEffectiveStatements.add(root.buildEffective());
- } catch (final RuntimeException ex) {
- throw propagateException(source, ex);
- }
+ for (final SourceSpecificContext source : sources) {
+ final RootStatementContext<?, ?, ?> root = source.getRoot();
+ try {
+ rootStatements.add(root.declared());
+ rootEffectiveStatements.add(root.buildEffective());
+ } catch (final RuntimeException ex) {
+ throw propagateException(source, ex);
}
- } finally {
- RecursiveObjectLeaker.cleanup();
}
sealMutableStatements();
}
@SuppressWarnings("checkstyle:illegalCatch")
- private void loadPhaseStatementsFor(final Set<SourceSpecificContext> sources) throws ReactorException {
- for (final SourceSpecificContext source : sources) {
+ private void loadPhaseStatementsFor(final Set<SourceSpecificContext> srcs) throws ReactorException {
+ for (final SourceSpecificContext source : srcs) {
try {
source.loadStatements();
} catch (final RuntimeException ex) {
SomeModifiersUnresolvedException buildFailure = null;
for (final SourceSpecificContext failedSource : sourcesToProgress) {
final Optional<SourceException> optSourceEx = failedSource.failModifiers(currentPhase);
- if (!optSourceEx.isPresent()) {
+ if (optSourceEx.isEmpty()) {
continue;
}
int count = 1;
for (final Throwable t : suppressed) {
- // FIXME: this should be configured in the appender, really
- if (LOG.isDebugEnabled()) {
- LOG.error("Error {}: {}", count, t.getMessage(), t);
- } else {
- LOG.error("Error {}: {}", count, t.getMessage());
- }
-
+ LOG.error("Error {}: {}", count, t.getMessage());
count++;
}
}
if (!addedCause) {
addedCause = true;
- final SourceIdentifier sourceId = StmtContextUtils.createSourceIdentifier(failedSource.getRoot());
+ final SourceIdentifier sourceId = createSourceIdentifier(failedSource.getRoot());
buildFailure = new SomeModifiersUnresolvedException(currentPhase, sourceId, sourceEx);
} else {
buildFailure.addSuppressed(sourceEx);