Bug 6856: Rpc definition should implicitly define input/ouput
[mdsal.git] / binding / mdsal-binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingGeneratorImpl.java
index e202da9df582ad60f74d789d4bd02aacb8c0e5e4..c485d01a87306170cc51a496354898ad4d2e1957 100644 (file)
@@ -27,6 +27,7 @@ import static org.opendaylight.yangtools.binding.generator.util.Types.typeForCla
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findNodeInSchemaContext;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
+
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -99,11 +100,12 @@ import org.opendaylight.yangtools.yang.model.api.Status;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
 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.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.type.CompatUtils;
@@ -512,7 +514,9 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 final ContainerSchemaNode input = rpc.getInput();
                 final ContainerSchemaNode output = rpc.getOutput();
 
-                if (input != null) {
+                //in case of implicit RPC input (StatementSource.CONTEXT),
+                // stay compatible (no input argument generated)
+                if (input != null && isExplicitStatement(input)) {
                     final GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName);
                     addImplementedInterfaceFromUses(input, inType);
                     inType.addImplementsType(DATA_OBJECT);
@@ -525,7 +529,9 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 }
 
                 Type outTypeInstance = VOID;
-                if (output != null) {
+                //in case of implicit RPC output (StatementSource.CONTEXT),
+                //stay compatible (Future<RpcResult<Void>> return type generated)
+                if (output != null && isExplicitStatement(output)) {
                     final GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName);
                     addImplementedInterfaceFromUses(output, outType);
                     outType.addImplementsType(DATA_OBJECT);
@@ -545,6 +551,11 @@ public class BindingGeneratorImpl implements BindingGenerator {
         genCtx.get(module).addTopLevelNodeType(interfaceBuilder);
     }
 
+    private static boolean isExplicitStatement(ContainerSchemaNode node) {
+        return node instanceof EffectiveStatement
+                && ((EffectiveStatement) node).getDeclared().getStatementSource() == StatementSource.DECLARATION;
+    }
+
     /**
      * Converts all <b>notifications</b> of the module to the list of
      * <code>Type</code> objects. In addition are to this list added containers
@@ -913,10 +924,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());
             }
@@ -1000,8 +1010,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema.getChildNodes());
         augmentBuilders.put(augTypeName, augTypeBuilder);
 
-        if(!augSchema.getChildNodes().isEmpty()) {
-            genCtx.get(module).addTargetToAugmentation(targetTypeRef, augTypeBuilder);
+        if (!augSchema.getChildNodes().isEmpty()) {
             genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
 
         }
@@ -1371,11 +1380,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;
@@ -1428,7 +1432,6 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef;
                 final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.getQName(),
                     typeBuilder, module);
-
                 if (enumBuilder != null) {
                     returnType = enumBuilder.toInstance(typeBuilder);
                 }
@@ -1461,6 +1464,10 @@ public class BindingGeneratorImpl implements BindingGenerator {
             return null;
         }
 
+        if (typeDef instanceof EnumTypeDefinition) {
+            ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
+        }
+
         String leafDesc = leaf.getDescription();
         if (leafDesc == null) {
             leafDesc = "";
@@ -1472,10 +1479,6 @@ public class BindingGeneratorImpl implements BindingGenerator {
     }
 
     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;
@@ -2017,10 +2020,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
@@ -2283,4 +2284,4 @@ public class BindingGeneratorImpl implements BindingGenerator {
             builder.addAnnotation("", "Deprecated");
         }
     }
-}
\ No newline at end of file
+}