2 * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.mdsal.binding.javav2.generator.impl;
11 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.addTOToTypeBuilder;
12 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.annotateDeprecatedIfNecessary;
13 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.augGenTypeName;
14 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.constructGetter;
15 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createDescription;
16 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createReturnTypeForUnion;
17 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.getAugmentIdentifier;
18 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.isInnerType;
19 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.qNameConstant;
20 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveInnerEnumFromTypeDefinition;
21 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
22 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
24 import com.google.common.annotations.Beta;
25 import com.google.common.base.Preconditions;
26 import java.util.HashMap;
27 import java.util.List;
29 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
30 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
31 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes;
32 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
33 import org.opendaylight.mdsal.binding.javav2.generator.util.NonJavaCharsConverter;
34 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
35 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
36 import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
37 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType;
38 import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
39 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
40 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
41 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
42 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
43 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
44 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
45 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
46 import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentable;
47 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
48 import org.opendaylight.yangtools.yang.common.QName;
49 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
50 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
51 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
52 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
53 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
54 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
55 import org.opendaylight.yangtools.yang.model.api.Module;
56 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
57 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
58 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
59 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
60 import org.opendaylight.yangtools.yang.model.api.UsesNode;
61 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
62 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
63 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
64 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
67 * Helper util class used for generation of types in Binding spec v2.
70 final class GenHelperUtil {
72 private GenHelperUtil() {
73 throw new UnsupportedOperationException("Util class");
77 * Create GeneratedTypeBuilder object from module argument.
80 * Module object from which builder will be created
82 * @param verboseClassComments
84 * @return <code>GeneratedTypeBuilder</code> which is internal
85 * representation of the module
86 * @throws IllegalArgumentException
89 static GeneratedTypeBuilder moduleToDataType(final Module module, final Map<Module, ModuleContext> genCtx, final boolean verboseClassComments) {
90 Preconditions.checkArgument(module != null, "Module reference cannot be NULL.");
92 final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data", verboseClassComments);
93 addImplementedInterfaceFromUses(module, moduleDataTypeBuilder, genCtx);
94 moduleDataTypeBuilder.addImplementsType(BindingTypes.TREE_ROOT);
95 moduleDataTypeBuilder.addComment(module.getDescription());
96 moduleDataTypeBuilder.setDescription(createDescription(module, verboseClassComments));
97 moduleDataTypeBuilder.setReference(module.getReference());
98 return moduleDataTypeBuilder;
102 * Generates type builder for <code>module</code>.
105 * Module which is source of package name for generated type
108 * string which is added to the module class name representation
110 * @param verboseClassComments
111 * @return instance of GeneratedTypeBuilder which represents
112 * <code>module</code>.
113 * @throws IllegalArgumentException
114 * if <code>module</code> is null
116 private static GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix, final boolean
117 verboseClassComments) {
118 Preconditions.checkArgument(module != null, "Module reference cannot be NULL.");
119 final String packageName = BindingMapping.getRootPackageName(module);
120 final String moduleName = BindingMapping.getClassName(NonJavaCharsConverter.convertIdentifier(module.getName
121 (), JavaIdentifier.CLASS)) + postfix;
123 final GeneratedTypeBuilderImpl moduleBuilder = new GeneratedTypeBuilderImpl(packageName, moduleName);
124 moduleBuilder.setDescription(createDescription(module, verboseClassComments));
125 moduleBuilder.setReference(module.getReference());
126 moduleBuilder.setModuleName(moduleName);
128 return moduleBuilder;
132 * Adds the implemented types to type builder.
134 * The method passes through the list of <i>uses</i> in
135 * {@code dataNodeContainer}. For every <i>use</i> is obtained corresponding
136 * generated type from all groupings
137 * allGroupings} which is added as <i>implements type</i> to
138 * <code>builder</code>
140 * @param dataNodeContainer
141 * element which contains the list of used YANG groupings
143 * builder to which are added implemented types according to
144 * <code>dataNodeContainer</code>
145 * @param genCtx generated context
146 * @return generated type builder with all implemented types
148 private static GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer,
149 final GeneratedTypeBuilder builder, final Map<Module, ModuleContext> genCtx) {
150 for (final UsesNode usesNode : dataNodeContainer.getUses()) {
151 final GeneratedType genType = findGroupingByPath(usesNode.getGroupingPath(), genCtx).toInstance();
152 if (genType == null) {
153 throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for "
154 + builder.getName());
156 builder.addImplementsType(genType);
161 static GeneratedTypeBuilder findGroupingByPath(final SchemaPath path, final Map<Module, ModuleContext> genCtx) {
162 for (final ModuleContext ctx : genCtx.values()) {
163 final GeneratedTypeBuilder result = ctx.getGrouping(path);
164 if (result != null) {
172 * Adds the methods to <code>typeBuilder</code> which represent subnodes of
173 * node for which <code>typeBuilder</code> was created.
175 * The subnodes aren't mapped to the methods if they are part of grouping or
176 * augment (in this case are already part of them).
180 * @param basePackageName
181 * string contains the module package name
183 * generated type builder which represents any node. The subnodes
184 * of this node are added to the <code>typeBuilder</code> as
185 * methods. The subnode can be of type leaf, leaf-list, list,
190 * set of data schema nodes which are the children of the node
191 * for which <code>typeBuilder</code> was created
192 * @return generated type builder which is the same builder as input
193 * parameter. The getter methods (representing child nodes) could be
196 static GeneratedTypeBuilder resolveDataSchemaNodes(final Module module, final String basePackageName,
197 final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf,
198 final Iterable<DataSchemaNode> schemaNodes, final Map<Module, ModuleContext> genCtx,
199 final SchemaContext schemaContext, final boolean verboseClassComments,
200 final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
201 final TypeProvider typeProvider) {
203 if (schemaNodes != null && parent != null) {
204 for (final DataSchemaNode schemaNode : schemaNodes) {
205 if (!schemaNode.isAugmenting() && !schemaNode.isAddedByUses()) {
206 addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, parent, childOf, module, genCtx,
207 schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
214 static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode
215 schemaNode, final Module module, final Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext,
216 final boolean verboseClassComments, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
217 return addDefaultInterfaceDefinition(packageName, schemaNode, null, module, genCtx, schemaContext,
218 verboseClassComments, genTypeBuilders);
221 static Map<Module, ModuleContext> processUsesAugments(final SchemaContext schemaContext, final
222 DataNodeContainer node, final Module module, Map<Module, ModuleContext> genCtx,
223 final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
224 final boolean verboseClassComments, final TypeProvider typeProvider) {
225 final String basePackageName = BindingMapping.getRootPackageName(module);
226 for (final UsesNode usesNode : node.getUses()) {
227 for (final AugmentationSchema augment : usesNode.getAugmentations()) {
228 genCtx = AugmentToGenType.usesAugmentationToGenTypes(schemaContext, basePackageName, augment, module,
229 usesNode, node, genCtx, genTypeBuilders, verboseClassComments, typeProvider);
230 genCtx = processUsesAugments(schemaContext, augment, module, genCtx, genTypeBuilders,
231 verboseClassComments, typeProvider);
237 static GeneratedTypeBuilder findChildNodeByPath(final SchemaPath path, final Map<Module, ModuleContext> genCtx) {
238 for (final ModuleContext ctx : genCtx.values()) {
239 final GeneratedTypeBuilder result = ctx.getChildNode(path);
240 if (result != null) {
247 static GeneratedTypeBuilder findCaseByPath(final SchemaPath path, final Map<Module, ModuleContext> genCtx) {
248 for (final ModuleContext ctx : genCtx.values()) {
249 final GeneratedTypeBuilder result = ctx.getCase(path);
250 if (result != null) {
258 * Returns a generated type builder for an augmentation.
260 * The name of the type builder is equal to the name of augmented node with
261 * serial number as suffix.
265 * @param augmentPackageName
266 * string with contains the package name to which the augment
268 * @param basePackageName
269 * string with the package name to which the augmented node
271 * @param targetTypeRef
274 * augmentation schema which contains data about the child nodes
275 * and uses of augment
276 * @return generated type builder for augment in genCtx
278 static Map<Module, ModuleContext> addRawAugmentGenTypeDefinition(final Module module, final String augmentPackageName,
279 final String basePackageName, final Type targetTypeRef, final AugmentationSchema augSchema,
280 final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final Map<Module, ModuleContext> genCtx) {
282 Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
283 if (augmentBuilders == null) {
284 augmentBuilders = new HashMap<>();
285 genTypeBuilders.put(augmentPackageName, augmentBuilders);
287 final String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes());
290 if (augIdentifier != null) {
291 augTypeName = BindingMapping.getClassName(augIdentifier);
293 augTypeName = augGenTypeName(augmentBuilders, targetTypeRef.getName());
296 GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);
298 augTypeBuilder.addImplementsType(BindingTypes.TREE_NODE);
299 augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));
300 annotateDeprecatedIfNecessary(augSchema.getStatus(), augTypeBuilder);
301 augTypeBuilder = addImplementedInterfaceFromUses(augSchema, augTypeBuilder, genCtx);
303 augTypeBuilder = augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema
305 augmentBuilders.put(augTypeName, augTypeBuilder);
307 if(!augSchema.getChildNodes().isEmpty()) {
308 genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
311 genCtx.get(module).addAugmentType(augTypeBuilder);
316 * Adds the methods to <code>typeBuilder</code> what represents subnodes of
317 * node for which <code>typeBuilder</code> was created.
321 * @param basePackageName
322 * string contains the module package name
324 * generated type builder which represents any node. The subnodes
325 * of this node are added to the <code>typeBuilder</code> as
326 * methods. The subnode can be of type leaf, leaf-list, list,
331 * set of data schema nodes which are the children of the node
332 * for which <code>typeBuilder</code> was created
333 * @return generated type builder which is the same object as the input
334 * parameter <code>typeBuilder</code>. The getter method could be
337 private static GeneratedTypeBuilder augSchemaNodeToMethods(final Module module, final String basePackageName,
338 final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf,
339 final Iterable<DataSchemaNode> schemaNodes) {
340 if (schemaNodes != null && typeBuilder != null) {
341 for (final DataSchemaNode schemaNode : schemaNodes) {
342 if (!schemaNode.isAugmenting()) {
343 //TODO: design decomposition and implement it
344 //addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module);
352 * Instantiates generated type builder with <code>packageName</code> and
353 * <code>schemaNode</code>.
355 * The new builder always implements
356 * {@link TreeNode TreeNode}.<br>
357 * If <code>schemaNode</code> is instance of GroupingDefinition it also
358 * implements {@link Augmentable
360 * If <code>schemaNode</code> is instance of
361 * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer
362 * DataNodeContainer} it can also implement nodes which are specified in
366 * string with the name of the package to which
367 * <code>schemaNode</code> belongs.
369 * schema node for which is created generated type builder
371 * parent type (can be null)
372 * @param schemaContext schema context
373 * @return generated type builder <code>schemaNode</code>
375 private static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode
376 schemaNode, final Type parent, final Module module, final Map<Module, ModuleContext> genCtx,
377 final SchemaContext schemaContext, final boolean verboseClassComments, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
379 GeneratedTypeBuilder it = addRawInterfaceDefinition(packageName, schemaNode, schemaContext, "",
380 verboseClassComments, genTypeBuilders);
381 if (parent == null) {
382 it.addImplementsType(BindingTypes.TREE_NODE);
384 it.addImplementsType(BindingTypes.treeChildNode(parent));
386 if (!(schemaNode instanceof GroupingDefinition)) {
387 it.addImplementsType(BindingTypes.augmentable(it));
390 if (schemaNode instanceof DataNodeContainer) {
391 //TODO: design decomposition and implement it
392 //groupingsToGenTypes(module, ((DataNodeContainer) schemaNode).getGroupings());
393 it = addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, it, genCtx);
400 * Returns reference to generated type builder for specified
401 * <code>schemaNode</code> with <code>packageName</code>.
403 * Firstly the generated type builder is searched in
404 * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't
405 * found it is created and added to <code>genTypeBuilders</code>.
408 * string with the package name to which returning generated type
411 * schema node which provide data about the schema node name
412 * @param schemaContext
414 * return type name prefix
415 * @return generated type builder for <code>schemaNode</code>
416 * @throws IllegalArgumentException
418 * <li>if <code>schemaNode</code> is null</li>
419 * <li>if <code>packageName</code> is null</li>
420 * <li>if QName of schema node is null</li>
421 * <li>if schemaNode name is null</li>
425 private static GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode,
426 final SchemaContext schemaContext, final String prefix, final boolean verboseClassComments,
427 final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
429 Preconditions.checkArgument(schemaNode != null, "Data Schema Node cannot be NULL.");
430 Preconditions.checkArgument(packageName != null, "Package Name for Generated Type cannot be NULL.");
431 final String schemaNodeName = schemaNode.getQName().getLocalName();
432 Preconditions.checkArgument(schemaNodeName != null, "Local Name of QName for Data Schema Node cannot be NULL.");
435 if (prefix == null) {
436 genTypeName = BindingMapping
437 .getClassName(NonJavaCharsConverter.normalizeClassIdentifier(packageName, schemaNodeName));
439 genTypeName = prefix + BindingMapping
440 .getClassName(NonJavaCharsConverter.normalizeClassIdentifier(packageName, schemaNodeName));
443 final GeneratedTypeBuilderImpl newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
444 final Module module = SchemaContextUtil.findParentModule(schemaContext, schemaNode);
445 qNameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, schemaNode.getQName());
446 newType.addComment(schemaNode.getDescription());
447 newType.setDescription(createDescription(schemaNode, newType.getFullyQualifiedName(), schemaContext, verboseClassComments));
448 newType.setReference(schemaNode.getReference());
449 newType.setSchemaPath((List<QName>) schemaNode.getPath().getPathFromRoot());
450 newType.setModuleName(module.getName());
452 if (!genTypeBuilders.containsKey(packageName)) {
453 final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();
454 builders.put(genTypeName, newType);
455 genTypeBuilders.put(packageName, builders);
457 final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
458 if (!builders.containsKey(genTypeName)) {
459 builders.put(genTypeName, newType);
466 private static void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode node,
467 final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Module module,
468 final Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext, final boolean verboseClassComments,
469 final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
470 //TODO: implement rest of schema nodes GTO building
471 if (node != null && typeBuilder != null) {
472 if (node instanceof ContainerSchemaNode) {
473 containerToGenType(module, basePackageName, typeBuilder, childOf, (ContainerSchemaNode) node,
474 schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider);
475 } else if (node instanceof LeafSchemaNode) {
476 resolveLeafSchemaNodeAsMethod(schemaContext, typeBuilder, genCtx, (LeafSchemaNode) node, module,
483 private static void containerToGenType(final Module module, final String basePackageName,
484 final GeneratedTypeBuilder parent, final GeneratedTypeBuilder childOf, final ContainerSchemaNode node,
485 final SchemaContext schemaContext, final boolean verboseClassComments, final Map<Module, ModuleContext> genCtx,
486 final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
488 final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node,
489 schemaContext, verboseClassComments, genCtx, genTypeBuilders, typeProvider);
490 if (genType != null) {
491 constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), genType, node.getStatus());
492 resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes(), genCtx,
493 schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
498 * Converts <code>leaf</code> to the getter method which is added to
499 * <code>typeBuilder</code>.
502 * generated type builder to which is added getter method as
503 * <code>leaf</code> mapping
505 * leaf schema node which is mapped as getter method which is
506 * added to <code>typeBuilder</code>
508 * Module in which type was defined
509 * @return boolean value
511 * <li>false - if <code>leaf</code> or <code>typeBuilder</code> are
513 * <li>true - in other cases</li>
516 private static Type resolveLeafSchemaNodeAsMethod(final SchemaContext schemaContext, final GeneratedTypeBuilder
517 typeBuilder, final Map<Module, ModuleContext> genCtx, final LeafSchemaNode leaf, final Module module,
518 final TypeProvider typeProvider) {
519 if (leaf == null || typeBuilder == null || leaf.isAddedByUses()) {
523 final String leafName = leaf.getQName().getLocalName();
524 if (leafName == null) {
528 final Module parentModule = findParentModule(schemaContext, leaf);
529 Type returnType = null;
531 final TypeDefinition<?> typeDef = leaf.getType();
532 if (isInnerType(leaf, typeDef)) {
533 if (typeDef instanceof EnumTypeDefinition) {
534 returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
535 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef;
536 final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.getQName(),
537 genCtx, typeBuilder, module);
538 if (enumBuilder != null) {
539 returnType = enumBuilder.toInstance(typeBuilder);
541 ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
542 } else if (typeDef instanceof UnionTypeDefinition) {
543 GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule,
544 typeProvider, schemaContext);
545 if (genTOBuilder != null) {
546 //TODO: https://bugs.opendaylight.org/show_bug.cgi?id=2289
547 returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider);
549 } else if (typeDef instanceof BitsTypeDefinition) {
550 GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule,
551 typeProvider, schemaContext);
552 if (genTOBuilder != null) {
553 returnType = genTOBuilder.toInstance();
556 // It is constrained version of already declared type (inner declared type exists,
557 // onlyfor special cases (Enum, Union, Bits), which were already checked.
558 // In order to get proper class we need to look up closest derived type
559 // and apply restrictions from leaf type
560 final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
561 returnType = typeProvider.javaTypeForSchemaDefinitionType(getBaseOrDeclaredType(typeDef), leaf,
565 final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
566 returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions);
569 if (returnType == null) {
573 if (typeDef instanceof EnumTypeDefinition) {
574 ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
577 String leafDesc = leaf.getDescription();
578 if (leafDesc == null) {
582 final MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType, leaf.getStatus());
584 //FIXME: deal with context-ref
588 private static TypeDefinition<?> getBaseOrDeclaredType(final TypeDefinition<?> typeDef) {
589 final TypeDefinition<?> baseType = typeDef.getBaseType();
590 return (baseType != null && baseType.getBaseType() != null) ? baseType : typeDef;
593 private static GeneratedTypeBuilder processDataSchemaNode(final Module module, final String basePackageName,
594 final GeneratedTypeBuilder childOf, final DataSchemaNode node, final SchemaContext schemaContext,
595 final boolean verboseClassComments, final Map<Module, ModuleContext> genCtx, final Map<String, Map<String,
596 GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
598 if (node.isAugmenting() || node.isAddedByUses()) {
601 final String packageName = packageNameForGeneratedType(basePackageName, node.getPath(), BindingNamespaceType.Data);
602 final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, node, childOf, module,
603 genCtx, schemaContext, verboseClassComments, genTypeBuilders);
604 genType.addComment(node.getDescription());
605 annotateDeprecatedIfNecessary(node.getStatus(), genType);
606 genType.setDescription(createDescription(node, genType.getFullyQualifiedName(), schemaContext, verboseClassComments));
607 genType.setModuleName(module.getName());
608 genType.setReference(node.getReference());
609 genType.setSchemaPath((List) node.getPath().getPathFromRoot());
610 if (node instanceof DataNodeContainer) {
611 genCtx.get(module).addChildNodeType(node, genType);
612 //TODO: implement groupings to GTO building first
613 // groupingsToGenTypes(module, ((DataNodeContainer) node).getGroupings());
614 processUsesAugments(schemaContext, (DataNodeContainer) node, module, genCtx, genTypeBuilders,
615 verboseClassComments, typeProvider);