X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fstmt%2Freactor%2FBuildGlobalContext.java;h=62822474d7042f4659c9bde7afcaced862b000ef;hb=bf55e6f6cc2a321af90aeacb974a1f7cf26be393;hp=14d450d56714d76082c7735d372e65e64200954d;hpb=e27979870db1358da1477c6d13b05c510c2045d8;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java index 14d450d567..62822474d7 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java @@ -8,7 +8,6 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import com.google.common.base.Preconditions; -import com.google.common.base.Throwables; import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -22,11 +21,14 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Set; +import java.util.function.Predicate; import javax.annotation.Nonnull; 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.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.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; @@ -39,9 +41,13 @@ 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.source.SourceException; import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource; +import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace; +import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace.SupportedFeatures; 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; @@ -49,36 +55,51 @@ import org.slf4j.LoggerFactory; class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBehaviour.Registry { private static final Logger LOG = LoggerFactory.getLogger(BuildGlobalContext.class); - private static final List PHASE_EXECUTION_ORDER = ImmutableList.builder() - .add(ModelProcessingPhase.SOURCE_LINKAGE) - .add(ModelProcessingPhase.STATEMENT_DEFINITION) - .add(ModelProcessingPhase.FULL_DECLARATION) - .add(ModelProcessingPhase.EFFECTIVE_MODEL) - .build(); + private static final List PHASE_EXECUTION_ORDER = ImmutableList + . 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 Map> definitions = new HashMap<>(); - private final Map,NamespaceBehaviourWithListeners> supportedNamespaces = new HashMap<>(); + private final Map> definitions = new HashMap<>(); + private final Map, NamespaceBehaviourWithListeners> supportedNamespaces = new HashMap<>(); - - private final Map supports; + private final Map supports; private final Set sources = new HashSet<>(); private ModelProcessingPhase currentPhase = ModelProcessingPhase.INIT; private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT; - public BuildGlobalContext(final Map supports) { + private final boolean enabledSemanticVersions; + + public BuildGlobalContext(final Map supports, + final StatementParserMode statementParserMode, final Predicate isFeatureSupported) { super(); this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null"); + Preconditions.checkNotNull(statementParserMode, "Statement parser mode must not be null."); + this.enabledSemanticVersions = statementParserMode == StatementParserMode.SEMVER_MODE; + + addToNs(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES, + Preconditions.checkNotNull(isFeatureSupported, "Supported feature predicate must not be null.")); } - public BuildGlobalContext(final Map supports, final Map> supportedValidation) { + public BuildGlobalContext(final Map supports, + final Map> supportedValidation, + final StatementParserMode statementParserMode, final Predicate isFeatureSupported) { super(); this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null"); + Preconditions.checkNotNull(statementParserMode, "Statement parser mode must not be null."); + this.enabledSemanticVersions = statementParserMode == StatementParserMode.SEMVER_MODE; - Set>> validationBundles = supportedValidation.entrySet(); - for (Entry> validationBundle : validationBundles) { + for (Entry> validationBundle : supportedValidation.entrySet()) { addToNs(ValidationBundlesNamespace.class, validationBundle.getKey(), validationBundle.getValue()); } + + addToNs(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES, + Preconditions.checkNotNull(isFeatureSupported, "Supported feature predicate must not be null.")); + } + + public boolean isEnabledSemanticVersioning() { + return enabledSemanticVersions; } public StatementSupportBundle getSupportsForPhase(final ModelProcessingPhase currentPhase) { @@ -86,7 +107,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh } public void addSource(@Nonnull final StatementStreamSource source) { - sources.add(new SourceSpecificContext(this,source)); + sources.add(new SourceSpecificContext(this, source)); } @Override @@ -105,35 +126,36 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh } @Override - public > NamespaceBehaviourWithListeners getNamespaceBehaviour(final Class type) { + public > NamespaceBehaviourWithListeners getNamespaceBehaviour( + final Class type) { NamespaceBehaviourWithListeners potential = supportedNamespaces.get(type); if (potential == null) { NamespaceBehaviour potentialRaw = supports.get(currentPhase).getNamespaceBehaviour(type); - if(potentialRaw != null) { + if (potentialRaw != null) { potential = createNamespaceContext(potentialRaw); supportedNamespaces.put(type, potential); } else { - throw new NamespaceNotAvailableException( - "Namespace " + type + " is not available in phase " + currentPhase); + throw new NamespaceNotAvailableException("Namespace " + type + " is not available in phase " + + currentPhase); } } Verify.verify(type.equals(potential.getIdentifier())); - /* - * Safe cast, previous checkState checks equivalence of key from which type argument are - * derived + /* + * Safe cast, previous checkState checks equivalence of key from which + * type argument are derived */ return (NamespaceBehaviourWithListeners) potential; } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({ "unchecked", "rawtypes" }) private > NamespaceBehaviourWithListeners createNamespaceContext( final NamespaceBehaviour potentialRaw) { if (potentialRaw instanceof DerivedNamespaceBehaviour) { - VirtualNamespaceContext derivedContext = - new VirtualNamespaceContext((DerivedNamespaceBehaviour) potentialRaw); - getNamespaceBehaviour(((DerivedNamespaceBehaviour) potentialRaw).getDerivedFrom()) - .addDerivedNamespace(derivedContext); + VirtualNamespaceContext derivedContext = new VirtualNamespaceContext( + (DerivedNamespaceBehaviour) potentialRaw); + getNamespaceBehaviour(((DerivedNamespaceBehaviour) potentialRaw).getDerivedFrom()).addDerivedNamespace( + derivedContext); return derivedContext; } return new SimpleNamespaceContext<>(potentialRaw); @@ -141,9 +163,9 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh public StatementDefinitionContext getStatementDefinition(final QName name) { StatementDefinitionContext potential = definitions.get(name); - if(potential == null) { + if (potential == null) { StatementSupport potentialRaw = supports.get(currentPhase).getStatementDefinition(name); - if(potentialRaw != null) { + if (potentialRaw != null) { potential = new StatementDefinitionContext<>(potentialRaw); definitions.put(name, potential); } @@ -152,7 +174,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh } public EffectiveModelContext build() throws SourceException, ReactorException { - for(ModelProcessingPhase phase : PHASE_EXECUTION_ORDER) { + for (ModelProcessingPhase phase : PHASE_EXECUTION_ORDER) { startPhase(phase); loadPhaseStatements(); completePhaseActions(); @@ -163,16 +185,15 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh private EffectiveModelContext transform() { Preconditions.checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL); - List> rootStatements = new ArrayList<>(); - for(SourceSpecificContext source : sources) { - DeclaredStatement root = source.getRoot().buildDeclared(); - rootStatements.add(root); + List> rootStatements = new ArrayList<>(sources.size()); + for (SourceSpecificContext source : sources) { + rootStatements.add(source.getRoot().buildDeclared()); } return new EffectiveModelContext(rootStatements); } - public EffectiveSchemaContext buildEffective() throws SourceException, ReactorException { - for(ModelProcessingPhase phase : PHASE_EXECUTION_ORDER) { + public EffectiveSchemaContext buildEffective() throws ReactorException { + for (ModelProcessingPhase phase : PHASE_EXECUTION_ORDER) { startPhase(phase); loadPhaseStatements(); completePhaseActions(); @@ -181,44 +202,56 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh return transformEffective(); } - private EffectiveSchemaContext transformEffective() { + private EffectiveSchemaContext transformEffective() throws ReactorException { Preconditions.checkState(finishedPhase == ModelProcessingPhase.EFFECTIVE_MODEL); - List> rootStatements = new ArrayList<>(); - List> rootEffectiveStatements = new ArrayList<>(); - - for(SourceSpecificContext source : sources) { - DeclaredStatement root = source.getRoot().buildDeclared(); - rootStatements.add(root); + List> rootStatements = new ArrayList<>(sources.size()); + List> rootEffectiveStatements = new ArrayList<>(sources.size()); + SourceIdentifier sourceId = null; - EffectiveStatement rootEffective = source.getRoot().buildEffective(); - rootEffectiveStatements.add(rootEffective); + try { + for (SourceSpecificContext source : sources) { + final RootStatementContext root = source.getRoot(); + sourceId = Utils.createSourceIdentifier(root); + rootStatements.add(root.buildDeclared()); + rootEffectiveStatements.add(root.buildEffective()); + } + } catch (SourceException ex) { + throw new SomeModifiersUnresolvedException(currentPhase, sourceId, ex); + } finally { + RecursiveObjectLeaker.cleanup(); } - return new EffectiveSchemaContext(rootStatements,rootEffectiveStatements); + return new EffectiveSchemaContext(rootStatements, rootEffectiveStatements); } private void startPhase(final ModelProcessingPhase phase) { Preconditions.checkState(Objects.equals(finishedPhase, phase.getPreviousPhase())); - for(SourceSpecificContext source : sources) { + for (SourceSpecificContext source : sources) { source.startPhase(phase); } currentPhase = phase; } - private void loadPhaseStatements() throws SourceException { + private void loadPhaseStatements() throws ReactorException { Preconditions.checkState(currentPhase != null); - for(SourceSpecificContext source : sources) { - source.loadStatements(); + for (SourceSpecificContext source : sources) { + try { + source.loadStatements(); + } catch (SourceException ex) { + final SourceIdentifier sourceId = Utils.createSourceIdentifier(source.getRoot()); + throw new SomeModifiersUnresolvedException(currentPhase, sourceId, ex); + } } } - private SomeModifiersUnresolvedException addSourceExceptions(final SomeModifiersUnresolvedException buildFailure, - final List sourcesToProgress) { + private SomeModifiersUnresolvedException addSourceExceptions(final List sourcesToProgress) { boolean addedCause = false; + SomeModifiersUnresolvedException buildFailure = null; for (SourceSpecificContext failedSource : sourcesToProgress) { final SourceException sourceEx = failedSource.failModifiers(currentPhase); - // Workaround for broken logging implementations which ignore suppressed exceptions + // Workaround for broken logging implementations which ignore + // suppressed exceptions Throwable cause = sourceEx.getCause() != null ? sourceEx.getCause() : sourceEx; if (LOG.isDebugEnabled()) { LOG.error("Failed to parse YANG from source {}", failedSource, sourceEx); @@ -243,9 +276,10 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh } } - if(!addedCause) { + if (!addedCause) { addedCause = true; - buildFailure.initCause(sourceEx); + final SourceIdentifier sourceId = Utils.createSourceIdentifier(failedSource.getRoot()); + buildFailure = new SomeModifiersUnresolvedException(currentPhase, sourceId, sourceEx); } else { buildFailure.addSuppressed(sourceEx); } @@ -253,44 +287,46 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh return buildFailure; } - private void completePhaseActions() throws ReactorException { + private void completePhaseActions() throws ReactorException { Preconditions.checkState(currentPhase != null); List sourcesToProgress = Lists.newArrayList(sources); + SourceIdentifier sourceId = null; try { boolean progressing = true; - while(progressing) { + while (progressing) { // We reset progressing to false. progressing = false; Iterator currentSource = sourcesToProgress.iterator(); - while(currentSource.hasNext()) { + while (currentSource.hasNext()) { SourceSpecificContext nextSourceCtx = currentSource.next(); + sourceId = Utils.createSourceIdentifier(nextSourceCtx.getRoot()); PhaseCompletionProgress sourceProgress = nextSourceCtx.tryToCompletePhase(currentPhase); switch (sourceProgress) { - case FINISHED: - currentSource.remove(); - // Fallback to progress, since we were able to make progress in computation - case PROGRESS: - progressing = true; - break; - case NO_PROGRESS: - // Noop - break; - default: - throw new IllegalStateException("Unsupported phase progress " + sourceProgress); + case FINISHED: + currentSource.remove(); + // Fallback to progress, since we were able to make + // progress in computation + case PROGRESS: + progressing = true; + break; + case NO_PROGRESS: + // Noop + break; + default: + throw new IllegalStateException("Unsupported phase progress " + sourceProgress); } } } } catch (SourceException e) { - throw Throwables.propagate(e); + throw new SomeModifiersUnresolvedException(currentPhase, sourceId, e); } - if(!sourcesToProgress.isEmpty()) { - SomeModifiersUnresolvedException buildFailure = new SomeModifiersUnresolvedException(currentPhase); - buildFailure = addSourceExceptions(buildFailure, sourcesToProgress); + if (!sourcesToProgress.isEmpty()) { + final SomeModifiersUnresolvedException buildFailure = addSourceExceptions(sourcesToProgress); throw buildFailure; } } - private void endPhase(final ModelProcessingPhase phase) { + private void endPhase(final ModelProcessingPhase phase) { Preconditions.checkState(currentPhase == phase); finishedPhase = currentPhase; } @@ -298,5 +334,4 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh public Set getSources() { return sources; } - }