8e8779d75d9d335b19aa1dd7b3f68360d118ee45
[mdsal.git] / binding2 / mdsal-binding2-generator-impl / src / main / java / org / opendaylight / mdsal / binding2 / generator / impl / BindingGeneratorImpl.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.mdsal.binding2.generator.impl;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.Preconditions;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17 import org.opendaylight.mdsal.binding.javav2.generator.api.BindingGenerator;
18 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
19 import org.opendaylight.mdsal.binding2.generator.yang.types.TypeProviderImpl;
20 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
21 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
22 import org.opendaylight.yangtools.yang.model.api.Module;
23 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
24 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
25
26 /**
27  * Main class for Binding generator v2. Provides transformation of Schema Context to
28  * generated transfer objects. Process is accompanied with Twirl templates to generate
29  * particular Javadoc for related YANG elements.
30  */
31 @Beta
32 public class BindingGeneratorImpl implements BindingGenerator {
33
34     /**
35      * When set to true, generated classes will include Javadoc comments
36      * which are useful for users.
37      */
38     private final boolean verboseClassComments;
39
40     /**
41      * Outer key represents the package name. Outer value represents map of all
42      * builders in the same package. Inner key represents the schema node name
43      * (in JAVA class/interface name format). Inner value represents instance of
44      * builder for schema node specified in key part.
45      */
46     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders = new HashMap<>();
47
48     private Map<Module, ModuleContext> genCtx = new HashMap<>();
49
50     /**
51      * Provide methods for converting YANG types to JAVA types.
52      */
53     private TypeProvider typeProvider;
54
55     /**
56      * Holds reference to schema context to resolve data of augmented element
57      * when creating augmentation builder
58      */
59     private SchemaContext schemaContext;
60
61     /**
62      * Creates a new binding generator v2.
63      *
64      * @param verboseClassComments generate verbose comments
65      */
66     public BindingGeneratorImpl(final boolean verboseClassComments) {
67         this.verboseClassComments = verboseClassComments;
68     }
69
70     /**
71      * Resolves generated types from <code>context</code> schema nodes of all modules.
72      *
73      * Generated types are created for modules, groupings, types, containers, lists, choices, augments, rpcs,
74      * notification, identities.
75      *
76      * @param context schema context which contains data about all schema nodes saved in modules
77      * @return list of types (usually <code>GeneratedType</code> <code>GeneratedTransferObject</code>which are generated
78      *         from <code>context</code> data.
79      * @throws IllegalArgumentException if arg <code>context</code> is null
80      * @throws IllegalStateException if <code>context</code> contain no modules
81      */
82     @Override
83     public List<Type> generateTypes(SchemaContext context) {
84         Preconditions.checkArgument(context != null, "Schema Context reference cannot be NULL.");
85         Preconditions.checkState(context.getModules() != null, "Schema Context does not contain defined modules.");
86         schemaContext = context;
87         typeProvider = new TypeProviderImpl(context);
88         final Set<Module> modules = context.getModules();
89         return generateTypes(context, modules);
90     }
91
92     @Override
93     public List<Type> generateTypes(SchemaContext context, Set<Module> modules) {
94         Preconditions.checkArgument(context != null, "Schema Context reference cannot be NULL.");
95         Preconditions.checkState(context.getModules() != null, "Schema Context does not contain defined modules.");
96         Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL.");
97
98         schemaContext = context;
99         typeProvider = new TypeProviderImpl(context);
100         final Module[] modulesArray = new Module[context.getModules().size()];
101         context.getModules().toArray(modulesArray);
102         final List<Module> contextModules = ModuleDependencySort.sort(modulesArray);
103
104         for (final Module contextModule : contextModules) {
105             genCtx = ModuleToGenType.generate(contextModule, context, typeProvider, verboseClassComments);
106         }
107         for (final Module contextModule : contextModules) {
108             genCtx = AugmentToGenType.generate(contextModule, schemaContext, genCtx,
109                     genTypeBuilders, verboseClassComments);
110         }
111
112         final List<Type> filteredGenTypes = new ArrayList<>();
113         for (final Module m : modules) {
114             final ModuleContext ctx = Preconditions.checkNotNull(genCtx.get(m),
115                     "Module context not found for module %s", m);
116             filteredGenTypes.addAll(ctx.getGeneratedTypes());
117             final Set<Type> additionalTypes = ((TypeProviderImpl) typeProvider).getAdditionalTypes().get(m);
118             if (additionalTypes != null) {
119                 filteredGenTypes.addAll(additionalTypes);
120             }
121         }
122
123         return filteredGenTypes;
124     }
125 }