Simplify ModuleInfoSnapshotBuilder 82/92882/3
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 3 Oct 2020 07:31:39 +0000 (09:31 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 3 Oct 2020 09:42:54 +0000 (11:42 +0200)
There is no need to allocate a full resolver, as the things we want
to achieve here are easily done through a simple parser.

Change-Id: I03a7255bc2b6f50171cc6b353ab15409e08ab747
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/BindingRuntimeHelpers.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ModuleInfoSnapshotBuilder.java
binding/mdsal-binding-runtime-spi/src/main/java/org/opendaylight/mdsal/binding/runtime/spi/ModuleInfoSnapshotResolver.java
yanglib/mdsal-yanglib-rfc7895/src/main/java/org/opendaylight/mdsal/yanglib/rfc7895/YangModuleLibrarySupport.java
yanglib/mdsal-yanglib-rfc8525/src/main/java/org/opendaylight/mdsal/yanglib/rfc8525/YangLibrarySupport.java

index f284d1666dd7855fe016b45349173336da5c0a89..62c36378ab99b3318aab5b605beedef12923267d 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.mdsal.binding.runtime.api.ModuleInfoSnapshot;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
 
 /**
@@ -41,33 +42,46 @@ public final class BindingRuntimeHelpers {
 
     public static @NonNull EffectiveModelContext createEffectiveModel(
             final Iterable<? extends YangModuleInfo> moduleInfos) {
-        return createEffectiveModel(ServiceLoaderState.ParserFactory.INSTANCE, moduleInfos);
+        try {
+            return createEffectiveModel(ServiceLoaderState.ParserFactory.INSTANCE, moduleInfos);
+        } catch (YangParserException e) {
+            throw new IllegalStateException("Failed to parse models", e);
+        }
     }
 
     public static @NonNull EffectiveModelContext createEffectiveModel(final YangParserFactory parserFactory,
-            final Iterable<? extends YangModuleInfo> moduleInfos) {
+            final Iterable<? extends YangModuleInfo> moduleInfos) throws YangParserException {
         return prepareContext(parserFactory, moduleInfos).getEffectiveModelContext();
     }
 
     public static @NonNull BindingRuntimeContext createRuntimeContext() {
-        final ModuleInfoSnapshot infos = prepareContext(ServiceLoaderState.ParserFactory.INSTANCE,
-            BindingReflections.loadModuleInfos());
+        final ModuleInfoSnapshot infos;
+        try {
+            infos = prepareContext(ServiceLoaderState.ParserFactory.INSTANCE,
+                BindingReflections.loadModuleInfos());
+        } catch (YangParserException e) {
+            throw new IllegalStateException("Failed to parse models", e);
+        }
         return new DefaultBindingRuntimeContext(ServiceLoaderState.Generator.INSTANCE.generateTypeMapping(
             infos.getEffectiveModelContext()), infos);
     }
 
     public static @NonNull BindingRuntimeContext createRuntimeContext(final Class<?>... classes) {
-        return createRuntimeContext(ServiceLoaderState.ParserFactory.INSTANCE, ServiceLoaderState.Generator.INSTANCE,
-            classes);
+        try {
+            return createRuntimeContext(ServiceLoaderState.ParserFactory.INSTANCE,
+                ServiceLoaderState.Generator.INSTANCE, classes);
+        } catch (YangParserException e) {
+            throw new IllegalStateException("Failed to parse models", e);
+        }
     }
 
     public static @NonNull BindingRuntimeContext createRuntimeContext(final YangParserFactory parserFactory,
-            final BindingRuntimeGenerator generator, final Class<?>... classes) {
+            final BindingRuntimeGenerator generator, final Class<?>... classes) throws YangParserException {
         return createRuntimeContext(parserFactory, generator, Arrays.asList(classes));
     }
 
     public static @NonNull BindingRuntimeContext createRuntimeContext(final YangParserFactory parserFactory,
-            final BindingRuntimeGenerator generator, final Collection<Class<?>> classes) {
+            final BindingRuntimeGenerator generator, final Collection<Class<?>> classes) throws YangParserException {
         final ModuleInfoSnapshot infos = prepareContext(parserFactory, classes.stream()
             .map(BindingRuntimeHelpers::extractYangModuleInfo)
             .collect(Collectors.toList()));
@@ -85,7 +99,7 @@ public final class BindingRuntimeHelpers {
     }
 
     private static @NonNull ModuleInfoSnapshot prepareContext(final YangParserFactory parserFactory,
-            final Iterable<? extends YangModuleInfo> moduleInfos) {
-        return new ModuleInfoSnapshotBuilder("helper", parserFactory).add(moduleInfos).build();
+            final Iterable<? extends YangModuleInfo> moduleInfos) throws YangParserException {
+        return new ModuleInfoSnapshotBuilder(parserFactory).add(moduleInfos).build();
     }
 }
index 5fe2d89bc72248db5816f170315fd20a6e8be419..0b8343972ea5730c4839532e9a2f93a2e7d1da75 100644 (file)
@@ -7,39 +7,74 @@
  */
 package org.opendaylight.mdsal.binding.runtime.spi;
 
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.annotations.Beta;
-import java.util.Arrays;
-import java.util.List;
-import java.util.NoSuchElementException;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.runtime.api.ModuleInfoSnapshot;
+import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.yangtools.concepts.CheckedBuilder;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+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.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 
 @Beta
-public final class ModuleInfoSnapshotBuilder implements CheckedBuilder<ModuleInfoSnapshot, NoSuchElementException> {
-    private final ModuleInfoSnapshotResolver registry;
+public final class ModuleInfoSnapshotBuilder implements CheckedBuilder<ModuleInfoSnapshot, YangParserException> {
+    private final Set<YangModuleInfo> moduleInfos = new HashSet<>();
+    private final YangParserFactory parserFactory;
 
-    public ModuleInfoSnapshotBuilder(final String name, final YangParserFactory parserFactory) {
-        registry = new ModuleInfoSnapshotResolver(name, parserFactory);
+    public ModuleInfoSnapshotBuilder(final YangParserFactory parserFactory) {
+        this.parserFactory = requireNonNull(parserFactory);
     }
 
     public @NonNull ModuleInfoSnapshotBuilder add(final YangModuleInfo info) {
-        return add(List.of(info));
+        ModuleInfoSnapshotResolver.flatDependencies(moduleInfos, info);
+        return this;
     }
 
     public @NonNull ModuleInfoSnapshotBuilder add(final YangModuleInfo... infos) {
-        return add(Arrays.asList(infos));
+        for (YangModuleInfo info : infos) {
+            add(info);
+        }
+        return this;
     }
 
     public @NonNull ModuleInfoSnapshotBuilder add(final Iterable<? extends YangModuleInfo> infos) {
-        registry.registerModuleInfos(infos);
+        for (YangModuleInfo info : infos) {
+            add(info);
+        }
         return this;
     }
 
     @Override
-    public ModuleInfoSnapshot build() {
-        return registry.takeSnapshot();
+    public ModuleInfoSnapshot build() throws YangParserException {
+        final YangParser parser = parserFactory.createParser();
+        final Map<SourceIdentifier, YangModuleInfo> mappedInfos = new HashMap<>();
+        final Map<String, ClassLoader> classLoaders = new HashMap<>();
+        for (YangModuleInfo info : moduleInfos) {
+            final YangTextSchemaSource source = ModuleInfoSnapshotResolver.toYangTextSource(info);
+            mappedInfos.put(source.getIdentifier(), info);
+
+            final Class<?> infoClass = info.getClass();
+            classLoaders.put(BindingReflections.getModelRootPackageName(infoClass.getPackage()),
+                infoClass.getClassLoader());
+
+            try {
+                parser.addSource(source);
+            } catch (YangSyntaxErrorException | IOException e) {
+                throw new YangParserException("Failed to add source for " + info, e);
+            }
+        }
+
+        return new DefaultModuleInfoSnapshot(parser.buildEffectiveModel(), mappedInfos, classLoaders);
     }
 }
index bd623d129d049accfc74c46c08904fb3f4cb3ec7..7982e8a4121e45bc9750029ea436fff7e640efe0 100644 (file)
@@ -220,6 +220,11 @@ public final class ModuleInfoSnapshotResolver implements Mutable {
         }
     }
 
+    static @NonNull YangTextSchemaSource toYangTextSource(final YangModuleInfo moduleInfo) {
+        return YangTextSchemaSource.delegateForByteSource(sourceIdentifierFrom(moduleInfo),
+            moduleInfo.getYangTextByteSource());
+    }
+
     private static @NonNull YangTextSchemaSource toYangTextSource(final SourceIdentifier identifier,
             final YangModuleInfo moduleInfo) {
         return YangTextSchemaSource.delegateForByteSource(identifier, moduleInfo.getYangTextByteSource());
@@ -239,7 +244,7 @@ public final class ModuleInfoSnapshotResolver implements Mutable {
         return ImmutableList.copyOf(requiredInfos).reverse();
     }
 
-    private static void flatDependencies(final Set<YangModuleInfo> set, final YangModuleInfo moduleInfo) {
+    static void flatDependencies(final Set<YangModuleInfo> set, final YangModuleInfo moduleInfo) {
         if (set.add(moduleInfo)) {
             for (YangModuleInfo dep : moduleInfo.getImportedModules()) {
                 flatDependencies(set, dep);
index f0871a71d66e9aa06f25973640702a221d300c79..f86e406133970c7e3355507e56d6ce586124297d 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.mdsal.yanglib.rfc7895;
 import static com.google.common.base.Verify.verifyNotNull;
 
 import com.google.common.annotations.Beta;
-import java.io.IOException;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -41,8 +40,8 @@ public final class YangModuleLibrarySupport implements YangLibSupport {
 
     @Inject
     public YangModuleLibrarySupport(final YangParserFactory parserFactory, final BindingRuntimeGenerator generator,
-            final BindingCodecTreeFactory codecFactory) throws YangParserException, IOException {
-        final ModuleInfoSnapshot snapshot = new ModuleInfoSnapshotBuilder("yanglib", parserFactory)
+            final BindingCodecTreeFactory codecFactory) throws YangParserException {
+        final ModuleInfoSnapshot snapshot = new ModuleInfoSnapshotBuilder(parserFactory)
                 .add($YangModuleInfoImpl.getInstance())
                 .build();
         context = snapshot.getEffectiveModelContext();
index 1748cab45198326c6e82a24ed99d885a632931bf..4587e9430fad74d53d8bef166507e3cd30ed4419 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.mdsal.yanglib.rfc8525;
 import static com.google.common.base.Verify.verifyNotNull;
 
 import com.google.common.annotations.Beta;
-import java.io.IOException;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -46,8 +45,8 @@ public final class YangLibrarySupport implements YangLibSupport {
 
     @Inject
     public YangLibrarySupport(final YangParserFactory parserFactory, final BindingRuntimeGenerator generator,
-            final BindingCodecTreeFactory codecFactory) throws YangParserException, IOException {
-        final ModuleInfoSnapshot snapshot = new ModuleInfoSnapshotBuilder("yanglib", parserFactory)
+            final BindingCodecTreeFactory codecFactory) throws YangParserException {
+        final ModuleInfoSnapshot snapshot = new ModuleInfoSnapshotBuilder(parserFactory)
                 .add($YangModuleInfoImpl.getInstance())
                 .build();
         context = snapshot.getEffectiveModelContext();