BindingRuntimeTypes should be an interface 77/99877/1
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 25 Feb 2022 16:06:13 +0000 (17:06 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 25 Feb 2022 16:06:54 +0000 (17:06 +0100)
We do not want to expose the internals of how this interface is
realized, make sure we split it into an interface and an implementation.

JIRA: MDSAL-696
Change-Id: Icc01bc2c66cbf57c8cbb2ff9c32ac30c373b899d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/BindingRuntimeTypesFactory.java
binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/DefaultBindingRuntimeTypes.java [new file with mode: 0644]
binding/mdsal-binding-runtime-api/src/main/java/org/opendaylight/mdsal/binding/runtime/api/BindingRuntimeTypes.java

index bb54c9c5abe62754b970349934bcb79967ce4d99..8c5a49450416f788b0ba575d17911ea1b09bde7a 100644 (file)
@@ -61,7 +61,7 @@ final class BindingRuntimeTypesFactory implements Mutable {
         factory.indexTypes(moduleGens);
         LOG.debug("Indexed {} generators in {}", moduleGens.size(), sw);
 
-        return new BindingRuntimeTypes(context, factory.augmentationToSchema, factory.typeToSchema,
+        return new DefaultBindingRuntimeTypes(context, factory.augmentationToSchema, factory.typeToSchema,
             factory.schemaToType, factory.identities);
     }
 
diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/DefaultBindingRuntimeTypes.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/DefaultBindingRuntimeTypes.java
new file mode 100644 (file)
index 0000000..3f21a81
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o.  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.mdsal.binding.generator.impl;
+
+import static com.google.common.base.Verify.verify;
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.MultimapBuilder;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.model.api.GeneratedType;
+import org.opendaylight.mdsal.binding.model.api.Type;
+import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeTypes;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class DefaultBindingRuntimeTypes implements BindingRuntimeTypes {
+    private static final Logger LOG = LoggerFactory.getLogger(DefaultBindingRuntimeTypes.class);
+
+    private final @NonNull EffectiveModelContext schemaContext;
+    private final ImmutableMap<Type, AugmentationSchemaNode> typeToAugmentation;
+    private final ImmutableMap<Type, WithStatus> typeToSchema;
+    private final ImmutableMultimap<Type, Type> choiceToCases;
+    private final ImmutableMap<QName, Type> identities;
+    // Not Immutable as we use two different implementations
+    private final Map<WithStatus, Type> schemaToType;
+
+    DefaultBindingRuntimeTypes(final EffectiveModelContext schemaContext,
+            final Map<Type, AugmentationSchemaNode> typeToAugmentation,
+            final Map<Type, WithStatus> typeToSchema, final Map<WithStatus, Type> schemaToType,
+            final Map<QName, Type> identities) {
+        this.schemaContext = requireNonNull(schemaContext);
+        this.typeToAugmentation = ImmutableMap.copyOf(typeToAugmentation);
+        this.typeToSchema = ImmutableMap.copyOf(typeToSchema);
+        this.identities = ImmutableMap.copyOf(identities);
+
+        // Careful to use identity for SchemaNodes, but only if needed
+        // FIXME: 8.0.0: YT should be switching to identity for equals(), so this should become unnecessary
+        Map<WithStatus, Type> copy;
+        try {
+            copy = ImmutableMap.copyOf(schemaToType);
+        } catch (IllegalArgumentException e) {
+            LOG.debug("Equality-duplicates found in {}", schemaToType.keySet());
+            copy = new IdentityHashMap<>(schemaToType);
+        }
+
+        this.schemaToType = copy;
+
+        // Two-phase indexing of choice/case nodes. First we load all choices. Note we are using typeToSchema argument,
+        // not field, so as not to instantiate its entrySet.
+        final Set<GeneratedType> choiceTypes = typeToSchema.entrySet().stream()
+            .filter(entry -> entry.getValue() instanceof ChoiceEffectiveStatement)
+            .map(entry -> {
+                final Type key = entry.getKey();
+                verify(key instanceof GeneratedType, "Unexpected choice type %s", key);
+                return (GeneratedType) key;
+            })
+            .collect(Collectors.toUnmodifiableSet());
+
+        final Multimap<Type, Type> builder = MultimapBuilder.hashKeys(choiceTypes.size()).arrayListValues().build();
+        for (Entry<Type, WithStatus> entry : typeToSchema.entrySet()) {
+            if (entry.getValue() instanceof CaseEffectiveStatement) {
+                final Type type = entry.getKey();
+                verify(type instanceof GeneratedType, "Unexpected case type %s", type);
+                builder.put(verifyNotNull(implementedChoiceType(((GeneratedType) type).getImplements(), choiceTypes),
+                    "Cannot determine choice type for %s", type), type);
+            }
+        }
+
+        choiceToCases = ImmutableMultimap.copyOf(builder);
+    }
+
+    private static GeneratedType implementedChoiceType(final List<Type> impls, final Set<GeneratedType> choiceTypes) {
+        for (Type impl : impls) {
+            if (impl instanceof GeneratedType && choiceTypes.contains(impl)) {
+                return (GeneratedType) impl;
+            }
+        }
+        return null;
+    }
+
+    DefaultBindingRuntimeTypes(final EffectiveModelContext schemaContext,
+            final Map<Type, AugmentationSchemaNode> typeToAugmentation,
+            final BiMap<Type, WithStatus> typeToDefiningSchema, final Map<QName, Type> identities) {
+        this(schemaContext, typeToAugmentation, typeToDefiningSchema, typeToDefiningSchema.inverse(), identities);
+    }
+
+    @Override
+    public EffectiveModelContext getEffectiveModelContext() {
+        return schemaContext;
+    }
+
+    @Override
+    public Optional<AugmentationSchemaNode> findAugmentation(final Type type) {
+        return Optional.ofNullable(typeToAugmentation.get(type));
+    }
+
+    @Override
+    public Optional<Type> findIdentity(final QName qname) {
+        return Optional.ofNullable(identities.get(qname));
+    }
+
+    @Override
+    public Optional<WithStatus> findSchema(final Type type) {
+        return Optional.ofNullable(typeToSchema.get(type));
+    }
+
+    @Override
+    public Optional<Type> findType(final WithStatus schema) {
+        return Optional.ofNullable(schemaToType.get(schema));
+    }
+
+    @Override
+    public Optional<Type> findOriginalAugmentationType(final AugmentationSchemaNode augment) {
+        // If the augment statement does not contain any child nodes, we did not generate an augmentation, as it would
+        // be plain littering.
+        // FIXME: MDSAL-695: this check is rather costly (involves filtering), can we just rely on the not being found
+        //                   in the end? all we are saving is essentially two map lookups after all...
+        if (augment.getChildNodes().isEmpty()) {
+            return Optional.empty();
+        }
+
+        // FIXME: MDSAL-695: We should have enough information from mdsal-binding-generator to receive a (sparse) Map
+        //                   for current -> original lookup. When combined with schemaToType, this amounts to the
+        //                   inverse view of what 'typeToSchema' holds
+        AugmentationSchemaNode current = augment;
+        while (true) {
+            // If this augmentation has been added through 'uses foo { augment bar { ... } }', we need to invert that
+            // walk and arrive at the original declaration site, as that is where we generated 'grouping foo's
+            // augmentation. That site may have a different module, hence the augment namespace may be different.
+            final Optional<AugmentationSchemaNode> original = current.getOriginalDefinition();
+            if (original.isEmpty()) {
+                return findType(current);
+            }
+            current = original.orElseThrow();
+        }
+    }
+
+    @Override
+    public Multimap<Type, Type> getChoiceToCases() {
+        return choiceToCases;
+    }
+
+    @Override
+    public Collection<Type> findCases(final Type choiceType) {
+        return choiceToCases.get(choiceType);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("typeToAugmentation", typeToAugmentation)
+                .add("typeToSchema", typeToSchema)
+                .add("choiceToCases", choiceToCases)
+                .add("identities", identities)
+                .toString();
+    }
+}
index 8a54fe653e96bebfeaf288a006a50e26bf531d0d..d0ac16642ab2fbe5979223eccbdfe1f15bd1d7fb 100644 (file)
  */
 package org.opendaylight.mdsal.binding.runtime.api;
 
-import static com.google.common.base.Verify.verify;
-import static com.google.common.base.Verify.verifyNotNull;
-import static java.util.Objects.requireNonNull;
-
 import com.google.common.annotations.Beta;
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Multimap;
-import com.google.common.collect.MultimapBuilder;
 import java.util.Collection;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.model.api.GeneratedType;
 import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
-import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextProvider;
-import org.opendaylight.yangtools.yang.model.api.stmt.CaseEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * The result of BindingGenerator run. Contains mapping between Types and SchemaNodes.
  */
 @Beta
-public final class BindingRuntimeTypes implements EffectiveModelContextProvider, Immutable {
-    private static final Logger LOG = LoggerFactory.getLogger(BindingRuntimeTypes.class);
-
-    private final @NonNull EffectiveModelContext schemaContext;
-    private final ImmutableMap<Type, AugmentationSchemaNode> typeToAugmentation;
-    private final ImmutableMap<Type, WithStatus> typeToSchema;
-    private final ImmutableMultimap<Type, Type> choiceToCases;
-    private final ImmutableMap<QName, Type> identities;
-    // Not Immutable as we use two different implementations
-    private final Map<WithStatus, Type> schemaToType;
-
-    public BindingRuntimeTypes(final EffectiveModelContext schemaContext,
-            final Map<Type, AugmentationSchemaNode> typeToAugmentation,
-            final Map<Type, WithStatus> typeToSchema, final Map<WithStatus, Type> schemaToType,
-            final Map<QName, Type> identities) {
-        this.schemaContext = requireNonNull(schemaContext);
-        this.typeToAugmentation = ImmutableMap.copyOf(typeToAugmentation);
-        this.typeToSchema = ImmutableMap.copyOf(typeToSchema);
-        this.identities = ImmutableMap.copyOf(identities);
-
-        // Careful to use identity for SchemaNodes, but only if needed
-        // FIXME: 8.0.0: YT should be switching to identity for equals(), so this should become unnecessary
-        Map<WithStatus, Type> copy;
-        try {
-            copy = ImmutableMap.copyOf(schemaToType);
-        } catch (IllegalArgumentException e) {
-            LOG.debug("Equality-duplicates found in {}", schemaToType.keySet());
-            copy = new IdentityHashMap<>(schemaToType);
-        }
-
-        this.schemaToType = copy;
-
-        // Two-phase indexing of choice/case nodes. First we load all choices. Note we are using typeToSchema argument,
-        // not field, so as not to instantiate its entrySet.
-        final Set<GeneratedType> choiceTypes = typeToSchema.entrySet().stream()
-            .filter(entry -> entry.getValue() instanceof ChoiceEffectiveStatement)
-            .map(entry -> {
-                final Type key = entry.getKey();
-                verify(key instanceof GeneratedType, "Unexpected choice type %s", key);
-                return (GeneratedType) key;
-            })
-            .collect(Collectors.toUnmodifiableSet());
-
-        final Multimap<Type, Type> builder = MultimapBuilder.hashKeys(choiceTypes.size()).arrayListValues().build();
-        for (Entry<Type, WithStatus> entry : typeToSchema.entrySet()) {
-            if (entry.getValue() instanceof CaseEffectiveStatement) {
-                final Type type = entry.getKey();
-                verify(type instanceof GeneratedType, "Unexpected case type %s", type);
-                builder.put(verifyNotNull(implementedChoiceType(((GeneratedType) type).getImplements(), choiceTypes),
-                    "Cannot determine choice type for %s", type), type);
-            }
-        }
-
-        choiceToCases = ImmutableMultimap.copyOf(builder);
-    }
-
-    private static GeneratedType implementedChoiceType(final List<Type> impls, final Set<GeneratedType> choiceTypes) {
-        for (Type impl : impls) {
-            if (impl instanceof GeneratedType && choiceTypes.contains(impl)) {
-                return (GeneratedType) impl;
-            }
-        }
-        return null;
-    }
-
-    public BindingRuntimeTypes(final EffectiveModelContext schemaContext,
-            final Map<Type, AugmentationSchemaNode> typeToAugmentation,
-            final BiMap<Type, WithStatus> typeToDefiningSchema, final Map<QName, Type> identities) {
-        this(schemaContext, typeToAugmentation, typeToDefiningSchema, typeToDefiningSchema.inverse(), identities);
-    }
-
-    @Override
-    public EffectiveModelContext getEffectiveModelContext() {
-        return schemaContext;
-    }
-
-    public Optional<AugmentationSchemaNode> findAugmentation(final Type type) {
-        return Optional.ofNullable(typeToAugmentation.get(type));
-    }
-
-    public Optional<Type> findIdentity(final QName qname) {
-        return Optional.ofNullable(identities.get(qname));
-    }
+public interface BindingRuntimeTypes extends EffectiveModelContextProvider, Immutable {
 
-    public Optional<WithStatus> findSchema(final Type type) {
-        return Optional.ofNullable(typeToSchema.get(type));
-    }
+    Optional<AugmentationSchemaNode> findAugmentation(Type type);
 
-    public Optional<Type> findType(final WithStatus schema) {
-        return Optional.ofNullable(schemaToType.get(schema));
-    }
+    Optional<Type> findIdentity(QName qname);
 
-    public Optional<Type> findOriginalAugmentationType(final AugmentationSchemaNode augment) {
-        // If the augment statement does not contain any child nodes, we did not generate an augmentation, as it would
-        // be plain littering.
-        // FIXME: MDSAL-695: this check is rather costly (involves filtering), can we just rely on the not being found
-        //                   in the end? all we are saving is essentially two map lookups after all...
-        if (augment.getChildNodes().isEmpty()) {
-            return Optional.empty();
-        }
+    Optional<WithStatus> findSchema(Type type);
 
-        // FIXME: MDSAL-695: We should have enough information from mdsal-binding-generator to receive a (sparse) Map
-        //                   for current -> original lookup. When combined with schemaToType, this amounts to the
-        //                   inverse view of what 'typeToSchema' holds
-        AugmentationSchemaNode current = augment;
-        while (true) {
-            // If this augmentation has been added through 'uses foo { augment bar { ... } }', we need to invert that
-            // walk and arrive at the original declaration site, as that is where we generated 'grouping foo's
-            // augmentation. That site may have a different module, hence the augment namespace may be different.
-            final Optional<AugmentationSchemaNode> original = current.getOriginalDefinition();
-            if (original.isEmpty()) {
-                return findType(current);
-            }
-            current = original.orElseThrow();
-        }
-    }
+    Optional<Type> findType(WithStatus schema);
 
-    public Multimap<Type, Type> getChoiceToCases() {
-        return choiceToCases;
-    }
+    Optional<Type> findOriginalAugmentationType(AugmentationSchemaNode augment);
 
-    public Collection<Type> findCases(final Type choiceType) {
-        return choiceToCases.get(choiceType);
-    }
+    Multimap<Type, Type> getChoiceToCases();
 
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(this)
-                .add("typeToAugmentation", typeToAugmentation)
-                .add("typeToSchema", typeToSchema)
-                .add("choiceToCases", choiceToCases)
-                .add("identities", identities)
-                .toString();
-    }
+    Collection<Type> findCases(Type choiceType);
 }