+ /**
+ * Converts <code>node</code> leaf list schema node to getter method of
+ * <code>typeBuilder</code>.
+ *
+ * @param typeBuilder
+ * generated type builder to which is <code>node</code> added as
+ * getter method
+ * @param node
+ * leaf list schema node which is added to
+ * <code>typeBuilder</code> as getter method
+ * @param module module
+ * @param typeProvider type provider instance
+ * @param genCtx actual generated context
+ * @return boolean value
+ * <ul>
+ * <li>true - if <code>node</code>, <code>typeBuilder</code>,
+ * nodeName equal null or <code>node</code> is added by <i>uses</i></li>
+ * <li>false - other cases</li>
+ * </ul>
+ */
+ private static boolean resolveLeafListSchemaNode(final SchemaContext schemaContext, final GeneratedTypeBuilder
+ typeBuilder, final LeafListSchemaNode node, final Module module, final TypeProvider typeProvider,
+ final Map<Module, ModuleContext> genCtx) {
+ if (node == null || typeBuilder == null) {
+ return false;
+ }
+
+ final QName nodeName = node.getQName();
+
+ final TypeDefinition<?> typeDef = node.getType();
+ final Module parentModule = findParentModule(schemaContext, node);
+
+ Type returnType = null;
+ if (typeDef.getBaseType() == null) {
+ if (typeDef instanceof EnumTypeDefinition) {
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, genCtx.get(module));
+ final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef;
+ final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName,
+ genCtx, typeBuilder, 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), genCtx);
+ if (genTOBuilder != null) {
+ returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule, typeProvider);
+ }
+ } else if (typeDef instanceof BitsTypeDefinition) {
+ final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule,
+ 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));
+ }
+ } else {
+ final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions, genCtx.get(module));
+ }
+
+ final ParameterizedType listType = Types.listTypeFor(returnType);
+ constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription(), listType, node.getStatus());
+ return true;
+ }
+
+ /**
+ * Converts <code>caseNodes</code> set to list of corresponding generated
+ * types.
+ *
+ * For every <i>case</i> which isn't added through augment or <i>uses</i> is
+ * created generated type builder. The package names for the builder is
+ * created as concatenation of the module package (
+ * <code>basePackageName</code>) and names of all parents nodes of the
+ * concrete <i>case</i>. There is also relation "<i>implements type</i>"
+ * between every case builder and <i>choice</i> 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 <i>case</i>
+ * @param choiceNode
+ * choice case node which is mapped to generated type
+ * @param verboseClassComments
+ * Javadoc verbosity switch
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>basePackageName</code> equals null</li>
+ * <li>if <code>refChoiceType</code> equals null</li>
+ * <li>if <code>caseNodes</code> equals null</li>
+ * </ul>
+ */
+ private static void generateTypesFromChoiceCases(final Module module, final SchemaContext schemaContext,
+ final Map<Module, ModuleContext> genCtx, final String basePackageName, final Type refChoiceType,
+ final ChoiceSchemaNode choiceNode, final boolean verboseClassComments, final TypeProvider typeProvider,
+ final Map<String, Map<String, GeneratedTypeBuilder>> 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<ChoiceCaseNode> caseNodes = choiceNode.getCases();
+ if (caseNodes == null) {
+ return;
+ }
+
+ for (final ChoiceCaseNode caseNode : caseNodes) {
+ if (caseNode != null && resolveDataSchemaNodesCheck(module, schemaContext, caseNode)) {
+ final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(basePackageName, caseNode,
+ module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
+ caseTypeBuilder.addImplementsType(refChoiceType);
+ caseTypeBuilder.setParentTypeForBuilder(refChoiceType);
+ annotateDeprecatedIfNecessary(caseNode.getStatus(), caseTypeBuilder);
+ genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder);
+ genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder, caseNode);
+ final Iterable<DataSchemaNode> 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 {
+ final GeneratedTypeBuilder moduleType = genCtx.get(module).getModuleNode();
+ Preconditions.checkNotNull(moduleType, "Module type can not be null.");
+ resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, moduleType, caseChildNodes,
+ genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider, namespaceType);
+ }
+ processUsesImplements(caseNode, module, schemaContext, genCtx, namespaceType);
+ }
+ }
+ }
+ }
+
+ private static Type resolveAnyNodeAsMethod(final SchemaContext schemaContext, final GeneratedTypeBuilder
+ typeBuilder, final Map<Module, ModuleContext> genCtx, final DataSchemaNode node, final Module module,