BUG-865: remove String-based getDataChildByName()
[mdsal.git] / binding / mdsal-binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingGeneratorImpl.java
index 9caae2f3180040c6903676d66f5f74be31ab34cf..f604a7c9c6048c60488412512aba53a5440535fa 100644 (file)
@@ -37,6 +37,7 @@ import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -101,14 +102,10 @@ import org.opendaylight.yangtools.yang.model.api.UsesNode;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.BaseTypes;
 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
-import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
-import org.opendaylight.yangtools.yang.model.util.UnionType;
 import org.opendaylight.yangtools.yang.model.util.type.CompatUtils;
-import org.opendaylight.yangtools.yang.parser.builder.util.Comparators;
 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -119,6 +116,27 @@ public class BindingGeneratorImpl implements BindingGenerator {
     private static final Splitter BSDOT_SPLITTER = Splitter.on("\\.");
     private static final char NEW_LINE = '\n';
 
+    /**
+     * Comparator based on augment target path.
+     */
+    private static final Comparator<AugmentationSchema> AUGMENT_COMP = (o1, o2) -> {
+        final Iterator<QName> thisIt = o1.getTargetPath().getPathFromRoot().iterator();
+        final Iterator<QName> otherIt = o2.getTargetPath().getPathFromRoot().iterator();
+
+        while (thisIt.hasNext()) {
+            if (!otherIt.hasNext()) {
+                return 1;
+            }
+
+            final int comp = thisIt.next().compareTo(otherIt.next());
+            if (comp != 0) {
+                return comp;
+            }
+        }
+
+        return otherIt.hasNext() ? -1 : 0;
+    };
+
     /**
      * Constant with the concrete name of identifier.
      */
@@ -331,7 +349,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
             final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final ContainerSchemaNode node) {
         final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node);
         if (genType != null) {
-            constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), genType);
+            constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), genType, node.getStatus());
             resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes());
         }
     }
@@ -341,7 +359,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node);
         if (genType != null) {
             constructGetter(parent, node.getQName().getLocalName(), node.getDescription(),
-                    Types.listTypeFor(genType));
+                    Types.listTypeFor(genType), node.getStatus());
 
             final List<String> listKeys = listKeys(node);
             final String packageName = packageNameForGeneratedType(basePackageName, node.getPath());
@@ -427,7 +445,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         final Set<AugmentationSchema> augmentations = module.getAugmentations();
         final List<AugmentationSchema> sortedAugmentations = new ArrayList<>(augmentations);
-        Collections.sort(sortedAugmentations, Comparators.AUGMENT_COMP);
+        Collections.sort(sortedAugmentations, AUGMENT_COMP);
 
         return sortedAugmentations;
     }
@@ -836,7 +854,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         } else {
             generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance(),
-                    (ChoiceSchemaNode) targetSchemaNode, augSchema.getChildNodes());
+                    (ChoiceSchemaNode) targetSchemaNode, augSchema.getChildNodes(), null);
         }
     }
 
@@ -871,7 +889,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                     augSchema);
         } else {
             generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance(),
-                    (ChoiceSchemaNode) targetSchemaNode, augSchema.getChildNodes());
+                    (ChoiceSchemaNode) targetSchemaNode, augSchema.getChildNodes(), usesNodeParent);
         }
     }
 
