Use cached AugmentationIdentifiers in BindingRuntimeContext
[mdsal.git] / binding / mdsal-binding-generator-impl / src / main / java / org / opendaylight / mdsal / binding / generator / util / BindingRuntimeContext.java
index 9b2cbcc613ed1e70ad498e0ed32dd2399443b229..dc2be63654c51fae21ba35f6c892dab8ae01ee2d 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.mdsal.binding.generator.util;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
 
-import com.google.common.base.Optional;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
@@ -18,6 +18,7 @@ import com.google.common.cache.LoadingCache;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import java.util.AbstractMap.SimpleEntry;
 import java.util.ArrayList;
@@ -28,8 +29,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.Set;
-import javax.annotation.Nullable;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.mdsal.binding.generator.api.BindingRuntimeTypes;
 import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy;
 import org.opendaylight.mdsal.binding.generator.impl.BindingGeneratorImpl;
@@ -41,10 +43,10 @@ import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
 import org.opendaylight.mdsal.binding.model.api.Type;
 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder;
 import org.opendaylight.mdsal.binding.model.util.ReferencedTypeImpl;
+import org.opendaylight.mdsal.binding.spec.naming.BindingMapping;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.yang.binding.Action;
 import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.BindingMapping;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
@@ -70,7 +72,7 @@ import org.slf4j.LoggerFactory;
  * <p>Runtime Context provides additional insight in Java YANG Binding,
  * binding classes and underlying YANG schema, it contains
  * runtime information, which could not be derived from generated
