import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
+import java.io.IOException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import org.eclipse.jdt.annotation.NonNull;
import org.gaul.modernizer_maven_annotations.SuppressModernizer;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParser;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
import org.opendaylight.yangtools.yang.model.repo.api.EffectiveModelContextFactory;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.StatementContext;
-import org.opendaylight.yangtools.yang.parser.impl.DefaultReactors;
import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource;
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.BuildAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
.weakValues().build();
private final Cache<Collection<SourceIdentifier>, EffectiveModelContext> semVerCache = CacheBuilder.newBuilder()
.weakValues().build();
- private final @NonNull SchemaRepository repository;
+ private final @NonNull SharedSchemaRepository repository;
private final @NonNull SchemaContextFactoryConfiguration config;
- SharedSchemaContextFactory(final @NonNull SchemaRepository repository,
- final @NonNull SchemaContextFactoryConfiguration config) {
+ SharedSchemaContextFactory(final @NonNull SharedSchemaRepository repository,
+ final @NonNull SchemaContextFactoryConfiguration config) {
this.repository = requireNonNull(repository);
this.config = requireNonNull(config);
}
final @NonNull Collection<SourceIdentifier> requiredSources) {
return createSchemaContext(requiredSources,
config.getStatementParserMode() == StatementParserMode.SEMVER_MODE ? semVerCache : revisionCache,
- new AssembleSources(config));
+ new AssembleSources(repository.factory(), config));
}
private @NonNull ListenableFuture<EffectiveModelContext> createSchemaContext(
}
private static final class AssembleSources implements AsyncFunction<List<ASTSchemaSource>, EffectiveModelContext> {
+ private final @NonNull YangParserFactory parserFactory;
private final @NonNull SchemaContextFactoryConfiguration config;
private final @NonNull Function<ASTSchemaSource, SourceIdentifier> getIdentifier;
- private AssembleSources(final @NonNull SchemaContextFactoryConfiguration config) {
+ private AssembleSources(final @NonNull YangParserFactory parserFactory,
+ final @NonNull SchemaContextFactoryConfiguration config) {
+ this.parserFactory = parserFactory;
this.config = config;
switch (config.getStatementParserMode()) {
case SEMVER_MODE:
res.getResolvedSources(), res.getUnsatisfiedImports());
}
- final BuildAction reactor = DefaultReactors.defaultReactor().newBuild(statementParserMode);
- config.getSupportedFeatures().ifPresent(reactor::setSupportedFeatures);
- config.getModulesDeviatedByModules().ifPresent(reactor::setModulesWithSupportedDeviations);
+ final YangParser parser = parserFactory.createParser(statementParserMode);
+ config.getSupportedFeatures().ifPresent(parser::setSupportedFeatures);
+ config.getModulesDeviatedByModules().ifPresent(parser::setModulesWithSupportedDeviations);
- for (final Entry<SourceIdentifier, ASTSchemaSource> e : srcs.entrySet()) {
- final ASTSchemaSource ast = e.getValue();
+ for (final Entry<SourceIdentifier, ASTSchemaSource> entry : srcs.entrySet()) {
+ final ASTSchemaSource ast = entry.getValue();
final ParserRuleContext parserRuleCtx = ast.getAST();
checkArgument(parserRuleCtx instanceof StatementContext, "Unsupported context class %s for source %s",
- parserRuleCtx.getClass(), e.getKey());
+ parserRuleCtx.getClass(), entry.getKey());
- reactor.addSource(YangStatementStreamSource.create(e.getKey(), (StatementContext) parserRuleCtx,
- ast.getSymbolicName().orElse(null)));
+ try {
+ parser.addSource(entry.getValue());
+ } catch (YangSyntaxErrorException | IOException e) {
+ throw new SchemaResolutionException("Failed to add source " + entry.getKey(), e);
+ }
}
final EffectiveModelContext schemaContext;
try {
- schemaContext = reactor.buildEffective();
- } catch (final ReactorException ex) {
- throw new SchemaResolutionException("Failed to resolve required models", ex.getSourceIdentifier(), ex);
+ schemaContext = parser.buildEffectiveModel();
+ } catch (final YangParserException e) {
+ throw new SchemaResolutionException("Failed to resolve required models", e);
}
return immediateFluentFuture(schemaContext);
import org.kohsuke.MetaInfServices;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
import org.opendaylight.yangtools.yang.model.repo.api.EffectiveModelContextFactory;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration;
import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
import org.opendaylight.yangtools.yang.model.repo.util.AbstractSchemaRepository;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserFactoryImpl;
/**
* A {@link SchemaRepository} which allows sharing of {@link SchemaContext} as long as their specification is the same.
});
private final @NonNull String id;
+ private final @NonNull YangParserFactory factory;
+
+ public SharedSchemaRepository() {
+ this("unnamed");
+ }
public SharedSchemaRepository(final String id) {
+ this(id, new YangParserFactoryImpl());
+ }
+
+ public SharedSchemaRepository(final String id, final YangParserFactory factory) {
this.id = requireNonNull(id);
+ this.factory = requireNonNull(factory);
}
@Override
return cacheByConfig.getUnchecked(config);
}
+ @NonNull YangParserFactory factory() {
+ return factory;
+ }
+
@Override
public String toString() {
return "SchemaRepository: " + id;
*/
package org.opendaylight.yangtools.yang.parser.repo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.SetMultimap;
import com.google.common.util.concurrent.ListenableFuture;
public void shouldFailOnAttemptToDeviateTheSameModule2() throws Exception {
final ListenableFuture<EffectiveModelContext> lf = createSchemaContext(null, BAR_INVALID, BAZ_INVALID);
assertTrue(lf.isDone());
- try {
- lf.get();
- fail("Deviation that targets the same module as the one it is defined is forbidden.");
- } catch (final ExecutionException ex) {
- final Throwable cause = ex.getCause().getCause().getCause();
- assertTrue(cause instanceof InferenceException);
- assertTrue(cause.getMessage()
- .startsWith("Deviation must not target the same module as the one it is defined in"));
- }
+
+ final ExecutionException ex = assertThrows(ExecutionException.class, lf::get);
+ final Throwable cause = Throwables.getRootCause(ex);
+ assertThat(cause, instanceOf(InferenceException.class));
+ assertThat(cause.getMessage(),
+ startsWith("Deviation must not target the same module as the one it is defined in"));
}
private static SettableSchemaProvider<ASTSchemaSource> getImmediateYangSourceProviderFromResource(