@@ -894,10 +912,9 @@ public class BindingGeneratorImpl implements BindingGenerator {
         final GroupingDefinition grouping = (GroupingDefinition) targetGrouping;
         SchemaNode result = grouping;
         for (final QName node : targetPath.getPathFromRoot()) {
-            // finding by local name is valid, grouping cannot contain nodes
-            // with same name and different namespace
             if (result instanceof DataNodeContainer) {
-                result = ((DataNodeContainer) result).getDataChildByName(node.getLocalName());
+                final QName resultNode = QName.create(result.getQName().getModule(), node.getLocalName());
+                result = ((DataNodeContainer) result).getDataChildByName(resultNode);
             } else if (result instanceof ChoiceSchemaNode) {
                 result = ((ChoiceSchemaNode) result).getCaseNodeByName(node.getLocalName());
             }
@@ -1170,7 +1187,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
             final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
             final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
             constructGetter(parent, choiceNode.getQName().getLocalName(),
-                    choiceNode.getDescription(), choiceTypeBuilder);
+                    choiceNode.getDescription(), choiceTypeBuilder, choiceNode.getStatus());
             choiceTypeBuilder.addImplementsType(typeForClass(DataContainer.class));
             annotateDeprecatedIfNecessary(choiceNode.getStatus(), choiceTypeBuilder);
             genCtx.get(module).addChildNodeType(choiceNode, choiceTypeBuilder);
@@ -1294,7 +1311,8 @@ public class BindingGeneratorImpl implements BindingGenerator {
      *             </ul>
      */
     private void generateTypesFromAugmentedChoiceCases(final Module module, final String basePackageName,
-            final Type targetType, final ChoiceSchemaNode targetNode, final Iterable<DataSchemaNode> augmentedNodes) {
+            final Type targetType, final ChoiceSchemaNode targetNode, final Iterable<DataSchemaNode> augmentedNodes,
+            final DataNodeContainer usesNodeParent) {
         checkArgument(basePackageName != null, "Base Package Name cannot be NULL.");
         checkArgument(targetType != null, "Referenced Choice Type cannot be NULL.");
         checkArgument(augmentedNodes != null, "Set of Choice Case Nodes cannot be NULL.");
@@ -1325,10 +1343,20 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 }
 
                 ChoiceCaseNode node = null;
+                final String caseLocalName = caseNode.getQName().getLocalName();
                 if (caseNode instanceof ChoiceCaseNode) {
                     node = (ChoiceCaseNode) caseNode;
+                } else if (targetNode.getCaseNodeByName(caseLocalName) == null) {
+                    final String targetNodeLocalName = targetNode.getQName().getLocalName();
+                    for (DataSchemaNode dataSchemaNode : usesNodeParent.getChildNodes()) {
+                        if (dataSchemaNode instanceof ChoiceSchemaNode && targetNodeLocalName.equals(dataSchemaNode.getQName
+                                ().getLocalName())) {
+                            node = ((ChoiceSchemaNode) dataSchemaNode).getCaseNodeByName(caseLocalName);
+                            break;
+                        }
+                    }
                 } else {
-                    node = targetNode.getCaseNodeByName(caseNode.getQName().getLocalName());
+                    node = targetNode.getCaseNodeByName(caseLocalName);
                 }
                 final Iterable<DataSchemaNode> childNodes = node.getChildNodes();
                 if (childNodes != null) {
@@ -1341,11 +1369,6 @@ public class BindingGeneratorImpl implements BindingGenerator {
     }
 
     private static boolean isInnerType(final LeafSchemaNode leaf, final TypeDefinition<?> type) {
-        // Deal with old parser, clearing out references to typedefs
-        if (type instanceof ExtendedType) {
-            return false;
-        }
-
         // New parser with encapsulated type
         if (leaf.getPath().equals(type.getPath())) {
             return true;
@@ -1356,11 +1379,6 @@ public class BindingGeneratorImpl implements BindingGenerator {
             return true;
         }
 
-        // Old parser uses broken Union type, which does not change its schema path
-        if (type instanceof UnionType) {
-            return true;
-        }
-
         return false;
     }
 
@@ -1441,16 +1459,12 @@ public class BindingGeneratorImpl implements BindingGenerator {
             leafDesc = "";
         }
 
-        final MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType);
+        final MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType, leaf.getStatus());
         processContextRefExtension(leaf, getter, parentModule);
         return returnType;
     }
 
     private static TypeDefinition<?> getBaseOrDeclaredType(final TypeDefinition<?> typeDef) {
-        if (typeDef instanceof ExtendedType) {
-            // Legacy behaviour returning ExtendedType is enough
-            return typeDef;
-        }
         // Returns DerivedType in case of new parser.
         final TypeDefinition<?> baseType = typeDef.getBaseType();
         return (baseType != null && baseType.getBaseType() != null) ? baseType : typeDef;
@@ -1533,7 +1547,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                         qname.getRevision());
                 final ModuleContext mc = genCtx.get(unionModule);
                 returnType = mc.getTypedefs().get(typeDef.getPath());
-            } else if (typeDef instanceof EnumTypeDefinition && BaseTypes.ENUMERATION_QNAME.equals(typeDef.getQName())) {
+            } else if (typeDef instanceof EnumTypeDefinition && typeDef.getBaseType() == null) {
                 // Annonymous enumeration (already generated, since it is inherited via uses).
                 LeafSchemaNode originalLeaf = (LeafSchemaNode) SchemaNodeUtils.getRootOriginalIfPossible(leaf);
                 QName qname = originalLeaf.getQName();
@@ -1644,7 +1658,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
 
         final ParameterizedType listType = Types.listTypeFor(returnType);
-        constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription(), listType);
+        constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription(), listType, node.getStatus());
         return true;
     }
 
