X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding2%2Fmdsal-binding2-generator-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fjavav2%2Fgenerator%2Fimpl%2FGenHelperUtil.java;h=9dc44c119e771ea18353175645f13916f17f376f;hb=b020023b71447f7fd2eee3c1eb4108578346da6d;hp=11ac9465a138eead5950c6a9729e82432a176608;hpb=e51917fff35cf59717f304147fd139403f4f32e7;p=mdsal.git diff --git a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java old mode 100644 new mode 100755 index 11ac9465a1..9dc44c119e --- a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java +++ b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java @@ -9,10 +9,10 @@ package org.opendaylight.mdsal.binding.javav2.generator.impl; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Objects.requireNonNull; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.addTOToTypeBuilder; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.annotateDeprecatedIfNecessary; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.constructGetter; -import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createDescription; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createReturnTypeForUnion; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.getAugmentIdentifier; import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.isInnerType; @@ -23,20 +23,25 @@ import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenU import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.computeDefaultSUID; import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.encodeAngleBrackets; import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameForGeneratedType; +import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.IDENTIFIABLE; +import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.IDENTIFIER; import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION; import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.parameterizedTypeFor; import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.wildcardTypeFor; -import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode; +import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.resolveRegExpressions; import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule; import com.google.common.annotations.Beta; import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; + import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext; import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider; import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil; @@ -44,10 +49,11 @@ import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes; import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier; import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer; import org.opendaylight.mdsal.binding.javav2.generator.util.ReferencedTypeImpl; +import org.opendaylight.mdsal.binding.javav2.generator.util.TypeComments; import org.opendaylight.mdsal.binding.javav2.generator.util.Types; import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl; -import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl; import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTypeBuilderImpl; +import org.opendaylight.mdsal.binding.javav2.generator.yang.types.BaseYangTypes; import org.opendaylight.mdsal.binding.javav2.generator.yang.types.GroupingDefinitionDependencySort; import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl; import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier; @@ -55,11 +61,11 @@ import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType; import org.opendaylight.mdsal.binding.javav2.model.api.ParameterizedType; import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions; import org.opendaylight.mdsal.binding.javav2.model.api.Type; +import org.opendaylight.mdsal.binding.javav2.model.api.YangSourceDefinition; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder; import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder; -import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder; import org.opendaylight.mdsal.binding.javav2.spec.base.BaseIdentity; import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode; import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType; @@ -68,8 +74,8 @@ import org.opendaylight.mdsal.binding.javav2.util.BindingMapping; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; -import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; -import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -88,9 +94,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.Status; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.UsesNode; -import org.opendaylight.yangtools.yang.model.api.meta.ModelStatement; 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.PatternConstraint; import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils; @@ -108,54 +114,58 @@ final class GenHelperUtil { /** * Create GeneratedTypeBuilder object from module argument. * - * @param module - * Module object from which builder will be created - * @param genCtx generated context + * @param module Module object from which builder will be created + * @param genCtx generated context * @param verboseClassComments verbosity switch - * * @return GeneratedTypeBuilder which is internal - * representation of the module - * @throws IllegalArgumentException - * if module is null + * representation of the module + * @throws IllegalArgumentException if module is null */ - static GeneratedTypeBuilder moduleToDataType(final Module module, final Map genCtx, final boolean verboseClassComments) { + static GeneratedTypeBuilder moduleToDataType(final Module module, final Map genCtx, + final boolean verboseClassComments) { Preconditions.checkArgument(module != null, "Module reference cannot be NULL."); final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data", verboseClassComments, genCtx.get(module)); addImplementedInterfaceFromUses(module, moduleDataTypeBuilder, genCtx); moduleDataTypeBuilder.addImplementsType(BindingTypes.TREE_ROOT); - moduleDataTypeBuilder.addComment(module.getDescription()); - moduleDataTypeBuilder.setDescription(createDescription(module, verboseClassComments)); - moduleDataTypeBuilder.setReference(module.getReference()); + + if (verboseClassComments) { + YangSourceDefinition.of(module).ifPresent(moduleDataTypeBuilder::setYangSourceDefinition); + TypeComments.description(module).ifPresent(moduleDataTypeBuilder::addComment); + module.getDescription().ifPresent(moduleDataTypeBuilder::setDescription); + module.getReference().ifPresent(moduleDataTypeBuilder::setReference); + } + return moduleDataTypeBuilder; } /** * Generates type builder for module. * - * @param module - * Module which is source of package name for generated type - * builder - * @param postfix - * string which is added to the module class name representation - * as suffix + * @param module Module which is source of package name for generated type + * builder + * @param postfix string which is added to the module class name representation + * as suffix * @param verboseClassComments verbosity switch * @return instance of GeneratedTypeBuilder which represents - * module. - * @throws IllegalArgumentException - * if module is null + * module. + * @throws IllegalArgumentException if module is null */ static GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix, final boolean - verboseClassComments, ModuleContext context) { + verboseClassComments, final ModuleContext context) { Preconditions.checkArgument(module != null, "Module reference cannot be NULL."); final String packageName = BindingMapping.getRootPackageName(module); // underscore used as separator for distinction of module name parts final String moduleName = new StringBuilder(module.getName()).append('_').append(postfix).toString(); final GeneratedTypeBuilderImpl moduleBuilder = new GeneratedTypeBuilderImpl(packageName, moduleName, context); - moduleBuilder.setDescription(createDescription(module, verboseClassComments)); - moduleBuilder.setReference(module.getReference()); + if (verboseClassComments) { + YangSourceDefinition.of(module).ifPresent(moduleBuilder::setYangSourceDefinition); + TypeComments.description(module).ifPresent(moduleBuilder::addComment); + module.getDescription().ifPresent(moduleBuilder::setDescription); + module.getReference().ifPresent(moduleBuilder::setReference); + } moduleBuilder.setModuleName(moduleName); return moduleBuilder; } @@ -163,34 +173,34 @@ final class GenHelperUtil { /** * Adds the implemented types to type builder. * + *

* The method passes through the list of uses in * {@code dataNodeContainer}. For every use is obtained corresponding * generated type from all groupings * allGroupings} which is added as implements type to * builder * - * @param dataNodeContainer - * element which contains the list of used YANG groupings - * @param builder - * builder to which are added implemented types according to - * dataNodeContainer - * @param genCtx generated context + * @param dataNodeContainer element which contains the list of used YANG groupings + * @param builder builder to which are added implemented types according to + * dataNodeContainer + * @param genCtx generated context * @return generated type builder with all implemented types */ static GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer, - final GeneratedTypeBuilder builder, final Map genCtx) { + final GeneratedTypeBuilder builder, final Map genCtx) { for (final UsesNode usesNode : dataNodeContainer.getUses()) { final GeneratedType genType = findGroupingByPath(usesNode.getGroupingPath(), genCtx).toInstance(); if (genType == null) { throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for " - + builder.getName()); + + builder.getName()); } builder.addImplementsType(genType); } return builder; } - static GeneratedTypeBuilder findGroupingByPath(final SchemaPath path, final Map genCtx) { + static GeneratedTypeBuilder findGroupingByPath(final SchemaPath path, final Map genCtx) { for (final ModuleContext ctx : genCtx.values()) { final GeneratedTypeBuilder result = ctx.getGrouping(path); if (result != null) { @@ -198,11 +208,11 @@ final class GenHelperUtil { } } return null; - } + } - static GeneratedTOBuilder findIdentityByQname(final QName qname, final Map genCtx) { + static GeneratedTypeBuilder findIdentityByQname(final QName qname, final Map genCtx) { for (final ModuleContext ctx : genCtx.values()) { - final GeneratedTOBuilder result = ctx.getIdentities().get(qname); + final GeneratedTypeBuilder result = ctx.getIdentities().get(qname); if (result != null) { return result; } @@ -214,33 +224,34 @@ final class GenHelperUtil { * Adds the methods to typeBuilder which represent subnodes of * node for which typeBuilder was created. * + *

* The subnodes aren't mapped to the methods if they are part of grouping or * augment (in this case are already part of them). * - * @param module - * current module - * @param basePackageName - * string contains the module package name - * @param parent - * generated type builder which represents any node. The subnodes - * of this node are added to the typeBuilder as - * methods. The subnode can be of type leaf, leaf-list, list, - * container, choice. - * @param childOf - * parent type - * @param schemaNodes - * set of data schema nodes which are the children of the node - * for which typeBuilder was created + * @param module current module + * @param basePackageName string contains the module package name + * @param parent generated type builder which represents any node. The subnodes + * of this node are added to the typeBuilder as + * methods. The subnode can be of type leaf, leaf-list, list, + * container, choice. + * @param childOf parent type + * @param schemaNodes set of data schema nodes which are the children of the node + * for which typeBuilder was created * @return generated type builder which is the same builder as input - * parameter. The getter methods (representing child nodes) could be - * added to it. + * parameter. The getter methods (representing child nodes) could be + * added to it. */ static GeneratedTypeBuilder resolveDataSchemaNodes(final Module module, final String basePackageName, - final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, - final Iterable schemaNodes, final Map genCtx, - final SchemaContext schemaContext, final boolean verboseClassComments, - final Map> genTypeBuilders, - final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { + final GeneratedTypeBuilder parent, final GeneratedTypeBuilder + childOf, + final Iterable schemaNodes, final Map genCtx, + final SchemaContext schemaContext, final boolean + verboseClassComments, + final Map> + genTypeBuilders, + final TypeProvider typeProvider, final BindingNamespaceType + namespaceType) { if (schemaNodes != null && parent != null) { for (final DataSchemaNode schemaNode : schemaNodes) { @@ -254,115 +265,115 @@ final class GenHelperUtil { } static boolean resolveDataSchemaNodesCheck(final Module module, final SchemaContext schemaContext, - final DataSchemaNode schemaNode) { + final DataSchemaNode schemaNode) { if (!schemaNode.isAugmenting()) { return true; - } else if (schemaNode.isAugmenting()) { - QName qname = schemaNode.getPath().getLastComponent(); - final Module originalModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), - qname.getRevision()); - if (module.equals(originalModule)) { - return true; - } } - return false; + final QName qname = schemaNode.getPath().getLastComponent(); + final Module originalModule = schemaContext.findModule(qname.getModule()).get(); + return module.equals(originalModule); } - static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String basePackageName, final SchemaNode - schemaNode, final Module module, final Map genCtx, final SchemaContext schemaContext, - final boolean verboseClassComments, final Map> genTypeBuilders, - final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { - return addDefaultInterfaceDefinition(basePackageName, schemaNode, null, module, genCtx, schemaContext, - verboseClassComments, genTypeBuilders, typeProvider , namespaceType); - } - - private static QName createQNameFromSuperNode(final Module module, final Object node, final SchemaNode superChildNode) { + private static QName createQNameFromSuperNode(final Module module, final Object node, final SchemaNode + superChildNode) { QName childNodeQName = null; if (node instanceof Module) { - childNodeQName = QName.create(((Module) node).getNamespace(), ((Module) node).getRevision(), - superChildNode.getQName().getLocalName()); + childNodeQName = QName.create(((Module) node).getQNameModule(), superChildNode.getQName().getLocalName()); } else if (node instanceof SchemaNode) { childNodeQName = QName.create(((SchemaNode) node).getQName(), superChildNode.getQName().getLocalName()); - } else if (node instanceof AugmentationSchema) { - childNodeQName = QName.create(module.getNamespace(), module.getRevision(), superChildNode.getQName().getLocalName()); + } else if (node instanceof AugmentationSchemaNode) { + childNodeQName = QName.create(module.getQNameModule(), superChildNode.getQName().getLocalName()); } else { - throw new IllegalArgumentException("Not support node type:" + node.toString()); + throw new IllegalArgumentException("Not support node type:" + node); } return childNodeQName; } private static void addUsesImplements(final SchemaNode superNode, final Module superModule, - final Object node, final Module module, final SchemaContext schemaContext, - Map genCtx, final BindingNamespaceType namespaceType) { + final Object node, final Module module, final SchemaContext schemaContext, + final Map genCtx, final BindingNamespaceType + namespaceType) { if (superNode instanceof DataNodeContainer) { for (DataSchemaNode superChildNode : ((DataNodeContainer) superNode).getChildNodes()) { if (superChildNode instanceof DataNodeContainer || superChildNode instanceof ChoiceSchemaNode) { final QName childQName = createQNameFromSuperNode(module, node, superChildNode); DataSchemaNode childNode = ((DataNodeContainer) node).getDataChildByName(childQName); - Preconditions.checkNotNull(childNode, node.toString() + "->" + childQName.toString()); + requireNonNull(childNode, () -> node + "->" + childQName); final GeneratedTypeBuilder type = genCtx.get(module).getChildNode(childNode.getPath()); - final GeneratedTypeBuilder superType = genCtx.get(superModule).getChildNode(superChildNode.getPath()); + final GeneratedTypeBuilder superType = genCtx.get(superModule).getChildNode(superChildNode + .getPath()); - Preconditions.checkNotNull(type, module.toString() + "->" + childNode.getPath().toString()); - Preconditions.checkNotNull(superType, superModule.toString() + "->" + superChildNode.getPath().toString()); + requireNonNull(type, () -> module + "->" + childNode.getPath()); + requireNonNull(superType, () -> superModule + "->" + superChildNode.getPath()); type.addImplementsType(superType); if (superChildNode instanceof ListSchemaNode && !((ListSchemaNode) superChildNode).getKeyDefinition().isEmpty()) { - if (namespaceType.equals(BindingNamespaceType.Grouping)) { + if (BindingNamespaceType.isGrouping(namespaceType)) { genCtx.get(module).getKeyType(childNode.getPath()) .addImplementsType(genCtx.get(superModule).getKeyType(superChildNode.getPath())); - } else if (namespaceType.equals(BindingNamespaceType.Data)) { + } else if (BindingNamespaceType.isData(namespaceType)) { genCtx.get(module).getKeyGenTO(childNode.getPath()) .addImplementsType(genCtx.get(superModule).getKeyType(superChildNode.getPath())); } } - addUsesImplements(superChildNode, superModule, childNode, module, schemaContext, genCtx, namespaceType); + addUsesImplements(superChildNode, superModule, childNode, module, schemaContext, genCtx, + namespaceType); } } } else if (superNode instanceof ChoiceSchemaNode) { - for (ChoiceCaseNode superCaseNode : ((ChoiceSchemaNode) superNode).getCases()) { + for (CaseSchemaNode superCaseNode : ((ChoiceSchemaNode) superNode).getCases().values()) { final QName childQName = createQNameFromSuperNode(module, node, superCaseNode); - ChoiceCaseNode caseNode = ((ChoiceSchemaNode) node).getCaseNodeByName(childQName); - Preconditions.checkNotNull(caseNode, node.toString() + "->" + childQName.toString()); + CaseSchemaNode caseNode = ((ChoiceSchemaNode) node).getCaseNodeByName(childQName); + requireNonNull(caseNode, () -> node + "->" + childQName); final GeneratedTypeBuilder type = genCtx.get(module).getCase(caseNode.getPath()); final GeneratedTypeBuilder superType = genCtx.get(superModule).getCase(superCaseNode.getPath()); - Preconditions.checkNotNull(type, module.toString() + "->" + caseNode.getPath().toString()); - Preconditions.checkNotNull(superType, superModule.toString() + "->" + superCaseNode.getPath().toString()); + requireNonNull(type, () -> module + "->" + caseNode.getPath()); + requireNonNull(superType, () -> superModule + "->" + superCaseNode.getPath()); type.addImplementsType(superType); addUsesImplements(superCaseNode, superModule, caseNode, module, schemaContext, genCtx, namespaceType); } } else { - throw new IllegalArgumentException("Not support super node :" + superNode.toString()); + throw new IllegalArgumentException("Not support super node :" + superNode); } } private static GroupingDefinition findGroupingNodeFromUses(final Module module, final SchemaContext schemaContext, - final Object parentNode, final UsesNode usesNode) { + final Object parentNode, final UsesNode usesNode) { SchemaNode groupingNode; if (parentNode instanceof Module) { - final Module superModule = schemaContext.findModuleByNamespaceAndRevision( - usesNode.getGroupingPath().getLastComponent().getModule().getNamespace(), - usesNode.getGroupingPath().getLastComponent().getModule().getRevision()); + final Module superModule = schemaContext.findModule( + usesNode.getGroupingPath().getLastComponent().getModule()).get(); groupingNode = superModule.getGroupings() .stream().filter(grouping -> grouping.getPath().equals(usesNode.getGroupingPath())) .findFirst().orElse(null); } else { //FIXME: Schema path is not unique for Yang 1.1, findDataSchemaNode always does search from data node first. - groupingNode = SchemaContextUtil.findDataSchemaNode(schemaContext, usesNode.getGroupingPath()); + final Iterable prefixedPath = usesNode.getGroupingPath().getPathFromRoot(); + final QName current = prefixedPath.iterator().next(); + final Module targetModule = schemaContext.findModule(current.getModule()).orElse(null); + Preconditions.checkArgument(targetModule != null, "Cannot find target module for %s and %s.", + current.getNamespace(), current.getRevision()); + groupingNode = targetModule.getGroupings().stream() + .filter(grouping -> grouping.getPath().equals(usesNode.getGroupingPath())) + .collect(Collectors.toList()).get(0); + if (groupingNode == null) { + groupingNode = SchemaContextUtil.findDataSchemaNode(schemaContext, usesNode.getGroupingPath()); + } } - Preconditions.checkNotNull(groupingNode, module.toString() + "->" - + usesNode.getGroupingPath().toString()); - Preconditions.checkState(groupingNode instanceof GroupingDefinition, - module.toString() + "->" + usesNode.getGroupingPath().toString()); + + requireNonNull(groupingNode, () -> module + "->" + usesNode.getGroupingPath()); + Preconditions.checkState(groupingNode instanceof GroupingDefinition, "%s->%s", module, + usesNode.getGroupingPath()); return (GroupingDefinition) groupingNode; } static Map processUsesImplements(final Object node, final Module module, - final SchemaContext schemaContext, Map genCtx, final BindingNamespaceType namespaceType) { + final SchemaContext schemaContext, final Map genCtx, final BindingNamespaceType namespaceType) { if (node instanceof DataNodeContainer) { for (final UsesNode usesNode : ((DataNodeContainer) node).getUses()) { final GroupingDefinition grouping = findGroupingNodeFromUses(module, schemaContext, node, usesNode); @@ -393,21 +404,21 @@ final class GenHelperUtil { return null; } - static Map addRawAugmentGenTypeDefinition(final Module module, final String augmentPackageName, - final Type targetTypeRef, final SchemaNode targetNode, final List schemaPathAugmentListEntry, - final Map> genTypeBuilders, final Map genCtx, + static Map addRawAugmentGenTypeDefinition(final Module module, + final String augmentPackageName, final GeneratedTypeBuilder targetTypeBuilder, final SchemaNode targetNode, + final List schemaPathAugmentListEntry, final Map> genTypeBuilders, final Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { //pick augmentation grouped by augmentation target, there is always at least one - final AugmentationSchema augSchema = schemaPathAugmentListEntry.get(0); - - Map augmentBuilders = genTypeBuilders.computeIfAbsent( - augmentPackageName, k -> new HashMap<>()); + final AugmentationSchemaNode augSchema = schemaPathAugmentListEntry.get(0); //this requires valid semantics in YANG model String augIdentifier = null; - for (AugmentationSchema aug : schemaPathAugmentListEntry) { + for (AugmentationSchemaNode aug : schemaPathAugmentListEntry) { + // FIXME: when there're multiple augment identifiers for augmentations of same target, + // it would pick the first identifier. augIdentifier = getAugmentIdentifier(aug.getUnknownSchemaNodes()); break; } @@ -422,26 +433,40 @@ final class GenHelperUtil { augTypeBuilder.addImplementsType(BindingTypes.TREE_NODE); augTypeBuilder.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, augTypeBuilder)); - augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); + augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeBuilder.toInstance())); augTypeBuilder.setBasePackageName(BindingMapping.getRootPackageName(module)); augTypeBuilder.setWithBuilder(true); + augTypeBuilder.setBindingNamespaceType(namespaceType); annotateDeprecatedIfNecessary(augSchema.getStatus(), augTypeBuilder); + //If target is case node then pass down parent type (the closest ancestor) to children data nodes. + final GeneratedTypeBuilder childOf; + if (targetNode instanceof CaseSchemaNode) { + childOf = (GeneratedTypeBuilder) targetTypeBuilder.getParentTypeForBuilder(); + } else { + augTypeBuilder.setParentTypeForBuilder(targetTypeBuilder); + childOf = targetTypeBuilder; + } + //produces getters for augTypeBuilder eventually - for (AugmentationSchema aug : schemaPathAugmentListEntry) { + for (AugmentationSchemaNode aug : schemaPathAugmentListEntry) { //apply all uses addImplementedInterfaceFromUses(aug, augTypeBuilder, genCtx); - augSchemaNodeToMethods(module, BindingMapping.getRootPackageName(module), augTypeBuilder, augTypeBuilder, aug.getChildNodes(), - genCtx, schemaContext, verboseClassComments, typeProvider, genTypeBuilders, namespaceType); + augSchemaNodeToMethods(module, BindingMapping.getRootPackageName(module), augTypeBuilder, childOf, + aug.getChildNodes(), genCtx, schemaContext, verboseClassComments, typeProvider, genTypeBuilders, + targetTypeBuilder.getBindingNamespaceType()); } + final Map augmentBuilders = genTypeBuilders.computeIfAbsent( + augmentPackageName, k -> new HashMap<>()); + augmentBuilders.put(augTypeBuilder.getName(), augTypeBuilder); - if(!augSchema.getChildNodes().isEmpty()) { - genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema); + if (!augSchema.getChildNodes().isEmpty()) { genCtx.get(module).addTargetToAugmentation(augTypeBuilder, augSchema.getTargetPath()); } genCtx.get(module).addAugmentType(augTypeBuilder); + genCtx.get(module).addTypeToAugmentations(augTypeBuilder, schemaPathAugmentListEntry); return genCtx; } @@ -449,28 +474,25 @@ final class GenHelperUtil { * Adds the methods to typeBuilder what represents subnodes of * node for which typeBuilder was created. * - * @param module - * current module - * @param basePackageName - * string contains the module package name - * @param typeBuilder - * generated type builder which represents any node. The subnodes - * of this node are added to the typeBuilder as - * methods. The subnode can be of type leaf, leaf-list, list, - * container, choice. - * @param childOf - * parent type - * @param schemaNodes - * set of data schema nodes which are the children of the node - * for which typeBuilder was created - * @return generated type builder which is the same object as the input - * parameter typeBuilder. The getter method could be - * added to it. + * @param module current module + * @param basePackageName string contains the module package name + * @param typeBuilder generated type builder which represents any node. The subnodes + * of this node are added to the typeBuilder as + * methods. The subnode can be of type leaf, leaf-list, list, + * container, choice. + * @param childOf parent type + * @param schemaNodes set of data schema nodes which are the children of the node + * for which typeBuilder was created + * @return generated type builder which is the same object as the input added to it. */ private static GeneratedTypeBuilder augSchemaNodeToMethods(final Module module, final String basePackageName, - final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Iterable schemaNodes, - final Map genCtx, final SchemaContext schemaContext, final boolean - verboseClassComments, final TypeProvider typeProvider, final Map schemaNodes, + final Map genCtx, final + SchemaContext schemaContext, final boolean + verboseClassComments, final TypeProvider + typeProvider, final Map> genTypeBuilders, final BindingNamespaceType namespaceType) { if (schemaNodes != null && typeBuilder != null) { for (final DataSchemaNode schemaNode : schemaNodes) { @@ -487,6 +509,7 @@ final class GenHelperUtil { * Instantiates generated type builder with packageName and * schemaNode. * + *

* The new builder always implements * {@link TreeNode TreeNode}.
* If schemaNode is instance of GroupingDefinition it also @@ -497,48 +520,39 @@ final class GenHelperUtil { * DataNodeContainer} it can also implement nodes which are specified in * uses. * - * @param basePackageName - * string contains the module package name - * @param schemaNode - * schema node for which is created generated type builder - * @param parent - * parent type (can be null) - * @param schemaContext schema context + * @param basePackageName string contains the module package name + * @param schemaNode schema node for which is created generated type builder + * @param childOf parent generated type of data tree node, which should be + * set null if current schema node is not a data tree node. + * @param schemaContext schema context * @return generated type builder schemaNode */ - private static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String basePackageName, final SchemaNode - schemaNode, final Type parent, final Module module, final Map genCtx, - final SchemaContext schemaContext, final boolean verboseClassComments, final Map> genTypeBuilders, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { - - String suffix = ""; - if (schemaNode instanceof GroupingDefinition) { - suffix = "grouping"; - } else if (namespaceType.equals(BindingNamespaceType.Grouping)) { - suffix = "data"; - } - - GeneratedTypeBuilder it = addRawInterfaceDefinition(basePackageName, schemaNode, schemaContext, "", suffix, + public static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String basePackageName, final SchemaNode + schemaNode, @Nullable final Type childOf, final Module module, final Map genCtx, + final SchemaContext schemaContext, final boolean + verboseClassComments, final Map> genTypeBuilders, final TypeProvider typeProvider, final BindingNamespaceType + namespaceType) { + + GeneratedTypeBuilder it = addRawInterfaceDefinition(basePackageName, schemaNode, schemaContext, "", "", verboseClassComments, genTypeBuilders, namespaceType, genCtx.get(module)); - if (namespaceType.equals(BindingNamespaceType.Data)) { - if (parent == null) { + if (BindingNamespaceType.isData(namespaceType)) { + if (childOf == null) { it.addImplementsType(BindingTypes.TREE_NODE); } else { - if (parent instanceof ListSchemaNode) { - it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, parent, parameterizedTypeFor - (BindingTypes.IDENTIFIABLE_ITEM, parent))); - } else { - it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, parent, parameterizedTypeFor - (BindingTypes.ITEM, parent))); - it.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, it)); + if (!(schemaNode instanceof ListSchemaNode) + || ((ListSchemaNode) schemaNode).getKeyDefinition().isEmpty()) { + it.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, childOf, + parameterizedTypeFor(BindingTypes.ITEM, it))); } } - if (!(schemaNode instanceof GroupingDefinition)) { - it.addImplementsType(BindingTypes.augmentable(it)); + if (!(schemaNode instanceof CaseSchemaNode)) { + it.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, it)); } - } else { - it.addImplementsType(BindingTypes.TREE_NODE); + + it.addImplementsType(BindingTypes.augmentable(it)); } if (schemaNode instanceof DataNodeContainer) { @@ -550,13 +564,16 @@ final class GenHelperUtil { return it; } - static GeneratedTypeBuilder resolveNotification(final GeneratedTypeBuilder listenerInterface, String + static GeneratedTypeBuilder resolveNotification(final GeneratedTypeBuilder listenerInterface, final String parentName, final String basePackageName, final NotificationDefinition notification, final Module module, - final SchemaContext schemaContext, final boolean verboseClassComments, Map> - genTypeBuilders, TypeProvider typeProvider, Map genCtx) { - final GeneratedTypeBuilder notificationInterface = addDefaultInterfaceDefinition - (basePackageName, notification, null, module, genCtx, schemaContext, - verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Data); + final SchemaContext schemaContext, final boolean + verboseClassComments, final Map> + genTypeBuilders, final TypeProvider typeProvider, final + Map genCtx) { + final GeneratedTypeBuilder notificationInterface = addDefaultInterfaceDefinition(basePackageName, notification, + null, module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, + BindingNamespaceType.Notification); annotateDeprecatedIfNecessary(notification.getStatus(), notificationInterface); notificationInterface.addImplementsType(NOTIFICATION); genCtx.get(module).addChildNodeType(notification, notificationInterface); @@ -564,7 +581,7 @@ final class GenHelperUtil { // Notification object resolveDataSchemaNodes(module, basePackageName, notificationInterface, notificationInterface, notification.getChildNodes(), genCtx, schemaContext, - verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Data); + verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Notification); //in case of tied notification, incorporate parent's localName final StringBuilder sb = new StringBuilder("on_"); @@ -573,9 +590,10 @@ final class GenHelperUtil { } sb.append(notificationInterface.getName()); - listenerInterface.addMethod(JavaIdentifierNormalizer.normalizeSpecificIdentifier(sb.toString(), JavaIdentifier.METHOD)) + listenerInterface.addMethod(JavaIdentifierNormalizer.normalizeSpecificIdentifier(sb.toString(), + JavaIdentifier.METHOD)) .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification") - .setComment(encodeAngleBrackets(notification.getDescription())).setReturnType(Types.VOID); + .setComment(encodeAngleBrackets(notification.getDescription().orElse(null))).setReturnType(Types.VOID); return listenerInterface; } @@ -583,31 +601,30 @@ final class GenHelperUtil { * Returns reference to generated type builder for specified * schemaNode with packageName. * + *

* Firstly the generated type builder is searched in * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't * found it is created and added to genTypeBuilders. * - * @param basePackageName - * string contains the module package name - * @param schemaNode - * schema node which provide data about the schema node name - * @param schemaContext schema context - * @param prefix - * return type name prefix + * @param basePackageName string contains the module package name + * @param schemaNode schema node which provide data about the schema node name + * @param schemaContext schema context + * @param prefix return type name prefix * @return generated type builder for schemaNode - * @throws IllegalArgumentException - *

- * + * @throws IllegalArgumentException */ static GeneratedTypeBuilder addRawInterfaceDefinition(final String basePackageName, final SchemaNode schemaNode, - final SchemaContext schemaContext, final String prefix, final String suffix, - final boolean verboseClassComments, final Map> genTypeBuilders, - final BindingNamespaceType namespaceType, ModuleContext context) { + final SchemaContext schemaContext, final String prefix, + final String suffix, + final boolean verboseClassComments, final Map> genTypeBuilders, + final BindingNamespaceType namespaceType, final + ModuleContext context) { Preconditions.checkArgument(schemaNode != null, "Data Schema Node cannot be NULL."); Preconditions.checkArgument(basePackageName != null, "Base package Name for Generated Type cannot be NULL."); @@ -628,14 +645,17 @@ final class GenHelperUtil { final GeneratedTypeBuilderImpl newType = new GeneratedTypeBuilderImpl(packageName, schemaNodeName, context); final Module module = SchemaContextUtil.findParentModule(schemaContext, schemaNode); qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, schemaNode.getQName()); - newType.addComment(schemaNode.getDescription()); - newType.setDescription(createDescription(schemaNode, newType.getFullyQualifiedName(), schemaContext, - verboseClassComments, namespaceType)); - newType.setReference(schemaNode.getReference()); + if (verboseClassComments) { + YangSourceDefinition.of(module, schemaNode).ifPresent(newType::setYangSourceDefinition); + TypeComments.description(schemaNode).ifPresent(newType::addComment); + schemaNode.getDescription().ifPresent(newType::setDescription); + schemaNode.getReference().ifPresent(newType::setReference); + } newType.setSchemaPath((List) schemaNode.getPath().getPathFromRoot()); newType.setModuleName(module.getName()); newType.setBasePackageName(BindingMapping.getRootPackageName(module)); newType.setWithBuilder(AuxiliaryGenUtils.hasBuilderClass(schemaNode, namespaceType)); + newType.setBindingNamespaceType(namespaceType); if (!genTypeBuilders.containsKey(packageName)) { final Map builders = new HashMap<>(); @@ -652,10 +672,13 @@ final class GenHelperUtil { } private static void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode node, - final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Module module, - final Map genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, - final Map> genTypeBuilders, final TypeProvider typeProvider, - final BindingNamespaceType namespaceType) { + final GeneratedTypeBuilder typeBuilder, final + GeneratedTypeBuilder childOf, final Module module, + final Map genCtx, final SchemaContext + schemaContext, final boolean verboseClassComments, + final Map> + genTypeBuilders, final TypeProvider typeProvider, + final BindingNamespaceType namespaceType) { if (node != null && typeBuilder != null) { if (node instanceof ContainerSchemaNode) { @@ -663,15 +686,15 @@ final class GenHelperUtil { schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); } else if (node instanceof LeafListSchemaNode) { resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) node, module, - typeProvider, genCtx); + typeProvider, genCtx, verboseClassComments); } else if (node instanceof LeafSchemaNode) { resolveLeafSchemaNodeAsMethod("", schemaContext, typeBuilder, genCtx, (LeafSchemaNode) node, module, - typeProvider); + typeProvider, verboseClassComments); } else if (node instanceof ListSchemaNode) { listToGenType(module, basePackageName, typeBuilder, childOf, (ListSchemaNode) node, schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); } else if (node instanceof ChoiceSchemaNode) { - choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, childOf, + choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, childOf, (ChoiceSchemaNode) node, genTypeBuilders, genCtx, typeProvider, namespaceType); } else if (node instanceof AnyXmlSchemaNode || node instanceof AnyDataSchemaNode) { resolveAnyNodeAsMethod(schemaContext, typeBuilder, genCtx, node, module, typeProvider); @@ -683,56 +706,59 @@ final class GenHelperUtil { * Converts choiceNode to the list of generated types for * choice and its cases. * + *

* The package names for choice and for its cases are created as * concatenation of the module package (basePackageName) and * names of all parents node. * - * @param module - * current module - * @param basePackageName - * string with the module package name - * @param parent - * parent type - * @param choiceNode - * choice node which is mapped to generated type. Also child - * nodes - cases are mapped to generated types. - * @throws IllegalArgumentException - *

    - *
  • if basePackageName is null
  • - *
  • if choiceNode is null
  • - *
+ * @param module current module + * @param basePackageName string with the module package name + * @param parent parent type + * @param choiceNode choice node which is mapped to generated type. Also child + * nodes - cases are mapped to generated types. + * @throws IllegalArgumentException
    + *
  • if basePackageName is null
  • + *
  • if choiceNode is null
  • + *
*/ private static void choiceToGenType(final Module module, final SchemaContext schemaContext, final boolean - verboseClasssComments, final String basePackageName, final GeneratedTypeBuilder parent, final - ChoiceSchemaNode choiceNode, final Map> genTypeBuilders, - final Map genCtx, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { + verboseClasssComments, final String basePackageName, final GeneratedTypeBuilder parent, + final GeneratedTypeBuilder childOf, final ChoiceSchemaNode choiceNode, + final Map> genTypeBuilders, + final Map genCtx, final TypeProvider typeProvider, + final BindingNamespaceType namespaceType) { checkArgument(basePackageName != null, "Base Package Name cannot be NULL."); checkArgument(choiceNode != null, "Choice Schema Node cannot be NULL."); final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(basePackageName, choiceNode, schemaContext, "", "", verboseClasssComments, genTypeBuilders, namespaceType, genCtx.get(module)); constructGetter(parent, choiceNode.getQName().getLocalName(), - choiceNode.getDescription(), choiceTypeBuilder, choiceNode.getStatus()); - if (namespaceType.equals(BindingNamespaceType.Data)) { + choiceNode.getDescription().orElse(null), choiceTypeBuilder, choiceNode.getStatus()); + choiceTypeBuilder.setParentTypeForBuilder(childOf); + if (BindingNamespaceType.isData(namespaceType)) { choiceTypeBuilder.addImplementsType(parameterizedTypeFor(BindingTypes.INSTANTIABLE, choiceTypeBuilder)); } annotateDeprecatedIfNecessary(choiceNode.getStatus(), choiceTypeBuilder); genCtx.get(module).addChildNodeType(choiceNode, choiceTypeBuilder); generateTypesFromChoiceCases(module, schemaContext, genCtx, basePackageName, choiceTypeBuilder.toInstance(), - choiceNode, verboseClasssComments, typeProvider, genTypeBuilders, namespaceType); + choiceNode, verboseClasssComments, typeProvider, genTypeBuilders, namespaceType); } private static void containerToGenType(final Module module, final String basePackageName, - final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final ContainerSchemaNode node, - final SchemaContext schemaContext, final boolean verboseClassComments, final Map genCtx, - final Map> genTypeBuilders, final TypeProvider typeProvider, - final BindingNamespaceType namespaceType) { + final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, + final ContainerSchemaNode node, + final SchemaContext schemaContext, final boolean verboseClassComments, + final Map genCtx, + final Map> genTypeBuilders, + final TypeProvider typeProvider, + final BindingNamespaceType namespaceType) { final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node, schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); if (genType != null) { StringBuilder getterName = new StringBuilder(node.getQName().getLocalName()); - final MethodSignatureBuilder getter = constructGetter(parent, getterName.toString(), node.getDescription(), genType, node.getStatus()); + constructGetter(parent, getterName.toString(), node.getDescription().orElse(null), genType, node + .getStatus()); resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes(), genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); processUsesImplements(node, module, schemaContext, genCtx, namespaceType); @@ -741,9 +767,10 @@ final class GenHelperUtil { private static void listToGenType(final Module module, final String basePackageName, final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final ListSchemaNode node, final SchemaContext schemaContext, - final boolean verboseClassComments, final Map genCtx, - final Map> genTypeBuilders, final TypeProvider typeProvider, - final BindingNamespaceType namespaceType) { + final boolean verboseClassComments, final Map genCtx, + final Map> genTypeBuilders, final + TypeProvider typeProvider, + final BindingNamespaceType namespaceType) { final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node, schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); @@ -751,43 +778,59 @@ final class GenHelperUtil { final String nodeName = node.getQName().getLocalName(); Type getterReturnType = Types.listTypeFor(genType); - if (namespaceType.equals(BindingNamespaceType.Grouping)) { + if (BindingNamespaceType.isGrouping(namespaceType)) { getterReturnType = Types.listTypeFor(wildcardTypeFor(genType.getPackageName(), genType.getName(), - true, true, null)); + true, true, null)); } - constructGetter(parent, nodeName, node.getDescription(), getterReturnType, node.getStatus()); + constructGetter(parent, nodeName, node.getDescription().orElse(null), getterReturnType, node.getStatus()); final List listKeys = node.getKeyDefinition(); final String packageName = new StringBuilder(packageNameForGeneratedType(basePackageName, node.getPath(), BindingNamespaceType.Key)).append('.').append(nodeName).toString(); //FIXME: Is it neccessary to generate interface of key and implemented by class? - if (namespaceType.equals(BindingNamespaceType.Grouping)) { - final GeneratedTypeBuilder genTypeBuilder = resolveListKeyTypeBuilder(packageName, node, genCtx.get(module)); + if (BindingNamespaceType.isGrouping(namespaceType)) { + final GeneratedTypeBuilder genTypeBuilder = resolveListKeyTypeBuilder(packageName, node, + genCtx.get(module)); for (final DataSchemaNode schemaNode : node.getChildNodes()) { if (resolveDataSchemaNodesCheck(module, schemaContext, schemaNode)) { - addSchemaNodeToListTypeBuilders(nodeName, basePackageName, schemaNode, genType, genTypeBuilder, listKeys, - module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, namespaceType); + addSchemaNodeToListTypeBuilders(nodeName, basePackageName, schemaNode, genType, + genTypeBuilder, listKeys, + module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, + namespaceType); } } if (genTypeBuilder != null) { typeBuildersToGenTypes(module, genType, genTypeBuilder.toInstance(), genCtx, namespaceType); genCtx.get(module).addKeyType(node.getPath(), genTypeBuilder); } + processUsesImplements(node, module, schemaContext, genCtx, namespaceType); } else { final GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, node, genCtx.get(module)); + if (genTOBuilder != null) { + final Type identifiableMarker = Types.parameterizedTypeFor(IDENTIFIABLE, genTOBuilder); + genTOBuilder.addImplementsType(IDENTIFIER); + genType.addImplementsType(identifiableMarker); + if (BindingNamespaceType.isData(namespaceType)) { + genType.addImplementsType(parameterizedTypeFor(BindingTypes.TREE_CHILD_NODE, childOf, + parameterizedTypeFor(BindingTypes.IDENTIFIABLE_ITEM, genType, genTOBuilder))); + } + } + for (final DataSchemaNode schemaNode : node.getChildNodes()) { if (resolveDataSchemaNodesCheck(module, schemaContext, schemaNode)) { - addSchemaNodeToListBuilders(nodeName, basePackageName, schemaNode, genType, genTOBuilder, listKeys, - module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, namespaceType); + addSchemaNodeToListBuilders(nodeName, basePackageName, schemaNode, genType, genTOBuilder, + listKeys, + module, typeProvider, schemaContext, genCtx, genTypeBuilders, verboseClassComments, + namespaceType); } } + processUsesImplements(node, module, schemaContext, genCtx, namespaceType); // serialVersionUID if (genTOBuilder != null) { final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID"); prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder))); genTOBuilder.setSUID(prop); - typeBuildersToGenTypes(module, genType, genTOBuilder.toInstance(), genCtx, namespaceType); genCtx.get(module).addGeneratedTOBuilder(node.getPath(), genTOBuilder); } @@ -796,42 +839,53 @@ final class GenHelperUtil { } private static void typeBuildersToGenTypes(final Module module, final GeneratedTypeBuilder typeBuilder, - final Type keyType, final Map genCtx, - final BindingNamespaceType namespaceType) { + final Type keyType, final Map genCtx, + final BindingNamespaceType namespaceType) { checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL."); if (keyType != null) { Type returnKeyType = keyType; - if (namespaceType.equals(BindingNamespaceType.Grouping)) { + if (BindingNamespaceType.isGrouping(namespaceType)) { returnKeyType = wildcardTypeFor(keyType.getPackageName(), keyType.getName(), true, true, null); } - constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", returnKeyType, Status.CURRENT); + constructGetter(typeBuilder, "identifier", "Returns Primary Key of Yang List Type", returnKeyType, Status + .CURRENT); } } + private static void addPatternConstant(final GeneratedTypeBuilder typeBuilder, final String leafName, + final List patternConstraints) { + if (!patternConstraints.isEmpty()) { + final StringBuilder field = new StringBuilder(); + field.append(BindingMapping.PATTERN_CONSTANT_NAME).append("_") + .append(JavaIdentifierNormalizer.normalizeSpecificIdentifier(leafName, JavaIdentifier.METHOD)); + typeBuilder.addConstant(Types.listTypeFor(BaseYangTypes.STRING_TYPE), field.toString(), + resolveRegExpressions(patternConstraints)); + } + } + /** * Converts leaf to the getter method which is added to * typeBuilder. * - * @param typeBuilder - * generated type builder to which is added getter method as - * leaf mapping - * @param leaf - * leaf schema node which is mapped as getter method which is - * added to typeBuilder - * @param module - * Module in which type was defined + * @param typeBuilder generated type builder to which is added getter method as + * leaf mapping + * @param leaf leaf schema node which is mapped as getter method which is + * added to typeBuilder + * @param module Module in which type was defined * @return boolean value - *
    - *
  • false - if leaf or typeBuilder are - * null
  • - *
  • true - in other cases
  • - *
+ *
    + *
  • false - if leaf or typeBuilder are + * null
  • + *
  • true - in other cases
  • + *
*/ private static Type resolveLeafSchemaNodeAsMethod(final String nodeName, final SchemaContext schemaContext, - final GeneratedTypeBuilder typeBuilder, final Map genCtx, final LeafSchemaNode leaf, - final Module module, final TypeProvider typeProvider) { + final GeneratedTypeBuilder typeBuilder, final Map genCtx, final LeafSchemaNode leaf, + final Module module, final TypeProvider typeProvider, final + boolean verboseClassComments) { if (leaf == null || typeBuilder == null) { return null; } @@ -845,7 +899,28 @@ final class GenHelperUtil { Type returnType = null; final TypeDefinition typeDef = leaf.getType(); - if (isInnerType(leaf, typeDef)) { + + if (leaf.isAddedByUses()) { + Preconditions.checkState(leaf instanceof DerivableSchemaNode); + if (isInnerType(leaf, typeDef)) { + final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(getBaseOrDeclaredType(typeDef), leaf, + restrictions, genCtx.get(module)); + } else { + if (typeDef.getBaseType() == null && (typeDef instanceof EnumTypeDefinition + || typeDef instanceof UnionTypeDefinition || typeDef instanceof BitsTypeDefinition)) { + LeafSchemaNode originalLeaf = (LeafSchemaNode) ((DerivableSchemaNode) leaf).getOriginal() + .orElse(null); + requireNonNull(originalLeaf); + returnType = genCtx.get(findParentModule(schemaContext, originalLeaf)).getInnerType(typeDef + .getPath()); + } else { + final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions, + genCtx.get(module)); + } + } + } else if (isInnerType(leaf, typeDef)) { if (typeDef instanceof EnumTypeDefinition) { returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, genCtx.get(module)); final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef; @@ -857,14 +932,15 @@ final class GenHelperUtil { ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType); } else if (typeDef instanceof UnionTypeDefinition) { final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule, - typeProvider, schemaContext, genCtx.get(module)); + typeProvider, schemaContext, genCtx.get(module), genCtx); if (genTOBuilder != null) { //TODO: https://bugs.opendaylight.org/show_bug.cgi?id=2289 - returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider); + returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, + typeProvider, verboseClassComments); } } else if (typeDef instanceof BitsTypeDefinition) { final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule, - typeProvider, schemaContext, genCtx.get(module)); + typeProvider, schemaContext, genCtx.get(module), genCtx); if (genTOBuilder != null) { returnType = genTOBuilder.toInstance(); } @@ -876,10 +952,12 @@ final class GenHelperUtil { final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); returnType = typeProvider.javaTypeForSchemaDefinitionType(getBaseOrDeclaredType(typeDef), leaf, restrictions, genCtx.get(module)); + addPatternConstant(typeBuilder, leafName, restrictions.getPatternConstraints()); } } else { final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions, genCtx.get(module)); + addPatternConstant(typeBuilder, leafName, restrictions.getPatternConstraints()); } if (returnType == null) { @@ -890,20 +968,15 @@ final class GenHelperUtil { ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType); } - String leafDesc = leaf.getDescription(); - if (leafDesc == null) { - leafDesc = ""; - } - final String leafGetterName; if ("key".equals(leafName.toLowerCase())) { StringBuilder sb = new StringBuilder(leafName) - .append('_').append("RESERVED_WORD"); + .append('_').append("RESERVED_WORD"); leafGetterName = sb.toString(); } else { leafGetterName = leafName; } - constructGetter(typeBuilder, leafGetterName, leafDesc, returnType, leaf.getStatus()); + constructGetter(typeBuilder, leafGetterName, leaf.getDescription().orElse(""), returnType, leaf.getStatus()); return returnType; } @@ -911,25 +984,24 @@ final class GenHelperUtil { * Converts node leaf list schema node to getter method of * typeBuilder. * - * @param typeBuilder - * generated type builder to which is node added as - * getter method - * @param node - * leaf list schema node which is added to - * typeBuilder as getter method - * @param module module + * @param typeBuilder generated type builder to which is node added as + * getter method + * @param node leaf list schema node which is added to + * typeBuilder as getter method + * @param module module * @param typeProvider type provider instance - * @param genCtx actual generated context + * @param genCtx actual generated context * @return boolean value - *
    - *
  • true - if node, typeBuilder, - * nodeName equal null or node is added by uses
  • - *
  • false - other cases
  • - *
+ *
    + *
  • true - if node, typeBuilder, + * nodeName equal null or node is added by uses
  • + *
  • false - other cases
  • + *
*/ private static boolean resolveLeafListSchemaNode(final SchemaContext schemaContext, final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node, final Module module, final TypeProvider typeProvider, - final Map genCtx) { + final Map genCtx, final boolean + verboseClassComments) { if (node == null || typeBuilder == null) { return false; } @@ -946,30 +1018,37 @@ final class GenHelperUtil { final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef; final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, genCtx, typeBuilder, module); - returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName(), - genCtx.get(module)); + returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName(), true, + null); ((TypeProviderImpl) typeProvider).putReferencedType(node.getPath(), returnType); } else if (typeDef instanceof UnionTypeDefinition) { final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule, - typeProvider, schemaContext, genCtx.get(module)); + typeProvider, schemaContext, genCtx.get(module), genCtx); if (genTOBuilder != null) { - returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider); + returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, + typeProvider, verboseClassComments); } } else if (typeDef instanceof BitsTypeDefinition) { final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule, - typeProvider, schemaContext, genCtx.get(module)); + typeProvider, schemaContext, genCtx.get(module), genCtx); returnType = genTOBuilder.toInstance(); } else { final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); - returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions, genCtx.get(module)); + returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions, + genCtx.get(module)); + + addPatternConstant(typeBuilder, nodeName.getLocalName(), restrictions.getPatternConstraints()); } } else { final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef); returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions, genCtx.get(module)); + + addPatternConstant(typeBuilder, nodeName.getLocalName(), restrictions.getPatternConstraints()); } final ParameterizedType listType = Types.listTypeFor(returnType); - constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription(), listType, node.getStatus()); + constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription().orElse(null), listType, node + .getStatus()); return true; } @@ -977,6 +1056,7 @@ final class GenHelperUtil { * Converts caseNodes set to list of corresponding generated * types. * + *

* For every case which isn't added through augment or uses is * created generated type builder. The package names for the builder is * created as concatenation of the module package ( @@ -984,109 +1064,63 @@ final class GenHelperUtil { * concrete case. There is also relation "implements type" * between every case builder and choice type * - * @param module - * current module - * @param schemaContext - * current schema context - * @param genCtx - * actual generated context - * @param basePackageName - * string with the module package name - * @param refChoiceType - * type which represents superior case - * @param choiceNode - * choice case node which is mapped to generated type - * @param verboseClassComments - * Javadoc verbosity switch - * @throws IllegalArgumentException - *

    - *
  • if basePackageName equals null
  • - *
  • if refChoiceType equals null
  • - *
  • if caseNodes equals null
  • - *
+ * @param module current module + * @param schemaContext current schema context + * @param genCtx actual generated context + * @param basePackageName string with the module package name + * @param refChoiceType type which represents superior case + * @param choiceNode choice case node which is mapped to generated type + * @param verboseClassComments Javadoc verbosity switch + * @throws IllegalArgumentException
    + *
  • if basePackageName equals null
  • + *
  • if refChoiceType equals null
  • + *
  • if caseNodes equals null
  • + *
*/ private static void generateTypesFromChoiceCases(final Module module, final SchemaContext schemaContext, - final Map genCtx, final String basePackageName, final Type refChoiceType, - final ChoiceSchemaNode choiceNode, final boolean verboseClassComments, final TypeProvider typeProvider, - final Map> genTypeBuilders, final BindingNamespaceType namespaceType) { + final Map genCtx, final String + basePackageName, final GeneratedType refChoiceType, + final ChoiceSchemaNode choiceNode, final boolean + verboseClassComments, + final TypeProvider typeProvider, final Map> genTypeBuilders, + final BindingNamespaceType namespaceType) { checkArgument(basePackageName != null, "Base Package Name cannot be NULL."); checkArgument(refChoiceType != null, "Referenced Choice Type cannot be NULL."); checkArgument(choiceNode != null, "ChoiceNode cannot be NULL."); - final Set caseNodes = choiceNode.getCases(); - if (caseNodes == null) { - return; - } - - for (final ChoiceCaseNode caseNode : caseNodes) { + for (final CaseSchemaNode caseNode : choiceNode.getCases().values()) { if (caseNode != null && resolveDataSchemaNodesCheck(module, schemaContext, caseNode)) { final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(basePackageName, caseNode, - module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); + null, module, genCtx, schemaContext, verboseClassComments, + genTypeBuilders, typeProvider, namespaceType); caseTypeBuilder.addImplementsType(refChoiceType); - caseTypeBuilder.setParentTypeForBuilder(refChoiceType); + caseTypeBuilder.setParentTypeForBuilder(refChoiceType.getParentTypeForBuilder()); annotateDeprecatedIfNecessary(caseNode.getStatus(), caseTypeBuilder); genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder); - genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder, caseNode); - final Iterable caseChildNodes = caseNode.getChildNodes(); - if (caseChildNodes != null) { - final SchemaPath choiceNodeParentPath = choiceNode.getPath().getParent(); - - if (!Iterables.isEmpty(choiceNodeParentPath.getPathFromRoot())) { - SchemaNode parent = findDataSchemaNode(schemaContext, choiceNodeParentPath); - - if (parent instanceof AugmentationSchema) { - final AugmentationSchema augSchema = (AugmentationSchema) parent; - final SchemaPath targetPath = augSchema.getTargetPath(); - SchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); - if (targetSchemaNode instanceof DataSchemaNode - && ((DataSchemaNode) targetSchemaNode).isAddedByUses()) { - if (targetSchemaNode instanceof DerivableSchemaNode) { - targetSchemaNode = ((DerivableSchemaNode) targetSchemaNode).getOriginal().orNull(); - } - if (targetSchemaNode == null) { - throw new IllegalStateException( - "Failed to find target node from grouping for augmentation " + augSchema - + " in module " + module.getName()); - } - } - parent = targetSchemaNode; - } - - Preconditions.checkState(parent != null, "Could not find Choice node parent %s", - choiceNodeParentPath); - GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.getPath(), genCtx); - if (childOfType == null) { - childOfType = findGroupingByPath(parent.getPath(), genCtx); - } - resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes, - genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); - } else { - resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, moduleToDataType(module, - genCtx, verboseClassComments), caseChildNodes, genCtx, schemaContext, - verboseClassComments, genTypeBuilders, typeProvider, namespaceType); - } + if (BindingNamespaceType.isData(namespaceType)) { + genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder, caseNode); } + + resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, + (GeneratedTypeBuilder) refChoiceType.getParentTypeForBuilder(), caseNode.getChildNodes(), + genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); + processUsesImplements(caseNode, module, schemaContext, genCtx, namespaceType); } } } private static Type resolveAnyNodeAsMethod(final SchemaContext schemaContext, final GeneratedTypeBuilder typeBuilder, final Map genCtx, final DataSchemaNode node, final Module module, - final TypeProvider typeProvider) { + final TypeProvider typeProvider) { final String anyName = node.getQName().getLocalName(); if (anyName == null) { return null; } - String anyDesc = node.getDescription(); - if (anyDesc == null) { - anyDesc = ""; - } - Type returnType = Types.DOCUMENT; - - constructGetter(typeBuilder, anyName, anyDesc, returnType, node.getStatus()); + constructGetter(typeBuilder, anyName, node.getDescription().orElse(""), returnType, node.getStatus()); return returnType; } @@ -1094,44 +1128,35 @@ final class GenHelperUtil { * Adds schemaNode to typeBuilder as getter method * or to genTOBuilder as property. * - * @param nodeName - * string contains the name of list - * @param basePackageName - * string contains the module package name - * @param schemaNode - * data schema node which should be added as getter method to - * typeBuilder or as a property to - * genTOBuilder if is part of the list key - * @param typeBuilder - * generated type builder for the list schema node - * @param genTOBuilder - * generated TO builder for the list keys - * @param listKeys - * list of string which contains QNames of the list keys - * @param module - * current module - * @param typeProvider - * provider that defines contract for generated types - * @param schemaContext - * schema context - * @param genCtx - * map of generated entities in context of YANG modules - * @param genTypeBuilders - * map of generated type builders - * @param verboseClassComments - * generate verbose comments - * @throws IllegalArgumentException - *
    - *
  • if schemaNode equals null
  • - *
  • if typeBuilder equals null
  • - *
+ * @param nodeName string contains the name of list + * @param basePackageName string contains the module package name + * @param schemaNode data schema node which should be added as getter method to + * typeBuilder or as a property to + * genTOBuilder if is part of the list key + * @param typeBuilder generated type builder for the list schema node + * @param genTOBuilder generated TO builder for the list keys + * @param listKeys list of string which contains QNames of the list keys + * @param module current module + * @param typeProvider provider that defines contract for generated types + * @param schemaContext schema context + * @param genCtx map of generated entities in context of YANG modules + * @param genTypeBuilders map of generated type builders + * @param verboseClassComments generate verbose comments + * @throws IllegalArgumentException
    + *
  • if schemaNode equals null
  • + *
  • if typeBuilder equals null
  • + *
*/ private static void addSchemaNodeToListBuilders(final String nodeName, final String basePackageName, - final DataSchemaNode schemaNode, final GeneratedTypeBuilder typeBuilder, - final GeneratedTOBuilder genTOBuilder, final List listKeys, final Module module, - final TypeProvider typeProvider, final SchemaContext schemaContext, final Map genCtx, - final Map> genTypeBuilders, final boolean verboseClassComments, - final BindingNamespaceType namespaceType) { + final DataSchemaNode schemaNode, final GeneratedTypeBuilder + typeBuilder, + final GeneratedTOBuilder genTOBuilder, final List + listKeys, final Module module, + final TypeProvider typeProvider, final SchemaContext + schemaContext, final Map genCtx, + final Map> + genTypeBuilders, final boolean verboseClassComments, + final BindingNamespaceType namespaceType) { checkArgument(schemaNode != null, "Data Schema Node cannot be NULL."); checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL."); @@ -1140,11 +1165,12 @@ final class GenHelperUtil { final QName leafQName = leaf.getQName(); final Type type = resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, typeBuilder, genCtx, leaf, module, - typeProvider); + typeProvider, verboseClassComments); if (listKeys.contains(leafQName)) { if (type == null) { - resolveLeafSchemaNodeAsProperty(nodeName, schemaContext, typeProvider, genCtx, genTOBuilder, leaf, true, - module); + resolveLeafSchemaNodeAsProperty(nodeName, schemaContext, typeProvider, genCtx, genTOBuilder, + leaf, true, + module); } else { AuxiliaryGenUtils.resolveLeafSchemaNodeAsProperty(nodeName, genTOBuilder, leaf, type, true); } @@ -1152,7 +1178,7 @@ final class GenHelperUtil { } else { if (schemaNode instanceof LeafListSchemaNode) { resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) schemaNode, module, - typeProvider, genCtx); + typeProvider, genCtx, verboseClassComments); } else if (schemaNode instanceof ContainerSchemaNode) { containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode, schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); @@ -1160,18 +1186,22 @@ final class GenHelperUtil { listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode, schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); } else if (schemaNode instanceof ChoiceSchemaNode) { - choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, + choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, typeBuilder, (ChoiceSchemaNode) schemaNode, genTypeBuilders, genCtx, typeProvider, namespaceType); } } } private static void addSchemaNodeToListTypeBuilders(final String nodeName, final String basePackageName, - final DataSchemaNode schemaNode, final GeneratedTypeBuilder typeBuilder, - final GeneratedTypeBuilder genTypeBuilder, final List listKeys, final Module module, - final TypeProvider typeProvider, final SchemaContext schemaContext, final Map genCtx, - final Map> genTypeBuilders, final boolean verboseClassComments, - final BindingNamespaceType namespaceType) { + final DataSchemaNode schemaNode, final GeneratedTypeBuilder + typeBuilder, + final GeneratedTypeBuilder genTypeBuilder, final List + listKeys, final Module module, + final TypeProvider typeProvider, final SchemaContext + schemaContext, final Map genCtx, + final Map> + genTypeBuilders, final boolean verboseClassComments, + final BindingNamespaceType namespaceType) { checkArgument(schemaNode != null, "Data Schema Node cannot be NULL."); checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL."); @@ -1179,15 +1209,15 @@ final class GenHelperUtil { final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode; final QName leafQName = leaf.getQName(); final Type type = resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, typeBuilder, genCtx, leaf, module, - typeProvider); + typeProvider, verboseClassComments); if (listKeys.contains(leafQName)) { resolveLeafSchemaNodeAsMethod(nodeName, schemaContext, genTypeBuilder, genCtx, leaf, module, - typeProvider); + typeProvider, verboseClassComments); } } else { if (schemaNode instanceof LeafListSchemaNode) { resolveLeafListSchemaNode(schemaContext, typeBuilder, (LeafListSchemaNode) schemaNode, module, - typeProvider, genCtx); + typeProvider, genCtx, verboseClassComments); } else if (schemaNode instanceof ContainerSchemaNode) { containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode, schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); @@ -1195,15 +1225,18 @@ final class GenHelperUtil { listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode, schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider, namespaceType); } else if (schemaNode instanceof ChoiceSchemaNode) { - choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, + choiceToGenType(module, schemaContext, verboseClassComments, basePackageName, typeBuilder, typeBuilder, (ChoiceSchemaNode) schemaNode, genTypeBuilders, genCtx, typeProvider, namespaceType); } } } - private static boolean resolveLeafSchemaNodeAsProperty(final String nodeName, final SchemaContext schemaContext, final TypeProvider - typeProvider, final Map genCtx, final GeneratedTOBuilder - toBuilder, final LeafSchemaNode leaf, final boolean isReadOnly, final Module module) { + private static boolean resolveLeafSchemaNodeAsProperty(final String nodeName, final SchemaContext schemaContext, + final TypeProvider + typeProvider, final Map + genCtx, final GeneratedTOBuilder + toBuilder, final LeafSchemaNode leaf, final + boolean isReadOnly, final Module module) { if (leaf != null && toBuilder != null) { Type returnType; @@ -1212,16 +1245,14 @@ final class GenHelperUtil { // GeneratedType for this type definition should be already // created final QName qname = typeDef.getQName(); - final Module unionModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), - qname.getRevision()); + final Module unionModule = schemaContext.findModule(qname.getModule()).get(); final ModuleContext mc = genCtx.get(unionModule); returnType = mc.getTypedefs().get(typeDef.getPath()); } 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(); - final Module enumModule = schemaContext.findModuleByNamespaceAndRevision(qname.getNamespace(), - qname.getRevision()); + final Module enumModule = schemaContext.findModule(qname.getModule()).orElse(null); returnType = genCtx.get(enumModule).getInnerType(originalLeaf.getType().getPath()); } else { returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, genCtx.get(module)); @@ -1233,25 +1264,34 @@ final class GenHelperUtil { private static TypeDefinition getBaseOrDeclaredType(final TypeDefinition typeDef) { final TypeDefinition baseType = typeDef.getBaseType(); - return (baseType != null && baseType.getBaseType() != null) ? baseType : typeDef; + return baseType != null && baseType.getBaseType() != null ? baseType : typeDef; } - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) private static GeneratedTypeBuilder processDataSchemaNode(final Module module, final String basePackageName, - final GeneratedTypeBuilder childOf, final DataSchemaNode node, final SchemaContext schemaContext, - final boolean verboseClassComments, Map genCtx, final Map> genTypeBuilders, final TypeProvider typeProvider, final BindingNamespaceType namespaceType) { + final GeneratedTypeBuilder childOf, final + DataSchemaNode node, final SchemaContext + schemaContext, + final boolean verboseClassComments, final Map genCtx, final Map> genTypeBuilders, final TypeProvider typeProvider, final BindingNamespaceType + namespaceType) { final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(basePackageName, node, childOf, module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType); - genType.addComment(node.getDescription()); annotateDeprecatedIfNecessary(node.getStatus(), genType); - genType.setDescription(createDescription(node, genType.getFullyQualifiedName(), schemaContext, - verboseClassComments, namespaceType)); genType.setModuleName(module.getName()); - genType.setReference(node.getReference()); + if (verboseClassComments) { + YangSourceDefinition.of(module, node).ifPresent(genType::setYangSourceDefinition); + TypeComments.description(node).ifPresent(genType::addComment); + node.getDescription().ifPresent(genType::setDescription); + node.getReference().ifPresent(genType::setReference); + } genType.setSchemaPath((List) node.getPath().getPathFromRoot()); - genType.setParentTypeForBuilder(childOf); + if (BindingNamespaceType.isData(namespaceType)) { + genType.setParentTypeForBuilder(childOf); + } + if (node instanceof DataNodeContainer) { genCtx.get(module).addChildNodeType(node, genType); } @@ -1265,25 +1305,18 @@ final class GenHelperUtil { * saved at first positions. For every grouping the record is added to map * {@link ModuleContext#groupings allGroupings} * - * @param module - * current module - * @param groupings - * collection of groupings from which types will be generated - * @param typeProvider - * provider that defines contract for generated types - * @param schemaContext - * schema context - * @param genCtx - * map of generated entities in context of YANG modules - * @param genTypeBuilders - * map of generated type builders - * @param verboseClassComments - * generate verbose comments - * + * @param module current module + * @param groupings collection of groupings from which types will be generated + * @param typeProvider provider that defines contract for generated types + * @param schemaContext schema context + * @param genCtx map of generated entities in context of YANG modules + * @param genTypeBuilders map of generated type builders + * @param verboseClassComments generate verbose comments */ static Map groupingsToGenTypes(final Module module, final Collection groupings, Map genCtx, final SchemaContext schemaContext, final boolean - verboseClassComments, Map> genTypeBuilders, final TypeProvider typeProvider) { + verboseClassComments, final Map> genTypeBuilders, final TypeProvider typeProvider) { final String basePackageName = BindingMapping.getRootPackageName(module); final List groupingsSortedByDependencies = new GroupingDefinitionDependencySort() .sort(groupings); @@ -1299,30 +1332,23 @@ final class GenHelperUtil { * builder is created and every child node of grouping is resolved to the * method. * - * @param basePackageName - * string contains the module package name - * @param grouping - * GroupingDefinition which contains data about grouping - * @param module - * current module - * @param typeProvider - * provider that defines contract for generated types - * @param schemaContext - * schema context - * @param genCtx - * map of generated entities in context of YANG modules - * @param genTypeBuilders - * map of generated type builders - * @param verboseClassComments - * generate verbose comments - * + * @param basePackageName string contains the module package name + * @param grouping GroupingDefinition which contains data about grouping + * @param module current module + * @param typeProvider provider that defines contract for generated types + * @param schemaContext schema context + * @param genCtx map of generated entities in context of YANG modules + * @param genTypeBuilders map of generated type builders + * @param verboseClassComments generate verbose comments * @return GeneratedType which is generated from grouping (object of type - * GroupingDefinition) + * GroupingDefinition) */ - private static Map groupingToGenType(final String basePackageName, final GroupingDefinition grouping, final Module - module, Map genCtx, final SchemaContext schemaContext, final boolean - verboseClassComments, Map> genTypeBuilders, final TypeProvider typeProvider) { - final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(basePackageName, grouping, module, genCtx, + private static Map groupingToGenType(final String basePackageName, + final GroupingDefinition grouping, final Module module, Map genCtx, + final SchemaContext schemaContext, final boolean verboseClassComments, + final Map> genTypeBuilders, final TypeProvider typeProvider) { + final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(basePackageName, grouping, null, module, + genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, BindingNamespaceType.Grouping); annotateDeprecatedIfNecessary(grouping.getStatus(), genType); genCtx.get(module).addGroupingType(grouping, genType); @@ -1341,64 +1367,66 @@ final class GenHelperUtil { * class {@link org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode * BaseIdentity} is added * - * @param module - * current module - * @param basePackageName - * string contains the module package name - * @param identity - * IdentitySchemaNode which contains data about identity - * @param schemaContext - * SchemaContext which is used to get package and name - * information about base of identity - * @param genCtx generated context + * @param module current module + * @param basePackageName string contains the module package name + * @param identity IdentitySchemaNode which contains data about identity + * @param schemaContext SchemaContext which is used to get package and name + * information about base of identity + * @param genCtx generated context * @return returns generated context */ static Map identityToGenType(final Module module, final String basePackageName, - final IdentitySchemaNode identity, final SchemaContext schemaContext, Map genCtx, - boolean verboseClassComments) { + final IdentitySchemaNode identity, final SchemaContext + schemaContext, final Map genCtx, + final boolean verboseClassComments) { resolveIdentitySchemaNode(basePackageName, schemaContext, identity, module, verboseClassComments, genCtx); return genCtx; } - private static GeneratedTOBuilder resolveIdentitySchemaNode(final String basePackageName, final SchemaContext schemaContext, - final IdentitySchemaNode identity, final Module module, final boolean verboseClassComments, - final Map genCtx) { - Preconditions.checkNotNull(identity,"Identity can not be null!"); + private static GeneratedTypeBuilder resolveIdentitySchemaNode(final String basePackageName, final SchemaContext + schemaContext, + final IdentitySchemaNode identity, final Module + module, final boolean verboseClassComments, + final Map genCtx) { + requireNonNull(identity, "Identity can not be null!"); //check first if identity has been resolved as base identity of some other one - GeneratedTOBuilder newType = findIdentityByQname(identity.getQName(), genCtx); + GeneratedTypeBuilder newType = findIdentityByQname(identity.getQName(), genCtx); if (newType == null) { final Module parentModule = SchemaContextUtil.findParentModule(schemaContext, identity); Preconditions.checkState(module.equals(parentModule), "If the type is null ,it must be in the same module, otherwise it must has been" + "resolved by an imported module."); - final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity.getPath(), + final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity + .getPath(), BindingNamespaceType.Identity); - newType = new GeneratedTOBuilderImpl(packageName, identity.getQName().getLocalName(), true, false, + newType = new GeneratedTypeBuilderImpl(packageName, identity.getQName().getLocalName(), true, false, genCtx.get(module)); final Set baseIdentities = identity.getBaseIdentities(); if (baseIdentities.size() == 0) { //no base - abstract - final GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(BaseIdentity.class.getPackage().getName(), + final GeneratedTypeBuilderImpl genType = new GeneratedTypeBuilderImpl(BaseIdentity.class.getPackage() + .getName(), BaseIdentity.class.getSimpleName(), genCtx.get(module)); - newType.setExtendsType(gto.toInstance()); + newType.addImplementsType(genType.toInstance()); } else { - //one base - inheritance - final IdentitySchemaNode baseIdentity = baseIdentities.iterator().next(); - GeneratedTOBuilder baseType = resolveIdentitySchemaNode(basePackageName, schemaContext, - baseIdentity, module, verboseClassComments, genCtx); - newType.setExtendsType(baseType.toInstance()); + //multiple bases - inheritance + for (IdentitySchemaNode baseIdentity : baseIdentities) { + GeneratedTypeBuilder baseType = resolveIdentitySchemaNode(basePackageName, schemaContext, + baseIdentity, module, verboseClassComments, genCtx); + newType.addImplementsType(baseType.toInstance()); + } } - newType.setAbstract(true); - newType.addComment(identity.getDescription()); - newType.setDescription(createDescription(identity, newType.getFullyQualifiedName(), schemaContext, - verboseClassComments, BindingNamespaceType.Identity)); - newType.setReference(identity.getReference()); - newType.setModuleName(module.getName()); + if (verboseClassComments) { + YangSourceDefinition.of(module).ifPresent(newType::setYangSourceDefinition); + TypeComments.description(module).ifPresent(newType::addComment); + module.getDescription().ifPresent(newType::setDescription); + module.getReference().ifPresent(newType::setReference); + } newType.setSchemaPath((List) identity.getPath().getPathFromRoot()); qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, identity.getQName());