- * classes alone using {@link org.opendaylight.yangtools.yang.binding.util.BindingReflections}.
+ * classes alone using {@link org.opendaylight.mdsal.binding.spec.reflect.BindingReflections}.
  *
  * <p>Some of this information are for example list of all available
  * children for cases {@link #getChoiceCaseChildren(DataNodeContainer)}, since
@@ -91,7 +93,7 @@ public final class BindingRuntimeContext implements Immutable {
         new CacheLoader<QName, Class<?>>() {
             @Override
             public Class<?> load(final QName key) {
-                final java.util.Optional<Type> identityType = runtimeTypes.findIdentity(key);
+                final Optional<Type> identityType = runtimeTypes.findIdentity(key);
                 checkArgument(identityType.isPresent(), "Supplied QName %s is not a valid identity", key);
                 try {
                     return strategy.loadClass(identityType.get());
@@ -222,7 +224,7 @@ public final class BindingRuntimeContext implements Immutable {
             }
         }
 
-        final AugmentationIdentifier identifier = new AugmentationIdentifier(childNames);
+        final AugmentationIdentifier identifier = AugmentationIdentifier.create(childNames);
         final AugmentationSchemaNode proxy = new EffectiveAugmentationSchema(origSchema, realChilds);
         return new SimpleEntry<>(identifier, proxy);
     }
@@ -232,7 +234,7 @@ public final class BindingRuntimeContext implements Immutable {
      *
      * @param schema Resolved parent choice schema
      * @param childClass Class representing case.
-     * @return Optionally a resolved case schema, absent if the choice is not legal in
+     * @return Optionally a resolved case schema,.empty if the choice is not legal in
      *         the given context.
      * @throws IllegalArgumentException If supplied class does not represent case.
      */
@@ -251,10 +253,6 @@ public final class BindingRuntimeContext implements Immutable {
         return found;
     }
 
-    private static Type referencedType(final Class<?> type) {
-        return new ReferencedTypeImpl(JavaTypeName.create(type));
-    }
-
     /**
      * Returns schema ({@link DataSchemaNode}, {@link AugmentationSchemaNode} or {@link TypeDefinition})
      * from which supplied class was generated. Returned schema may be augmented with
@@ -288,7 +286,7 @@ public final class BindingRuntimeContext implements Immutable {
 
         for (final ChoiceSchemaNode choice :  Iterables.filter(schema.getChildNodes(), ChoiceSchemaNode.class)) {
             final ChoiceSchemaNode originalChoice = getOriginalSchema(choice);
-            final java.util.Optional<Type> optType = runtimeTypes.findType(originalChoice);
+            final Optional<Type> optType = runtimeTypes.findType(originalChoice);
             checkState(optType.isPresent(), "Failed to find generated type for choice %s", originalChoice);
             final Type choiceType = optType.get();
 
@@ -328,6 +326,22 @@ public final class BindingRuntimeContext implements Immutable {
         return getEnumMapping(findTypeWithSchema(enumClassName));
     }
 
+    private static BiMap<String, String> getEnumMapping(final Entry<GeneratedType, WithStatus> typeWithSchema) {
+        final TypeDefinition<?> typeDef = (TypeDefinition<?>) typeWithSchema.getValue();
+
+        Preconditions.checkArgument(typeDef instanceof EnumTypeDefinition);
+        final EnumTypeDefinition enumType = (EnumTypeDefinition) typeDef;
+
+        final HashBiMap<String, String> mappedEnums = HashBiMap.create();
+
+        for (final EnumTypeDefinition.EnumPair enumPair : enumType.getValues()) {
+            mappedEnums.put(enumPair.getName(), BindingMapping.getClassName(enumPair.getName()));
+        }
+
+        // TODO cache these maps for future use
+        return mappedEnums;
+    }
+
     private Entry<GeneratedType, WithStatus> findTypeWithSchema(final String className) {
         // All we have is a straight FQCN, which we need to split into a hierarchical JavaTypeName. This involves
         // some amount of guesswork -- we do that by peeling components at the dot and trying out, e.g. given
@@ -352,13 +366,13 @@ public final class BindingRuntimeContext implements Immutable {
             }
 
             final Type type = new ReferencedTypeImpl(name);
-            final java.util.Optional<WithStatus> optSchema = runtimeTypes.findSchema(type);
+            final Optional<WithStatus> optSchema = runtimeTypes.findSchema(type);
             if (!optSchema.isPresent()) {
                 continue;
             }
 
             final WithStatus schema = optSchema.get();
-            final java.util.Optional<Type> optDefinedType =  runtimeTypes.findType(schema);
+            final Optional<Type> optDefinedType =  runtimeTypes.findType(schema);
             if (!optDefinedType.isPresent()) {
                 continue;
             }
@@ -374,22 +388,6 @@ public final class BindingRuntimeContext implements Immutable {
         throw new IllegalArgumentException("Failed to find type for " + className);
     }
 
-    private static BiMap<String, String> getEnumMapping(final Entry<GeneratedType, WithStatus> typeWithSchema) {
-        final TypeDefinition<?> typeDef = (TypeDefinition<?>) typeWithSchema.getValue();
-
-        Preconditions.checkArgument(typeDef instanceof EnumTypeDefinition);
-        final EnumTypeDefinition enumType = (EnumTypeDefinition) typeDef;
-
-        final HashBiMap<String, String> mappedEnums = HashBiMap.create();
-
-        for (final EnumTypeDefinition.EnumPair enumPair : enumType.getValues()) {
-            mappedEnums.put(enumPair.getName(), BindingMapping.getClassName(enumPair.getName()));
-        }
-
-        // TODO cache these maps for future use
-        return mappedEnums;
-    }
-
     public Set<Class<?>> getCases(final Class<?> choice) {
         final Collection<Type> cazes = runtimeTypes.findCases(referencedType(choice));
         final Set<Class<?>> ret = new HashSet<>(cazes.size());
@@ -406,7 +404,7 @@ public final class BindingRuntimeContext implements Immutable {
 
     public Class<?> getClassForSchema(final SchemaNode childSchema) {
         final SchemaNode origSchema = getOriginalSchema(childSchema);
-        final java.util.Optional<Type> clazzType = runtimeTypes.findType(origSchema);
+        final Optional<Type> clazzType = runtimeTypes.findType(origSchema);
         checkArgument(clazzType.isPresent(), "Failed to find binding type for %s (original %s)",
             childSchema, origSchema);
 
@@ -429,7 +427,7 @@ public final class BindingRuntimeContext implements Immutable {
                 }
 
                 if (!augment.getChildNodes().isEmpty()) {
-                    final java.util.Optional<Type> augType = runtimeTypes.findType(augOrig);
+                    final Optional<Type> augType = runtimeTypes.findType(augOrig);
                     if (augType.isPresent()) {
                         identifierToType.put(getAugmentationIdentifier(augment), augType.get());
                     }
@@ -441,11 +439,13 @@ public final class BindingRuntimeContext implements Immutable {
     }
 
     private static AugmentationIdentifier getAugmentationIdentifier(final AugmentationSchemaNode augment) {
-        final Set<QName> childNames = new HashSet<>();
-        for (final DataSchemaNode child : augment.getChildNodes()) {
-            childNames.add(child.getQName());
-        }
-        return new AugmentationIdentifier(childNames);
+        // FIXME: use DataSchemaContextNode.augmentationIdentifierFrom() once it does caching
+        return AugmentationIdentifier.create(augment.getChildNodes().stream().map(DataSchemaNode::getQName)
+            .collect(ImmutableSet.toImmutableSet()));
+    }
+
+    private static Type referencedType(final Class<?> type) {
+        return new ReferencedTypeImpl(JavaTypeName.create(type));
     }
 
     private static Type referencedType(final Type type) {
@@ -485,4 +485,12 @@ public final class BindingRuntimeContext implements Immutable {
     public Class<?> getIdentityClass(final QName input) {
         return identityClasses.getUnchecked(input);
     }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("ClassLoadingStrategy", strategy)
+                .add("runtimeTypes", runtimeTypes)
+                .add("schemaContext", schemaContext).toString();
+    }
 }