@@ -1864,13 +1878,18 @@ public class BindingGeneratorImpl implements BindingGenerator {
      *            string with comment for the getter method
      * @param returnType
      *            type which represents the return type of the getter method
+     * @param status
+     *            status from yang file, for deprecated annotation
      * @return method signature builder which represents the getter method of
      *         <code>interfaceBuilder</code>
      */
     private static MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder,
-            final String schemaNodeName, final String comment, final Type returnType) {
+            final String schemaNodeName, final String comment, final Type returnType, final Status status) {
         final MethodSignatureBuilder getMethod = interfaceBuilder
                 .addMethod(getterMethodName(schemaNodeName, returnType));
+        if (status == Status.DEPRECATED) {
+            getMethod.addAnnotation("", "Deprecated");
+        }
         getMethod.setComment(encodeAngleBrackets(comment));
         getMethod.setReturnType(returnType);
         return getMethod;
@@ -1936,7 +1955,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         if (genTOBuilder != null) {
             final GeneratedTransferObject genTO = genTOBuilder.toInstance();
-            constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO);
+            constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO, Status.CURRENT);
             genCtx.get(module).addGeneratedTOBuilder(genTOBuilder);
         }
     }
@@ -1987,10 +2006,8 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
     /**
      * Builds generated TO builders for <code>typeDef</code> of type
-     * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or
-     * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
-     * BitsTypeDefinition} which are also added to <code>typeBuilder</code> as
-     * enclosing transfer object.
+     * {@link UnionTypeDefinition} or {@link BitsTypeDefinition} which are
+     * also added to <code>typeBuilder</code> as enclosing transfer object.
      *
      * If more then one generated TO builder is created for enclosing then all
      * of the generated TO builders are added to <code>typeBuilder</code> as
@@ -2118,7 +2135,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
     private String createDescription(final SchemaNode schemaNode, final String fullyQualifiedName) {
         final StringBuilder sb = new StringBuilder();
         final String nodeDescription = encodeAngleBrackets(schemaNode.getDescription());
-        final String formattedDescription = YangTemplate.formatToParagraph(nodeDescription, 0);
+        final String formattedDescription = YangTextTemplate.formatToParagraph(nodeDescription, 0);
 
         if (!Strings.isNullOrEmpty(formattedDescription)) {
             sb.append(formattedDescription);
@@ -2149,7 +2166,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
             sb.append("The schema path to identify an instance is");
             sb.append(NEW_LINE);
             sb.append("<i>");
-            sb.append(YangTemplate.formatSchemaPath(module.getName(), schemaNode.getPath().getPathFromRoot()));
+            sb.append(YangTextTemplate.formatSchemaPath(module.getName(), schemaNode.getPath().getPathFromRoot()));
             sb.append("</i>");
             sb.append(NEW_LINE);
 
@@ -2186,7 +2203,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
     private String createDescription(final Module module) {
         final StringBuilder sb = new StringBuilder();
         final String moduleDescription = encodeAngleBrackets(module.getDescription());
-        final String formattedDescription = YangTemplate.formatToParagraph(moduleDescription, 0);
+        final String formattedDescription = YangTextTemplate.formatToParagraph(moduleDescription, 0);
 
         if (!Strings.isNullOrEmpty(formattedDescription)) {
             sb.append(formattedDescription);