Introduce IRSchemaSource 05/92305/6
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 27 Aug 2020 09:51:02 +0000 (11:51 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 7 Sep 2020 08:46:22 +0000 (10:46 +0200)
Rather than using ASTSchemaSource, use a dedicated IRSchemaSource,
which ends up being the replacement for ASTSchemaSource. We are
undoing some work previously done, but it allows easier backporting.

JIRA: YANGTOOLS-1130
Change-Id: Ifdeaa0d053558eda12432264fb768ed0d821468f
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
18 files changed:
yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesProcessor.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaContextFactory.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/YangTextSchemaContextResolver.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/MultipleRevImportBug6875Test.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/OpenconfigVerSharedSchemaRepositoryTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SchemaContextFactoryDeviationsTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaContextFactoryTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaRepositoryTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/repo/SharedSchemaRepositoryWithFeaturesTest.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/ir/AntlrSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/ir/IRSchemaSource.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/ASTSchemaSource.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/ArgumentContextUtils.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/TextToASTTransformer.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/TextToIRTransformer.java [new file with mode: 0644]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangModelDependencyInfo.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/YangStatementStreamSource.java

index 72ed01e62880114f2e87bbcda218924b23c01f66..ce884c15c49826751ce95cbc8cfe248c8786b207 100644 (file)
@@ -41,11 +41,10 @@ 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.SchemaSourceException;
 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
 import org.opendaylight.yangtools.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
 import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator.ImportResolutionMode;
@@ -269,21 +268,21 @@ class YangToSourcesProcessor {
             final YangParser parser = parserFactory.createParser(parserMode);
             final List<YangTextSchemaSource> sourcesInProject = new ArrayList<>(yangFilesInProject.size());
 
-            final List<Entry<YangTextSchemaSource, ASTSchemaSource>> parsed = yangFilesInProject.parallelStream()
+            final List<Entry<YangTextSchemaSource, IRSchemaSource>> parsed = yangFilesInProject.parallelStream()
                     .map(file -> {
                         final YangTextSchemaSource textSource = YangTextSchemaSource.forFile(file);
                         try {
                             return new SimpleImmutableEntry<>(textSource,
-                                    TextToASTTransformer.transformText(textSource));
-                        } catch (YangSyntaxErrorException | SchemaSourceException | IOException e) {
+                                    TextToIRTransformer.transformText(textSource));
+                        } catch (YangSyntaxErrorException | IOException e) {
                             throw new IllegalArgumentException("Failed to parse " + file, e);
                         }
                     })
                     .collect(Collectors.toList());
 
-            for (final Entry<YangTextSchemaSource, ASTSchemaSource> entry : parsed) {
+            for (final Entry<YangTextSchemaSource, IRSchemaSource> entry : parsed) {
                 final YangTextSchemaSource textSource = entry.getKey();
-                final ASTSchemaSource astSource = entry.getValue();
+                final IRSchemaSource astSource = entry.getValue();
                 parser.addSource(astSource);
 
                 if (!astSource.getIdentifier().equals(textSource.getIdentifier())) {
index 58151ed70104598925f155e4a71175ee6b572f5a..9abb87ce7ee3f522353cc8cdcb7de056702a6a3d 100644 (file)
@@ -29,6 +29,7 @@ import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.api.YinDomSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.api.YinTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.api.YinXmlSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangStatementStreamSource;
 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YinStatementStreamSource;
@@ -40,7 +41,7 @@ import org.xml.sax.SAXException;
 
 final class YangParserImpl implements YangParser {
     private static final @NonNull Collection<Class<? extends SchemaSourceRepresentation>> REPRESENTATIONS =
-            ImmutableList.of(ASTSchemaSource.class, YangTextSchemaSource.class,
+            ImmutableList.of(IRSchemaSource.class, ASTSchemaSource.class, YangTextSchemaSource.class,
                 YinDomSchemaSource.class, YinXmlSchemaSource.class, YinTextSchemaSource.class);
 
     private final BuildAction buildAction;
@@ -113,7 +114,9 @@ final class YangParserImpl implements YangParser {
     private static StatementStreamSource sourceToStatementStream(final SchemaSourceRepresentation source)
             throws IOException, YangSyntaxErrorException {
         requireNonNull(source);
-        if (source instanceof ASTSchemaSource) {
+        if (source instanceof IRSchemaSource) {
+            return YangStatementStreamSource.create((IRSchemaSource) source);
+        } else if (source instanceof ASTSchemaSource) {
             return YangStatementStreamSource.create((ASTSchemaSource) source);
         } else if (source instanceof YangTextSchemaSource) {
             return YangStatementStreamSource.create((YangTextSchemaSource) source);
index 87ab72d55587327d390d8cf57d0fdc5b41658fee..e9a4fc6d842f55158ae155a19327b69881e30f84 100644 (file)
@@ -35,6 +35,7 @@ import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import org.eclipse.jdt.annotation.NonNull;
 import org.gaul.modernizer_maven_annotations.SuppressModernizer;
+import org.opendaylight.yangtools.concepts.SemVer;
 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;
@@ -43,9 +44,10 @@ 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.SchemaResolutionException;
+import org.opendaylight.yangtools.yang.model.repo.api.SemVerSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.YangModelDependencyInfo;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
 import org.slf4j.Logger;
@@ -78,7 +80,7 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
     private @NonNull ListenableFuture<EffectiveModelContext> createSchemaContext(
             final Collection<SourceIdentifier> requiredSources,
             final Cache<Collection<SourceIdentifier>, EffectiveModelContext> cache,
-            final AsyncFunction<List<ASTSchemaSource>, EffectiveModelContext> assembleSources) {
+            final AsyncFunction<List<IRSchemaSource>, EffectiveModelContext> assembleSources) {
         // Make sources unique
         final List<SourceIdentifier> uniqueSourceIdentifiers = deDuplicateSources(requiredSources);
 
@@ -89,7 +91,7 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
         }
 
         // Request all sources be loaded
-        ListenableFuture<List<ASTSchemaSource>> sf = Futures.allAsList(Collections2.transform(uniqueSourceIdentifiers,
+        ListenableFuture<List<IRSchemaSource>> sf = Futures.allAsList(Collections2.transform(uniqueSourceIdentifiers,
             this::requestSource));
 
         // Detect mismatch between requested Source IDs and IDs that are extracted from parsed source
@@ -129,8 +131,8 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
         return rf;
     }
 
-    private ListenableFuture<ASTSchemaSource> requestSource(final @NonNull SourceIdentifier identifier) {
-        return repository.getSchemaSource(identifier, ASTSchemaSource.class);
+    private ListenableFuture<IRSchemaSource> requestSource(final @NonNull SourceIdentifier identifier) {
+        return repository.getSchemaSource(identifier, IRSchemaSource.class);
     }
 
     /**
@@ -151,8 +153,8 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
     }
 
     @SuppressModernizer
-    private static final class SourceIdMismatchDetector implements Function<List<ASTSchemaSource>,
-            List<ASTSchemaSource>> {
+    private static final class SourceIdMismatchDetector implements Function<List<IRSchemaSource>,
+            List<IRSchemaSource>> {
         private final List<SourceIdentifier> sourceIdentifiers;
 
         SourceIdMismatchDetector(final List<SourceIdentifier> sourceIdentifiers) {
@@ -160,14 +162,14 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
         }
 
         @Override
-        public List<ASTSchemaSource> apply(final List<ASTSchemaSource> input) {
-            final Map<SourceIdentifier, ASTSchemaSource> filtered = new LinkedHashMap<>();
+        public List<IRSchemaSource> apply(final List<IRSchemaSource> input) {
+            final Map<SourceIdentifier, IRSchemaSource> filtered = new LinkedHashMap<>();
 
             for (int i = 0; i < input.size(); i++) {
 
                 final SourceIdentifier expectedSId = sourceIdentifiers.get(i);
-                final ASTSchemaSource astSchemaSource = input.get(i);
-                final SourceIdentifier realSId = astSchemaSource.getIdentifier();
+                final IRSchemaSource irSchemaSource = input.get(i);
+                final SourceIdentifier realSId = irSchemaSource.getIdentifier();
 
                 if (!expectedSId.equals(realSId)) {
                     LOG.warn("Source identifier mismatch for module \"{}\", requested as {} but actually is {}. "
@@ -178,17 +180,17 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
                     LOG.warn("Duplicate source for module {} detected in reactor", realSId);
                 }
 
-                filtered.put(realSId, astSchemaSource);
+                filtered.put(realSId, irSchemaSource);
 
             }
             return ImmutableList.copyOf(filtered.values());
         }
     }
 
-    private static final class AssembleSources implements AsyncFunction<List<ASTSchemaSource>, EffectiveModelContext> {
+    private static final class AssembleSources implements AsyncFunction<List<IRSchemaSource>, EffectiveModelContext> {
         private final @NonNull YangParserFactory parserFactory;
         private final @NonNull SchemaContextFactoryConfiguration config;
-        private final @NonNull Function<ASTSchemaSource, SourceIdentifier> getIdentifier;
+        private final @NonNull Function<IRSchemaSource, SourceIdentifier> getIdentifier;
 
         private AssembleSources(final @NonNull YangParserFactory parserFactory,
                 final @NonNull SchemaContextFactoryConfiguration config) {
@@ -196,19 +198,19 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
             this.config = config;
             switch (config.getStatementParserMode()) {
                 case SEMVER_MODE:
-                    this.getIdentifier = ASTSchemaSource::getSemVerIdentifier;
+                    this.getIdentifier = AssembleSources::getSemVerIdentifier;
                     break;
                 default:
-                    this.getIdentifier = ASTSchemaSource::getIdentifier;
+                    this.getIdentifier = IRSchemaSource::getIdentifier;
             }
         }
 
         @Override
-        public FluentFuture<EffectiveModelContext> apply(final List<ASTSchemaSource> sources)
+        public FluentFuture<EffectiveModelContext> apply(final List<IRSchemaSource> sources)
                 throws SchemaResolutionException, ReactorException {
-            final Map<SourceIdentifier, ASTSchemaSource> srcs = Maps.uniqueIndex(sources, getIdentifier);
+            final Map<SourceIdentifier, IRSchemaSource> srcs = Maps.uniqueIndex(sources, getIdentifier);
             final Map<SourceIdentifier, YangModelDependencyInfo> deps =
-                    Maps.transformValues(srcs, ASTSchemaSource::getDependencyInformation);
+                    Maps.transformValues(srcs, YangModelDependencyInfo::forIR);
 
             LOG.debug("Resolving dependency reactor {}", deps);
 
@@ -226,10 +228,9 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
             config.getSupportedFeatures().ifPresent(parser::setSupportedFeatures);
             config.getModulesDeviatedByModules().ifPresent(parser::setModulesWithSupportedDeviations);
 
-            for (final Entry<SourceIdentifier, ASTSchemaSource> entry : srcs.entrySet()) {
-                final ASTSchemaSource ast = entry.getValue();
+            for (final Entry<SourceIdentifier, IRSchemaSource> entry : srcs.entrySet()) {
                 try {
-                    parser.addSource(ast);
+                    parser.addSource(entry.getValue());
                 } catch (YangSyntaxErrorException | IOException e) {
                     throw new SchemaResolutionException("Failed to add source " + entry.getKey(), e);
                 }
@@ -244,5 +245,15 @@ final class SharedSchemaContextFactory implements EffectiveModelContextFactory {
 
             return immediateFluentFuture(schemaContext);
         }
+
+        private static SemVerSourceIdentifier getSemVerIdentifier(final IRSchemaSource source) {
+            final SourceIdentifier identifier = source.getIdentifier();
+            final SemVer semver = YangModelDependencyInfo.findSemanticVersion(source.getRootStatement(), identifier);
+            if (identifier instanceof SemVerSourceIdentifier && semver == null) {
+                return (SemVerSourceIdentifier) identifier;
+            }
+
+            return SemVerSourceIdentifier.create(identifier.getName(), identifier.getRevision(), semver);
+        }
     }
 }
index bb6b4b5c54b85b60bd96129d9a326417d8f97bb9..dcd98a40cba77d885e997a4cd087ec25c34c745c 100644 (file)
@@ -53,8 +53,10 @@ import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
 import org.opendaylight.yangtools.yang.model.repo.util.InMemorySchemaSourceCache;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,7 +68,7 @@ public final class YangTextSchemaContextResolver implements AutoCloseable, Schem
     private final Multimap<SourceIdentifier, YangTextSchemaSource> texts = ArrayListMultimap.create();
     private final AtomicReference<Optional<EffectiveModelContext>> currentSchemaContext =
             new AtomicReference<>(Optional.empty());
-    private final InMemorySchemaSourceCache<ASTSchemaSource> cache;
+    private final InMemorySchemaSourceCache<IRSchemaSource> cache;
     private final SchemaListenerRegistration transReg;
     private final SchemaSourceRegistry registry;
     private final SchemaRepository repository;
@@ -77,10 +79,10 @@ public final class YangTextSchemaContextResolver implements AutoCloseable, Schem
         this.repository = requireNonNull(repository);
         this.registry = requireNonNull(registry);
 
-        final TextToASTTransformer t = TextToASTTransformer.create(repository, registry);
+        final TextToIRTransformer t = TextToIRTransformer.create(repository, registry);
         transReg = registry.registerSchemaSourceListener(t);
 
-        cache = InMemorySchemaSourceCache.createSoftCache(registry, ASTSchemaSource.class, SOURCE_LIFETIME_SECONDS,
+        cache = InMemorySchemaSourceCache.createSoftCache(registry, IRSchemaSource.class, SOURCE_LIFETIME_SECONDS,
             TimeUnit.SECONDS);
     }
 
index 68108c8b25696ccac7e01677b3cb98d877952711..e15da607ac7999c9d59c1d3f0650fce8f50e256f 100644 (file)
@@ -24,8 +24,8 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
 
 public class MultipleRevImportBug6875Test {
     private static final String BAR_NS = "bar";
@@ -39,13 +39,13 @@ public class MultipleRevImportBug6875Test {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
                 "shared-schema-repo-multiple-rev-import-test");
 
-        final SettableSchemaProvider<ASTSchemaSource> foo = getSourceProvider(
+        final SettableSchemaProvider<IRSchemaSource> foo = getSourceProvider(
             "/rfc7950/bug6875/yang1-1/foo.yang");
-        final SettableSchemaProvider<ASTSchemaSource> bar1 = getSourceProvider(
+        final SettableSchemaProvider<IRSchemaSource> bar1 = getSourceProvider(
             "/rfc7950/bug6875/yang1-1/bar@1999-01-01.yang");
-        final SettableSchemaProvider<ASTSchemaSource> bar2 = getSourceProvider(
+        final SettableSchemaProvider<IRSchemaSource> bar2 = getSourceProvider(
             "/rfc7950/bug6875/yang1-1/bar@2017-02-06.yang");
-        final SettableSchemaProvider<ASTSchemaSource> bar3 = getSourceProvider(
+        final SettableSchemaProvider<IRSchemaSource> bar3 = getSourceProvider(
             "/rfc7950/bug6875/yang1-1/bar@1970-01-01.yang");
 
         setAndRegister(sharedSchemaRepository, foo);
@@ -83,11 +83,11 @@ public class MultipleRevImportBug6875Test {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
                 "shared-schema-repo-multiple-rev-import-test");
 
-        final SettableSchemaProvider<ASTSchemaSource> foo = getSourceProvider(
+        final SettableSchemaProvider<IRSchemaSource> foo = getSourceProvider(
             "/rfc7950/bug6875/yang1-0/foo.yang");
-        final SettableSchemaProvider<ASTSchemaSource> bar1 = getSourceProvider(
+        final SettableSchemaProvider<IRSchemaSource> bar1 = getSourceProvider(
             "/rfc7950/bug6875/yang1-0/bar@1999-01-01.yang");
-        final SettableSchemaProvider<ASTSchemaSource> bar2 = getSourceProvider(
+        final SettableSchemaProvider<IRSchemaSource> bar2 = getSourceProvider(
             "/rfc7950/bug6875/yang1-0/bar@2017-02-06.yang");
 
         setAndRegister(sharedSchemaRepository, foo);
@@ -109,16 +109,16 @@ public class MultipleRevImportBug6875Test {
     }
 
     private static void setAndRegister(final SharedSchemaRepository sharedSchemaRepository,
-            final SettableSchemaProvider<ASTSchemaSource> source) {
+            final SettableSchemaProvider<IRSchemaSource> source) {
         source.register(sharedSchemaRepository);
         source.setResult();
     }
 
-    private static SettableSchemaProvider<ASTSchemaSource> getSourceProvider(final String resourceName)
+    private static SettableSchemaProvider<IRSchemaSource> getSourceProvider(final String resourceName)
             throws Exception {
         final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName);
-        return SettableSchemaProvider.createImmediate(TextToASTTransformer.transformText(yangSource),
-            ASTSchemaSource.class);
+        return SettableSchemaProvider.createImmediate(TextToIRTransformer.transformText(yangSource),
+            IRSchemaSource.class);
     }
 
     private static SchemaNode findNode(final SchemaContext context, final Iterable<QName> qnames) {
index 4fa3f12622c6ea2766c71bf4f2b2eb5d0bb3b7b7..a5e624c50957de3c7bf4364b8c1d65f69a442ff2 100644 (file)
@@ -19,8 +19,8 @@ import org.opendaylight.yangtools.yang.model.repo.api.EffectiveModelContextFacto
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration;
 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
 
 public class OpenconfigVerSharedSchemaRepositoryTest {
 
@@ -29,15 +29,15 @@ public class OpenconfigVerSharedSchemaRepositoryTest {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
                 "openconfig-ver-shared-schema-repo-test");
 
-        final SettableSchemaProvider<ASTSchemaSource> bar = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> bar = getImmediateYangSourceProviderFromResource(
                 "/openconfig-version/openconfigver-shared-schema-repository/bar@2016-01-01.yang");
         bar.register(sharedSchemaRepository);
         bar.setResult();
-        final SettableSchemaProvider<ASTSchemaSource> foo = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> foo = getImmediateYangSourceProviderFromResource(
                 "/openconfig-version/openconfigver-shared-schema-repository/foo.yang");
         foo.register(sharedSchemaRepository);
         foo.setResult();
-        final SettableSchemaProvider<ASTSchemaSource> semVer = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> semVer = getImmediateYangSourceProviderFromResource(
                 "/openconfig-version/openconfigver-shared-schema-repository/openconfig-extensions.yang");
         semVer.register(sharedSchemaRepository);
         semVer.setResult();
@@ -61,15 +61,15 @@ public class OpenconfigVerSharedSchemaRepositoryTest {
     public void testSharedSchemaRepository() throws Exception {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository("shared-schema-repo-test");
 
-        final SettableSchemaProvider<ASTSchemaSource> bar = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> bar = getImmediateYangSourceProviderFromResource(
                 "/openconfig-version/shared-schema-repository/bar@2016-01-01.yang");
         bar.register(sharedSchemaRepository);
         bar.setResult();
-        final SettableSchemaProvider<ASTSchemaSource> foo = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> foo = getImmediateYangSourceProviderFromResource(
                 "/openconfig-version/shared-schema-repository/foo.yang");
         foo.register(sharedSchemaRepository);
         foo.setResult();
-        final SettableSchemaProvider<ASTSchemaSource> semVer = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> semVer = getImmediateYangSourceProviderFromResource(
                 "/openconfig-version/shared-schema-repository/openconfig-extensions.yang");
         semVer.register(sharedSchemaRepository);
         semVer.setResult();
@@ -91,10 +91,10 @@ public class OpenconfigVerSharedSchemaRepositoryTest {
         assertEquals(moduleSize, schemaContext.getModules().size());
     }
 
-    static SettableSchemaProvider<ASTSchemaSource> getImmediateYangSourceProviderFromResource(final String resourceName)
+    static SettableSchemaProvider<IRSchemaSource> getImmediateYangSourceProviderFromResource(final String resourceName)
             throws Exception {
         final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName);
-        return SettableSchemaProvider.createImmediate(TextToASTTransformer.transformText(yangSource),
-            ASTSchemaSource.class);
+        return SettableSchemaProvider.createImmediate(TextToIRTransformer.transformText(yangSource),
+            IRSchemaSource.class);
     }
 }
index be8ca50946e1e69aac340398f75eb19c2400d01c..80fba57f96bbffe4868423f8422186faf5a8f1f9 100644 (file)
@@ -34,8 +34,8 @@ import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfig
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
 
 public class SchemaContextFactoryDeviationsTest {
@@ -121,11 +121,11 @@ public class SchemaContextFactoryDeviationsTest {
             startsWith("Deviation must not target the same module as the one it is defined in"));
     }
 
-    private static SettableSchemaProvider<ASTSchemaSource> getImmediateYangSourceProviderFromResource(
+    private static SettableSchemaProvider<IRSchemaSource> getImmediateYangSourceProviderFromResource(
             final String resourceName) throws Exception {
         final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName);
-        return SettableSchemaProvider.createImmediate(TextToASTTransformer.transformText(yangSource),
-                ASTSchemaSource.class);
+        return SettableSchemaProvider.createImmediate(TextToIRTransformer.transformText(yangSource),
+                IRSchemaSource.class);
     }
 
     private static ListenableFuture<EffectiveModelContext> createSchemaContext(
@@ -136,7 +136,7 @@ public class SchemaContextFactoryDeviationsTest {
 
         final Collection<SourceIdentifier> requiredSources = new ArrayList<>();
         for (final String resource : resources) {
-            final SettableSchemaProvider<ASTSchemaSource> yangSource = getImmediateYangSourceProviderFromResource(
+            final SettableSchemaProvider<IRSchemaSource> yangSource = getImmediateYangSourceProviderFromResource(
                     resource);
             yangSource.register(sharedSchemaRepository);
             yangSource.setResult();
index b29e6f87a7a49cde034afcd0c782a107d31e0e72..631a76e3ad2f48a83eed5a28b1ef8f50adee7787 100644 (file)
@@ -24,8 +24,8 @@ import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfig
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
 
 @RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class SharedSchemaContextFactoryTest {
@@ -45,7 +45,7 @@ public class SharedSchemaContextFactoryTest {
         s1 = RevisionSourceIdentifier.create("ietf-inet-types", Revision.of("2010-09-24"));
         s2 = RevisionSourceIdentifier.create("iana-timezones", Revision.of("2012-07-09"));
 
-        final TextToASTTransformer transformer = TextToASTTransformer.create(repository, repository);
+        final TextToIRTransformer transformer = TextToIRTransformer.create(repository, repository);
         repository.registerSchemaSourceListener(transformer);
 
         repository.registerSchemaSource(sourceIdentifier -> immediateFluentFuture(source1),
@@ -71,7 +71,7 @@ public class SharedSchemaContextFactoryTest {
         s1 = source1.getIdentifier();
         s2 = source2.getIdentifier();
 
-        final SettableSchemaProvider<ASTSchemaSource> provider =
+        final SettableSchemaProvider<IRSchemaSource> provider =
                 SharedSchemaRepositoryTest.getImmediateYangSourceProviderFromResource(
                     "/no-revision/imported@2012-12-12.yang");
         provider.setResult();
@@ -80,7 +80,7 @@ public class SharedSchemaContextFactoryTest {
         // Register the same provider under source id without revision
         final SourceIdentifier sIdWithoutRevision = RevisionSourceIdentifier.create(provider.getId().getName());
         repository.registerSchemaSource(provider, PotentialSchemaSource.create(
-                sIdWithoutRevision, ASTSchemaSource.class, PotentialSchemaSource.Costs.IMMEDIATE.getValue()));
+                sIdWithoutRevision, IRSchemaSource.class, PotentialSchemaSource.Costs.IMMEDIATE.getValue()));
 
         final SharedSchemaContextFactory sharedSchemaContextFactory = new SharedSchemaContextFactory(repository,
             config);
index d4717a5e855affdb5698859126a652d1924d1949..7c6a96b039bd4eea212c0f86bcd68b977e9d7245 100644 (file)
@@ -51,8 +51,8 @@ import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceListener;
 import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
 
 public class SharedSchemaRepositoryTest {
 
@@ -65,16 +65,16 @@ public class SharedSchemaRepositoryTest {
         final SourceIdentifier id2 = loadAndRegisterSource(sharedSchemaRepository,
             "/no-revision/imported@2012-12-12.yang");
 
-        ListenableFuture<ASTSchemaSource> source = sharedSchemaRepository.getSchemaSource(idNoRevision,
-            ASTSchemaSource.class);
+        ListenableFuture<IRSchemaSource> source = sharedSchemaRepository.getSchemaSource(idNoRevision,
+            IRSchemaSource.class);
         assertEquals(idNoRevision, source.get().getIdentifier());
-        source = sharedSchemaRepository.getSchemaSource(id2, ASTSchemaSource.class);
+        source = sharedSchemaRepository.getSchemaSource(id2, IRSchemaSource.class);
         assertEquals(id2, source.get().getIdentifier());
     }
 
     private static SourceIdentifier loadAndRegisterSource(final SharedSchemaRepository sharedSchemaRepository,
             final String resourceName) throws Exception {
-        final SettableSchemaProvider<ASTSchemaSource> sourceProvider = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> sourceProvider = getImmediateYangSourceProviderFromResource(
             resourceName);
         sourceProvider.setResult();
         final SourceIdentifier idNoRevision = sourceProvider.getId();
@@ -86,11 +86,11 @@ public class SharedSchemaRepositoryTest {
     public void testSimpleSchemaContext() throws Exception {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
 
-        final SettableSchemaProvider<ASTSchemaSource> remoteInetTypesYang = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> remoteInetTypesYang = getImmediateYangSourceProviderFromResource(
             "/ietf/ietf-inet-types@2010-09-24.yang");
         remoteInetTypesYang.register(sharedSchemaRepository);
-        final ListenableFuture<ASTSchemaSource> registeredSourceFuture = sharedSchemaRepository.getSchemaSource(
-            remoteInetTypesYang.getId(), ASTSchemaSource.class);
+        final ListenableFuture<IRSchemaSource> registeredSourceFuture = sharedSchemaRepository.getSchemaSource(
+            remoteInetTypesYang.getId(), IRSchemaSource.class);
         assertFalse(registeredSourceFuture.isDone());
 
         final EffectiveModelContextFactory fact = sharedSchemaRepository.createEffectiveModelContextFactory();
@@ -123,15 +123,15 @@ public class SharedSchemaRepositoryTest {
     public void testTwoSchemaContextsSharingSource() throws Exception {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
 
-        final SettableSchemaProvider<ASTSchemaSource> remoteInetTypesYang = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> remoteInetTypesYang = getImmediateYangSourceProviderFromResource(
             "/ietf/ietf-inet-types@2010-09-24.yang");
         remoteInetTypesYang.register(sharedSchemaRepository);
         remoteInetTypesYang.setResult();
-        final SettableSchemaProvider<ASTSchemaSource> remoteTopologyYang = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> remoteTopologyYang = getImmediateYangSourceProviderFromResource(
             "/ietf/network-topology@2013-10-21.yang");
         remoteTopologyYang.register(sharedSchemaRepository);
         remoteTopologyYang.setResult();
-        final SettableSchemaProvider<ASTSchemaSource> remoteModuleNoRevYang =
+        final SettableSchemaProvider<IRSchemaSource> remoteModuleNoRevYang =
                 getImmediateYangSourceProviderFromResource("/no-revision/module-without-revision.yang");
         remoteModuleNoRevYang.register(sharedSchemaRepository);
 
@@ -154,7 +154,7 @@ public class SharedSchemaRepositoryTest {
     public void testFailedSchemaContext() throws Exception {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
 
-        final SettableSchemaProvider<ASTSchemaSource> remoteInetTypesYang = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> remoteInetTypesYang = getImmediateYangSourceProviderFromResource(
             "/ietf/ietf-inet-types@2010-09-24.yang");
         remoteInetTypesYang.register(sharedSchemaRepository);
 
@@ -183,12 +183,12 @@ public class SharedSchemaRepositoryTest {
     public void testDifferentCosts() throws Exception {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository("netconf-mounts");
 
-        final SettableSchemaProvider<ASTSchemaSource> immediateInetTypesYang = spy(
+        final SettableSchemaProvider<IRSchemaSource> immediateInetTypesYang = spy(
             getImmediateYangSourceProviderFromResource("/ietf/ietf-inet-types@2010-09-24.yang"));
         immediateInetTypesYang.register(sharedSchemaRepository);
         immediateInetTypesYang.setResult();
 
-        final SettableSchemaProvider<ASTSchemaSource> remoteInetTypesYang = spy(
+        final SettableSchemaProvider<IRSchemaSource> remoteInetTypesYang = spy(
             getRemoteYangSourceProviderFromResource("/ietf/ietf-inet-types@2010-09-24.yang"));
         remoteInetTypesYang.register(sharedSchemaRepository);
         remoteInetTypesYang.setResult();
@@ -284,7 +284,7 @@ public class SharedSchemaRepositoryTest {
             }), PotentialSchemaSource.create(runningId, YangTextSchemaSource.class,
                 PotentialSchemaSource.Costs.REMOTE_IO.getValue()));
 
-        final TextToASTTransformer transformer = TextToASTTransformer.create(sharedSchemaRepository,
+        final TextToIRTransformer transformer = TextToIRTransformer.create(sharedSchemaRepository,
             sharedSchemaRepository);
         sharedSchemaRepository.registerSchemaSourceListener(transformer);
 
@@ -324,17 +324,17 @@ public class SharedSchemaRepositoryTest {
         assertEquals(moduleSize, schemaContext.getModules().size());
     }
 
-    static SettableSchemaProvider<ASTSchemaSource> getRemoteYangSourceProviderFromResource(final String resourceName)
+    static SettableSchemaProvider<IRSchemaSource> getRemoteYangSourceProviderFromResource(final String resourceName)
             throws Exception {
         final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName);
-        return SettableSchemaProvider.createRemote(TextToASTTransformer.transformText(yangSource),
-            ASTSchemaSource.class);
+        return SettableSchemaProvider.createRemote(TextToIRTransformer.transformText(yangSource),
+            IRSchemaSource.class);
     }
 
-    static SettableSchemaProvider<ASTSchemaSource> getImmediateYangSourceProviderFromResource(final String resourceName)
+    static SettableSchemaProvider<IRSchemaSource> getImmediateYangSourceProviderFromResource(final String resourceName)
             throws Exception {
         final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName);
-        return SettableSchemaProvider.createImmediate(TextToASTTransformer.transformText(yangSource),
-            ASTSchemaSource.class);
+        return SettableSchemaProvider.createImmediate(TextToIRTransformer.transformText(yangSource),
+            IRSchemaSource.class);
     }
 }
index df0c09686bcccb123e82b606d4ef305f4a2f5cf1..1447bab49914c949444aa5a933b4340d44e882c7 100644 (file)
@@ -25,8 +25,8 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 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.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
-import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToIRTransformer;
 
 public class SharedSchemaRepositoryWithFeaturesTest {
 
@@ -37,7 +37,7 @@ public class SharedSchemaRepositoryWithFeaturesTest {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
                 "shared-schema-repo-with-features-test");
 
-        final SettableSchemaProvider<ASTSchemaSource> foobar = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> foobar = getImmediateYangSourceProviderFromResource(
             "/if-feature-resolution-test/shared-schema-repository/foobar.yang");
         foobar.register(sharedSchemaRepository);
         foobar.setResult();
@@ -77,7 +77,7 @@ public class SharedSchemaRepositoryWithFeaturesTest {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
                 "shared-schema-repo-with-features-test");
 
-        final SettableSchemaProvider<ASTSchemaSource> foobar = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> foobar = getImmediateYangSourceProviderFromResource(
             "/if-feature-resolution-test/shared-schema-repository/foobar.yang");
         foobar.register(sharedSchemaRepository);
         foobar.setResult();
@@ -119,7 +119,7 @@ public class SharedSchemaRepositoryWithFeaturesTest {
         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
                 "shared-schema-repo-with-features-test");
 
-        final SettableSchemaProvider<ASTSchemaSource> foobar = getImmediateYangSourceProviderFromResource(
+        final SettableSchemaProvider<IRSchemaSource> foobar = getImmediateYangSourceProviderFromResource(
             "/if-feature-resolution-test/shared-schema-repository/foobar.yang");
         foobar.register(sharedSchemaRepository);
         foobar.setResult();
@@ -143,11 +143,11 @@ public class SharedSchemaRepositoryWithFeaturesTest {
         assertNotNull(testLeafC);
     }
 
-    private static SettableSchemaProvider<ASTSchemaSource> getImmediateYangSourceProviderFromResource(
+    private static SettableSchemaProvider<IRSchemaSource> getImmediateYangSourceProviderFromResource(
             final String resourceName) throws Exception {
         final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName);
-        return SettableSchemaProvider.createImmediate(TextToASTTransformer.transformText(yangSource),
-            ASTSchemaSource.class);
+        return SettableSchemaProvider.createImmediate(TextToIRTransformer.transformText(yangSource),
+            IRSchemaSource.class);
     }
 
     private static void assertSchemaContext(final SchemaContext schemaContext, final int moduleSize) {
index b215c218a9f245a1ba94fea0efcfcdcc8210c8df..a185ae651ad143c7fa756231817a418f897ee152 100644 (file)
@@ -56,17 +56,28 @@ public final class AntlrSupport {
     }
 
     /**
-     * Create an {@link IRStatement} from a parsed {@link StatementContext}.
+     * Create an {@link IRStatement} from a parsed {@link FileContext}.
      *
      * @param file ANTLR file context
      * @return A new IRStatement
      * @throws NullPointerException if {@code file} is null or it does not contain a root statement
      */
     public static @NonNull IRStatement createStatement(final FileContext file) {
-        return new AntlrSupport().createStatement(file.statement());
+        return createStatement(file.statement());
+    }
+
+    /**
+     * Create an {@link IRStatement} from a parsed {@link StatementContext}.
+     *
+     * @param stmt ANTLR statement context
+     * @return A new IRStatement
+     * @throws NullPointerException if {@code stmt} is null
+     */
+    public static @NonNull IRStatement createStatement(final StatementContext stmt) {
+        return new AntlrSupport().statementOf(stmt);
     }
 
-    private @NonNull IRStatement createStatement(final StatementContext stmt) {
+    private @NonNull IRStatement statementOf(final StatementContext stmt) {
         final ParseTree firstChild = stmt.getChild(0);
         verify(firstChild instanceof KeywordContext, "Unexpected shape of %s", stmt);
 
@@ -94,7 +105,7 @@ public final class AntlrSupport {
 
         switch (statements.size()) {
             case 0:
-                return createStatement(keyword, argument, line, column);
+                return statementOf(keyword, argument, line, column);
             case 1:
                 return new IRStatement144(keyword, argument, statements.get(0), line, column);
             default:
@@ -102,7 +113,7 @@ public final class AntlrSupport {
         }
     }
 
-    private static @NonNull IRStatement createStatement(final IRKeyword keyword, final IRArgument argument,
+    private static @NonNull IRStatement statementOf(final IRKeyword keyword, final IRArgument argument,
             final int line, final int column) {
         if (line >= 0 && column >= 0) {
             if (line <= 65535 && column <= 65535) {
@@ -232,7 +243,7 @@ public final class AntlrSupport {
     private ImmutableList<IRStatement> createStatements(final StatementContext stmt) {
         final List<StatementContext> statements = stmt.statement();
         return statements.isEmpty() ? ImmutableList.of()
-                : statements.stream().map(this::createStatement).collect(ImmutableList.toImmutableList());
+                : statements.stream().map(this::statementOf).collect(ImmutableList.toImmutableList());
     }
 
     private String strOf(final ParseTree tree) {
@@ -248,7 +259,8 @@ public final class AntlrSupport {
     }
 
     @VisibleForTesting
-    static String trimWhitespace(final String str, final int dquot) {
+    @Deprecated
+    public static String trimWhitespace(final String str, final int dquot) {
         final int firstBrk = str.indexOf('\n');
         if (firstBrk == -1) {
             return str;
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/ir/IRSchemaSource.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/ir/IRSchemaSource.java
new file mode 100644 (file)
index 0000000..961c381
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.rfc7950.ir;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.Beta;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.AbstractIdentifiable;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword.Unqualified;
+
+@Beta
+public final class IRSchemaSource extends AbstractIdentifiable<SourceIdentifier> implements SchemaSourceRepresentation {
+    private final @NonNull IRStatement rootStatement;
+    private final @Nullable String symbolicName;
+
+    public IRSchemaSource(final @NonNull SourceIdentifier identifier, final @NonNull IRStatement rootStatement,
+            @Nullable final String symbolicName) {
+        super(identifier);
+        this.rootStatement = requireNonNull(rootStatement);
+        this.symbolicName = symbolicName;
+
+        final IRKeyword rootKeyword = rootStatement.keyword();
+        checkArgument(rootKeyword instanceof Unqualified, "Root statement has invalid keyword %s", rootKeyword);
+        final String rootName = rootKeyword.identifier();
+        switch (rootName) {
+            case "module":
+            case "submodule":
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid root statement keyword " + rootName);
+        }
+
+        checkArgument(rootStatement.argument() != null, "Root statement does not have an argument");
+    }
+
+    public IRSchemaSource(final @NonNull SourceIdentifier identifier, final @NonNull IRStatement rootStatement) {
+        this(identifier, rootStatement, null);
+    }
+
+    @Override
+    public Optional<String> getSymbolicName() {
+        return Optional.ofNullable(symbolicName);
+    }
+
+    @Override
+    public Class<@NonNull IRSchemaSource> getType() {
+        return IRSchemaSource.class;
+    }
+
+    /**
+     * Return the root statement of this source.
+     *
+     * @return Root statement.
+     */
+    public @NonNull IRStatement getRootStatement() {
+        return rootStatement;
+    }
+}
index 9cf3717a76971482ddec2938afb3f61ebace44fd..5bc7b89730dd6a2a1d739827761848ce2ee7cbe0 100644 (file)
@@ -11,6 +11,7 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
 import java.util.Optional;
+import org.antlr.v4.runtime.ParserRuleContext;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.concepts.AbstractIdentifiable;
@@ -19,7 +20,7 @@ import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
 import org.opendaylight.yangtools.yang.model.repo.api.SemVerSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRStatement;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.StatementContext;
 
 /**
  * Abstract Syntax Tree representation of a schema source. This representation is internal to the YANG parser
@@ -31,19 +32,22 @@ import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRStatement;
  * basic semantic validation and we were able to extract dependency information.
  */
 @Beta
+@Deprecated(forRemoval = true)
 public final class ASTSchemaSource extends AbstractIdentifiable<SourceIdentifier>
         implements SchemaSourceRepresentation {
+    private final @NonNull StatementContext tree;
+    private final @Nullable String symbolicName;
+
+    // FIXME: compute lazily
     private final @NonNull YangModelDependencyInfo depInfo;
     private final @NonNull SemVerSourceIdentifier semVerId;
-    private final @NonNull IRStatement rootStatement;
-    private final @Nullable String symbolicName;
 
     private ASTSchemaSource(final @NonNull SourceIdentifier identifier, final @NonNull SemVerSourceIdentifier semVerId,
-            final @NonNull IRStatement tree, final @NonNull YangModelDependencyInfo depInfo,
+            final @NonNull StatementContext tree, final @NonNull YangModelDependencyInfo depInfo,
             @Nullable final String symbolicName) {
         super(identifier);
         this.depInfo = requireNonNull(depInfo);
-        this.rootStatement = requireNonNull(tree);
+        this.tree = requireNonNull(tree);
         this.semVerId = requireNonNull(semVerId);
         this.symbolicName = symbolicName;
     }
@@ -63,9 +67,9 @@ public final class ASTSchemaSource extends AbstractIdentifiable<SourceIdentifier
      *             if we fail to extract dependency information.
      */
     static @NonNull ASTSchemaSource create(final @NonNull SourceIdentifier identifier,
-            final @Nullable String symbolicName, final @NonNull IRStatement rootStatement)
+            final @Nullable String symbolicName, final @NonNull StatementContext tree)
                     throws YangSyntaxErrorException {
-        final YangModelDependencyInfo depInfo = YangModelDependencyInfo.parseAST(rootStatement, identifier);
+        final YangModelDependencyInfo depInfo = YangModelDependencyInfo.parseAST(tree, identifier);
         final SourceIdentifier id = getSourceId(depInfo);
 
         final SemVerSourceIdentifier semVerId;
@@ -75,7 +79,7 @@ public final class ASTSchemaSource extends AbstractIdentifiable<SourceIdentifier
             semVerId = getSemVerSourceId(depInfo);
         }
 
-        return new ASTSchemaSource(id, semVerId, rootStatement, depInfo, symbolicName);
+        return new ASTSchemaSource(id, semVerId, tree, depInfo, symbolicName);
     }
 
     @Override
@@ -93,12 +97,16 @@ public final class ASTSchemaSource extends AbstractIdentifiable<SourceIdentifier
     }
 
     /**
-     * Return the root statement of this source.
+     * Return the underlying abstract syntax tree.
      *
-     * @return Root statement.
+     * @return Underlying AST.
      */
-    public @NonNull IRStatement getRootStatement() {
-        return rootStatement;
+    public @NonNull ParserRuleContext getAST() {
+        return tree;
+    }
+
+    @NonNull StatementContext tree() {
+        return tree;
     }
 
     /**
index f3878c33714d408933fa4c6a3f16b6e5a2efc402..56725a62e9adb3f9c17c793a6051044037676634 100644 (file)
@@ -11,9 +11,17 @@ import static com.google.common.base.Verify.verify;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.CharMatcher;
+import com.google.common.base.VerifyException;
 import java.util.List;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.TerminalNode;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.YangVersion;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.ArgumentContext;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.UnquotedStringContext;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.AntlrSupport;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument.Concatenation;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument.Single;
@@ -119,6 +127,65 @@ abstract class ArgumentContextUtils {
         return concatStrings(((Concatenation) argument).parts(), ref);
     }
 
+    /*
+     * NOTE: this method we do not use convenience methods provided by generated parser code, but instead are making
+     *       based on the grammar assumptions. While this is more verbose, it cuts out a number of unnecessary code,
+     *       such as intermediate List allocation et al.
+     */
+    @Deprecated(forRemoval = true)
+    final @NonNull String stringFromStringContext(final ArgumentContext context, final StatementSourceReference ref) {
+        // Get first child, which we fully expect to exist and be a lexer token
+        final ParseTree firstChild = context.getChild(0);
+        if (firstChild instanceof TerminalNode) {
+            final Token token = ((TerminalNode) firstChild).getSymbol();
+            switch (token.getType()) {
+                case YangStatementParser.IDENTIFIER:
+                    // Simplest of cases -- it is an IDENTIFIER, hence we do not need to validate anything else and can
+                    // just grab the string and run with it.
+                    return firstChild.getText();
+                case YangStatementParser.DQUOT_STRING:
+                case YangStatementParser.DQUOT_END:
+                case YangStatementParser.SQUOT_STRING:
+                case YangStatementParser.SQUOT_END:
+                    // Quoted strings are potentially a pain, deal with them separately
+                    return decodeQuoted(context, ref);
+                default:
+                    throw new VerifyException("Unexpected token " + token);
+            }
+        }
+
+        verify(firstChild instanceof UnquotedStringContext, "Unexpected shape of %s", context);
+        // Simple case, just grab the text, as ANTLR has done all the heavy lifting
+        final String str = firstChild.getText();
+        checkUnquoted(str, ref);
+        return str;
+    }
+
+    @Deprecated
+    private @NonNull String decodeQuoted(final ArgumentContext context, final StatementSourceReference ref) {
+        if (context.getChildCount() > 2) {
+            // Potentially-complex case of string quoting, escaping and concatenation.
+            return concatStrings(context, ref);
+        }
+
+        // No concatenation needed, special-case
+        final ParseTree child = context.getChild(0);
+        verify(child instanceof TerminalNode, "Unexpected shape of %s", context);
+        final Token token = ((TerminalNode) child).getSymbol();
+        switch (token.getType()) {
+            case YangStatementParser.DQUOT_END:
+            case YangStatementParser.SQUOT_END:
+                // We are missing actual body, hence this is an empty string
+                return "";
+            case YangStatementParser.SQUOT_STRING:
+                return token.getText();
+            case YangStatementParser.DQUOT_STRING:
+                return normalizeDoubleQuoted(token, ref);
+            default:
+                throw new VerifyException("Unhandled token " + token);
+        }
+    }
+
     private @NonNull String concatStrings(final List<? extends Single> parts, final StatementSourceReference ref) {
         final StringBuilder sb = new StringBuilder();
         for (Single part : parts) {
@@ -128,6 +195,49 @@ abstract class ArgumentContextUtils {
         return sb.toString();
     }
 
+    @Deprecated
+    private String concatStrings(final ArgumentContext context, final StatementSourceReference ref) {
+        final StringBuilder sb = new StringBuilder();
+        for (ParseTree child : context.children) {
+            verify(child instanceof TerminalNode, "Unexpected argument component %s", child);
+            final Token token = ((TerminalNode) child).getSymbol();
+            switch (token.getType()) {
+                case YangStatementParser.SEP:
+                    // Separator, just skip it over
+                case YangStatementParser.PLUS:
+                    // Operator, which we are handling by concat, skip it over
+                case YangStatementParser.DQUOT_END:
+                case YangStatementParser.SQUOT_END:
+                    // Quote stops, skip them over because we either already added the content, or would be appending
+                    // an empty string
+                    break;
+                case YangStatementParser.SQUOT_STRING:
+                    // Single-quoted string, append it as a literal
+                    sb.append(token.getText());
+                    break;
+                case YangStatementParser.DQUOT_STRING:
+                    sb.append(normalizeDoubleQuoted(token, ref));
+                    break;
+                default:
+                    throw new VerifyException("Unexpected token " + token);
+            }
+        }
+        return sb.toString();
+    }
+
+    @Deprecated
+    private String normalizeDoubleQuoted(final Token token, final StatementSourceReference ref) {
+        // Whitespace normalization happens irrespective of further handling and has no effect on the result. Strictly
+        // speaking we should also have the previous token, which would be a DQUOT_START and get the position from it.
+        // Seeing as it is a single-character token let's just subtract one from this token to achieve the same result.
+        final String stripped = AntlrSupport.trimWhitespace(token.getText(), token.getCharPositionInLine() - 1);
+
+        // Now we need to perform some amount of unescaping. This serves as a pre-check before we dispatch
+        // validation and processing (which will reuse the work we have done)
+        final int backslash = stripped.indexOf('\\');
+        return backslash == -1 ? stripped : unescape(ref, stripped, backslash);
+    }
+
     /*
      * NOTE: Enforcement and transformation logic done by these methods should logically reside in the lexer and ANTLR
      *       account the for it with lexer modes. We do not want to force a re-lexing phase in the parser just because
index dc450fba3a3ca43b3470b72c8edf71b52b003dac..b1da7660ca040f107c08c69ccf79ab575ae1d9d4 100644 (file)
@@ -8,25 +8,57 @@
 package org.opendaylight.yangtools.yang.parser.rfc7950.repo;
 
 import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.Futures;
 import java.io.IOException;
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.tree.ErrorNode;
+import org.antlr.v4.runtime.tree.ParseTreeListener;
+import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.antlr.v4.runtime.tree.TerminalNode;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
 import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
 import org.opendaylight.yangtools.yang.model.repo.util.SchemaSourceTransformer;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.StatementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * A {@link SchemaSourceTransformer} which handles translation of models from
  * {@link YangTextSchemaSource} representation into {@link ASTSchemaSource}.
+ *
+ * @deprecated Use {@link TextToIRTransformer} instead.
  */
 @Beta
+@Deprecated(forRemoval = true)
 public final class TextToASTTransformer extends SchemaSourceTransformer<YangTextSchemaSource, ASTSchemaSource> {
     private static final Logger LOG = LoggerFactory.getLogger(TextToASTTransformer.class);
 
+    private static final ParseTreeListener MAKE_IMMUTABLE_LISTENER = new ParseTreeListener() {
+        @Override
+        public void enterEveryRule(final ParserRuleContext ctx) {
+            // No-op
+        }
+
+        @Override
+        public void exitEveryRule(final ParserRuleContext ctx) {
+            ctx.children = ctx.children == null ? ImmutableList.of() : ImmutableList.copyOf(ctx.children);
+        }
+
+        @Override
+        public void visitTerminal(final TerminalNode node) {
+            // No-op
+        }
+
+        @Override
+        public void visitErrorNode(final ErrorNode node) {
+            // No-op
+        }
+    };
+
     private TextToASTTransformer(final SchemaRepository provider, final SchemaSourceRegistry consumer) {
         super(provider, YangTextSchemaSource.class, consumer, ASTSchemaSource.class,
             input -> Futures.immediateFuture(transformText(input)));
@@ -38,11 +70,16 @@ public final class TextToASTTransformer extends SchemaSourceTransformer<YangText
 
     public static ASTSchemaSource transformText(final YangTextSchemaSource text) throws SchemaSourceException,
             IOException, YangSyntaxErrorException {
-        final YangStatementStreamSource src = YangStatementStreamSource.create(text);
+        final StatementContext stmt = YangStatementStreamSource.parseYangSource(text);
         LOG.debug("Model {} parsed successfully", text);
 
+        // Walk the resulting tree and replace each children with an immutable list, lowering memory requirements
+        // and making sure the resulting tree will not get accidentally modified. An alternative would be to use
+        // org.antlr.v4.runtime.Parser.TrimToSizeListener, but that does not make the tree immutable.
+        ParseTreeWalker.DEFAULT.walk(MAKE_IMMUTABLE_LISTENER, stmt);
+
         // TODO: missing validation (YangModelBasicValidationListener should be re-implemented to new parser)
 
-        return ASTSchemaSource.create(text.getIdentifier(), text.getSymbolicName().orElse(null), src.rootStatement());
+        return ASTSchemaSource.create(text.getIdentifier(), text.getSymbolicName().orElse(null), stmt);
     }
 }
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/TextToIRTransformer.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/repo/TextToIRTransformer.java
new file mode 100644 (file)
index 0000000..6a7a189
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.rfc7950.repo;
+
+import com.google.common.annotations.Beta;
+import com.google.common.util.concurrent.Futures;
+import java.io.IOException;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Revision;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaRepository;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
+import org.opendaylight.yangtools.yang.model.repo.util.SchemaSourceTransformer;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.AntlrSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRStatement;
+
+@Beta
+public final class TextToIRTransformer extends SchemaSourceTransformer<YangTextSchemaSource, IRSchemaSource> {
+    private TextToIRTransformer(final SchemaRepository provider, final SchemaSourceRegistry consumer) {
+        super(provider, YangTextSchemaSource.class, consumer, IRSchemaSource.class,
+            input -> Futures.immediateFuture(transformText(input)));
+    }
+
+    public static @NonNull TextToIRTransformer create(final SchemaRepository provider,
+            final SchemaSourceRegistry consumer) {
+        return new TextToIRTransformer(provider, consumer);
+    }
+
+    public static @NonNull IRSchemaSource transformText(final YangTextSchemaSource text)
+            throws YangSyntaxErrorException, IOException {
+        final IRStatement rootStatement = AntlrSupport.createStatement(YangStatementStreamSource.parseYangSource(text));
+        final String name = YangModelDependencyInfo.safeStringArgument(text.getIdentifier(), rootStatement, "name");
+        final String latestRevision = YangModelDependencyInfo.getLatestRevision(rootStatement, text.getIdentifier());
+        final RevisionSourceIdentifier sourceId = latestRevision == null ? RevisionSourceIdentifier.create(name)
+                : RevisionSourceIdentifier.create(name, Revision.of(latestRevision));
+
+        return new IRSchemaSource(sourceId, rootStatement);
+    }
+}
index 2add5979e9cf3331d47a6406a1b4fdbd0b52a0f4..d27f477a4e6a237cff738219f6bc05a2f4a47283 100644 (file)
@@ -10,11 +10,14 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.repo;
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
+import com.google.common.annotations.Beta;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableSet;
 import java.io.IOException;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
@@ -29,9 +32,12 @@ import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.ArgumentContext;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.StatementContext;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRArgument;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword.Unqualified;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRStatement;
 import org.opendaylight.yangtools.yang.parser.spi.source.DeclarationInTextSource;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
@@ -61,6 +67,8 @@ public abstract class YangModelDependencyInfo {
 
     private static final String OPENCONFIG_VERSION = OpenConfigStatements.OPENCONFIG_VERSION.getStatementName()
             .getLocalName();
+    @Deprecated
+    private static final Splitter COLON_SPLITTER = Splitter.on(":").omitEmptyStrings().trimResults();
 
     private final String name;
     private final Revision revision;
@@ -161,14 +169,25 @@ public abstract class YangModelDependencyInfo {
     }
 
     /**
-     * Extracts {@link YangModelDependencyInfo} from an abstract syntax tree of a YANG model.
+     * Extracts {@link YangModelDependencyInfo} from an intermediate representation root statement of a YANG model.
+     *
+     * @param source Schema source
+     * @return {@link YangModelDependencyInfo}
+     * @throws IllegalArgumentException If the root statement is not a valid YANG module/submodule
+     */
+    public static @NonNull YangModelDependencyInfo forIR(final IRSchemaSource source) {
+        return forIR(source.getRootStatement(), source.getIdentifier());
+    }
+
+    /**
+     * Extracts {@link YangModelDependencyInfo} from an intermediate representation root statement of a YANG model.
      *
      * @param source Source identifier
      * @param rootStatement root statement
      * @return {@link YangModelDependencyInfo}
-     * @throws IllegalArgumentException If the AST is not a valid YANG module/submodule
+     * @throws IllegalArgumentException If the root statement is not a valid YANG module/submodule
      */
-    static @NonNull YangModelDependencyInfo parseAST(final IRStatement rootStatement,
+    static @NonNull YangModelDependencyInfo forIR(final IRStatement rootStatement,
             final SourceIdentifier source) {
         final IRKeyword keyword = rootStatement.keyword();
         checkArgument(keyword instanceof Unqualified, "Invalid root statement %s", keyword);
@@ -183,6 +202,27 @@ public abstract class YangModelDependencyInfo {
         throw new IllegalArgumentException("Root of parsed AST must be either module or submodule");
     }
 
+    /**
+     * Extracts {@link YangModelDependencyInfo} from an abstract syntax tree of a YANG model.
+     *
+     * @param source Source identifier
+     * @param tree Abstract syntax tree
+     * @return {@link YangModelDependencyInfo}
+     * @throws IllegalArgumentException If the AST is not a valid YANG module/submodule
+     */
+    @Deprecated(forRemoval = true)
+    static @NonNull YangModelDependencyInfo parseAST(final StatementContext rootStatement,
+            final SourceIdentifier source) {
+        final String keyWordText = rootStatement.keyword().getText();
+        if (MODULE.equals(keyWordText)) {
+            return parseModuleContext(rootStatement, source);
+        }
+        if (SUBMODULE.equals(keyWordText)) {
+            return parseSubmoduleContext(rootStatement, source);
+        }
+        throw new IllegalArgumentException("Root of parsed AST must be either module or submodule");
+    }
+
     /**
      * Extracts {@link YangModelDependencyInfo} from input stream containing a YANG model. This parsing does not
      * validate full YANG module, only parses header up to the revisions and imports.
@@ -200,7 +240,7 @@ public abstract class YangModelDependencyInfo {
             throws IOException, YangSyntaxErrorException {
         final YangStatementStreamSource source = YangStatementStreamSource.create(
             YangTextSchemaSource.forResource(refClass, resourceName));
-        return parseAST(source.rootStatement(), source.getIdentifier());
+        return forIR(source.rootStatement(), source.getIdentifier());
     }
 
     private static @NonNull YangModelDependencyInfo parseModuleContext(final IRStatement module,
@@ -214,6 +254,18 @@ public abstract class YangModelDependencyInfo {
         return new ModuleDependencyInfo(name, latestRevision, imports, includes, semVer);
     }
 
+    @Deprecated
+    private static @NonNull YangModelDependencyInfo parseModuleContext(final StatementContext module,
+            final SourceIdentifier source) {
+        final String name = safeStringArgument(source, module, "module name");
+        final String latestRevision = getLatestRevision(module, source);
+        final Optional<SemVer> semVer = Optional.ofNullable(findSemanticVersion(module, source));
+        final ImmutableSet<ModuleImport> imports = parseImports(module, source);
+        final ImmutableSet<ModuleImport> includes = parseIncludes(module, source);
+
+        return new ModuleDependencyInfo(name, latestRevision, imports, includes, semVer);
+    }
+
     private static ImmutableSet<ModuleImport> parseImports(final IRStatement module,
             final SourceIdentifier source) {
         final Set<ModuleImport> result = new HashSet<>();
@@ -229,7 +281,25 @@ public abstract class YangModelDependencyInfo {
         return ImmutableSet.copyOf(result);
     }
 
-    private static SemVer findSemanticVersion(final IRStatement statement, final SourceIdentifier source) {
+    @Deprecated
+    private static ImmutableSet<ModuleImport> parseImports(final StatementContext module,
+            final SourceIdentifier source) {
+        final Set<ModuleImport> result = new HashSet<>();
+        for (final StatementContext subStatementContext : module.statement()) {
+            if (IMPORT.equals(subStatementContext.keyword().getText())) {
+                final String importedModuleName = safeStringArgument(source, subStatementContext,
+                    "imported module name");
+                final String revisionDateStr = getRevisionDateString(subStatementContext, source);
+                final Revision revisionDate = Revision.ofNullable(revisionDateStr).orElse(null);
+                final SemVer importSemVer = findSemanticVersion(subStatementContext, source);
+                result.add(new ModuleImportImpl(importedModuleName, revisionDate, importSemVer));
+            }
+        }
+        return ImmutableSet.copyOf(result);
+    }
+
+    @Beta
+    public static SemVer findSemanticVersion(final IRStatement statement, final SourceIdentifier source) {
         String semVerString = null;
         for (final IRStatement substatement : statement.statements()) {
             // FIXME: this should also check we are using a prefix
@@ -242,6 +312,29 @@ public abstract class YangModelDependencyInfo {
         return Strings.isNullOrEmpty(semVerString) ? null : SemVer.valueOf(semVerString);
     }
 
+    @Deprecated
+    private static SemVer findSemanticVersion(final StatementContext statement, final SourceIdentifier source) {
+        String semVerString = null;
+        for (final StatementContext subStatement : statement.statement()) {
+            final String subStatementName = trimPrefix(subStatement.keyword().getText());
+            if (OPENCONFIG_VERSION.equals(subStatementName)) {
+                semVerString = safeStringArgument(source,  subStatement, "version string");
+                break;
+            }
+        }
+
+        return Strings.isNullOrEmpty(semVerString) ? null : SemVer.valueOf(semVerString);
+    }
+
+    @Deprecated
+    private static String trimPrefix(final String identifier) {
+        final List<String> namesParts = COLON_SPLITTER.splitToList(identifier);
+        if (namesParts.size() == 2) {
+            return namesParts.get(1);
+        }
+        return identifier;
+    }
+
     private static boolean isBuiltin(final IRStatement stmt, final String localName) {
         final IRKeyword keyword = stmt.keyword();
         return keyword instanceof Unqualified && localName.equals(keyword.identifier());
@@ -260,6 +353,22 @@ public abstract class YangModelDependencyInfo {
         return ImmutableSet.copyOf(result);
     }
 
+    @Deprecated
+    private static ImmutableSet<ModuleImport> parseIncludes(final StatementContext module,
+            final SourceIdentifier source) {
+        final Set<ModuleImport> result = new HashSet<>();
+        for (final StatementContext subStatementContext : module.statement()) {
+            if (INCLUDE.equals(subStatementContext.keyword().getText())) {
+                final String revisionDateStr = getRevisionDateString(subStatementContext, source);
+                final String IncludeModuleName = safeStringArgument(source, subStatementContext,
+                    "included submodule name");
+                final Revision revisionDate = Revision.ofNullable(revisionDateStr).orElse(null);
+                result.add(new ModuleImportImpl(IncludeModuleName, revisionDate));
+            }
+        }
+        return ImmutableSet.copyOf(result);
+    }
+
     private static String getRevisionDateString(final IRStatement importStatement, final SourceIdentifier source) {
         String revisionDateStr = null;
         for (final IRStatement substatement : importStatement.statements()) {
@@ -270,6 +379,17 @@ public abstract class YangModelDependencyInfo {
         return revisionDateStr;
     }
 
+    @Deprecated
+    private static String getRevisionDateString(final StatementContext importStatement, final SourceIdentifier source) {
+        String revisionDateStr = null;
+        for (final StatementContext importSubStatement : importStatement.statement()) {
+            if (REVISION_DATE.equals(importSubStatement.keyword().getText())) {
+                revisionDateStr = safeStringArgument(source, importSubStatement, "imported module revision-date");
+            }
+        }
+        return revisionDateStr;
+    }
+
     public static String getLatestRevision(final IRStatement module, final SourceIdentifier source) {
         String latestRevision = null;
         for (final IRStatement substatement : module.statements()) {
@@ -283,6 +403,20 @@ public abstract class YangModelDependencyInfo {
         return latestRevision;
     }
 
+    @Deprecated
+    public static String getLatestRevision(final StatementContext module, final SourceIdentifier source) {
+        String latestRevision = null;
+        for (final StatementContext subStatementContext : module.statement()) {
+            if (REVISION.equals(subStatementContext.keyword().getText())) {
+                final String currentRevision = safeStringArgument(source, subStatementContext, "revision date");
+                if (latestRevision == null || latestRevision.compareTo(currentRevision) < 0) {
+                    latestRevision = currentRevision;
+                }
+            }
+        }
+        return latestRevision;
+    }
+
     private static @NonNull YangModelDependencyInfo parseSubmoduleContext(final IRStatement submodule,
             final SourceIdentifier source) {
         final String name = safeStringArgument(source, submodule, "submodule name");
@@ -295,6 +429,19 @@ public abstract class YangModelDependencyInfo {
         return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes);
     }
 
+    @Deprecated
+    private static @NonNull YangModelDependencyInfo parseSubmoduleContext(final StatementContext submodule,
+            final SourceIdentifier source) {
+        final String name = safeStringArgument(source, submodule, "submodule name");
+        final String belongsTo = parseBelongsTo(submodule, source);
+
+        final String latestRevision = getLatestRevision(submodule, source);
+        final ImmutableSet<ModuleImport> imports = parseImports(submodule, source);
+        final ImmutableSet<ModuleImport> includes = parseIncludes(submodule, source);
+
+        return new SubmoduleDependencyInfo(name, latestRevision, belongsTo, imports, includes);
+    }
+
     private static String parseBelongsTo(final IRStatement submodule, final SourceIdentifier source) {
         for (final IRStatement substatement : submodule.statements()) {
             if (isBuiltin(substatement, BELONGS_TO)) {
@@ -304,7 +451,17 @@ public abstract class YangModelDependencyInfo {
         return null;
     }
 
-    private static String safeStringArgument(final SourceIdentifier source, final IRStatement stmt, final String desc) {
+    @Deprecated
+    private static String parseBelongsTo(final StatementContext submodule, final SourceIdentifier source) {
+        for (final StatementContext subStatementContext : submodule.statement()) {
+            if (BELONGS_TO.equals(subStatementContext.keyword().getText())) {
+                return safeStringArgument(source, subStatementContext, "belongs-to module name");
+            }
+        }
+        return null;
+    }
+
+    static String safeStringArgument(final SourceIdentifier source, final IRStatement stmt, final String desc) {
         final StatementSourceReference ref = getReference(source, stmt);
         final IRArgument arg = stmt.argument();
         checkArgument(arg != null, "Missing %s at %s", desc, ref);
@@ -312,10 +469,27 @@ public abstract class YangModelDependencyInfo {
         return ArgumentContextUtils.rfc6020().stringFromStringContext(arg, ref);
     }
 
+    @Deprecated
+    private static String safeStringArgument(final SourceIdentifier source, final StatementContext stmt,
+            final String desc) {
+        final StatementSourceReference ref = getReference(source, stmt);
+        final ArgumentContext arg = stmt.argument();
+        checkArgument(arg != null, "Missing %s at %s", desc, ref);
+        // TODO: we probably need to understand yang version first....
+        return ArgumentContextUtils.rfc6020().stringFromStringContext(arg, ref);
+    }
+
     private static StatementSourceReference getReference(final SourceIdentifier source, final IRStatement stmt) {
         return DeclarationInTextSource.atPosition(source.getName(), stmt.startLine(), stmt.startColumn());
     }
 
+    @Deprecated
+    private static StatementSourceReference getReference(final SourceIdentifier source,
+            final StatementContext context) {
+        return DeclarationInTextSource.atPosition(source.getName(), context.getStart().getLine(),
+            context.getStart().getCharPositionInLine());
+    }
+
     /**
      * Dependency information for YANG module.
      */
index 63a4bfc40a1093160b9bc5f55236fd582a0565cd..2f624c10dc92e7c6a604c569f8d927c76760c311 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.repo;
 
+import static com.google.common.base.Verify.verifyNotNull;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
@@ -25,9 +26,11 @@ import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.parser.antlr.YangStatementLexer;
 import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser;
 import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.FileContext;
+import org.opendaylight.yangtools.yang.parser.antlr.YangStatementParser.StatementContext;
 import org.opendaylight.yangtools.yang.parser.rfc7950.antlr.CompactYangStatementLexer;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.AntlrSupport;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRKeyword;
+import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRSchemaSource;
 import org.opendaylight.yangtools.yang.parser.rfc7950.ir.IRStatement;
 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
 import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
@@ -65,13 +68,8 @@ public final class YangStatementStreamSource extends AbstractIdentifiable<Source
      */
     public static YangStatementStreamSource create(final YangTextSchemaSource source) throws IOException,
             YangSyntaxErrorException {
-        final IRStatement rootStatement;
-        try (InputStream stream = source.openStream()) {
-            rootStatement = parseYangSource(source.getIdentifier(), stream);
-        }
-
-        return new YangStatementStreamSource(source.getIdentifier(), rootStatement,
-            source.getSymbolicName().orElse(null));
+        return new YangStatementStreamSource(source.getIdentifier(),
+            AntlrSupport.createStatement(parseYangSource(source)), source.getSymbolicName().orElse(null));
     }
 
     /**
@@ -79,8 +77,21 @@ public final class YangStatementStreamSource extends AbstractIdentifiable<Source
      *
      * @param source YangTextSchemaSource, must not be null
      * @return A new {@link YangStatementStreamSource}
+     * @throws NullPointerException if {@code source} is null
      */
     public static YangStatementStreamSource create(final ASTSchemaSource source) {
+        return create(source.getIdentifier(), AntlrSupport.createStatement(source.tree()),
+            source.getSymbolicName().orElse(null));
+    }
+
+    /**
+     * Create a {@link YangStatementStreamSource} for a {@link IRSchemaSource}.
+     *
+     * @param source YangTextSchemaSource, must not be null
+     * @return A new {@link YangStatementStreamSource}
+     * @throws NullPointerException if {@code source} is null
+     */
+    public static YangStatementStreamSource create(final IRSchemaSource source) {
         return create(source.getIdentifier(), source.getRootStatement(), source.getSymbolicName().orElse(null));
     }
 
@@ -131,7 +142,14 @@ public final class YangStatementStreamSource extends AbstractIdentifiable<Source
         return rootStatement;
     }
 
-    private static IRStatement parseYangSource(final SourceIdentifier source, final InputStream stream)
+    static StatementContext parseYangSource(final YangTextSchemaSource source)
+            throws IOException, YangSyntaxErrorException {
+        try (InputStream stream = source.openStream()) {
+            return parseYangSource(source.getIdentifier(), stream);
+        }
+    }
+
+    private static StatementContext parseYangSource(final SourceIdentifier source, final InputStream stream)
             throws IOException, YangSyntaxErrorException {
         final YangStatementLexer lexer = new CompactYangStatementLexer(CharStreams.fromStream(stream));
         final YangStatementParser parser = new YangStatementParser(new CommonTokenStream(lexer));
@@ -145,6 +163,6 @@ public final class YangStatementStreamSource extends AbstractIdentifiable<Source
 
         final FileContext result = parser.file();
         errorListener.validate();
-        return AntlrSupport.createStatement(result);
+        return verifyNotNull(result.statement());
     }
 }