Disambiguate generated nested enumerations
[mdsal.git] / binding / mdsal-binding-generator-util / src / main / java / org / opendaylight / mdsal / binding / model / util / generated / type / builder / AbstractGeneratedTypeBuilder.java
1 /*
2  * Copyright (c) 2013 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.binding.model.util.generated.type.builder;
9
10 import com.google.common.base.Preconditions;
11 import java.util.Collections;
12 import java.util.List;
13 import java.util.Objects;
14 import java.util.Optional;
15 import org.opendaylight.mdsal.binding.model.api.AccessModifier;
16 import org.opendaylight.mdsal.binding.model.api.Constant;
17 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
18 import org.opendaylight.mdsal.binding.model.api.Type;
19 import org.opendaylight.mdsal.binding.model.api.TypeComment;
20 import org.opendaylight.mdsal.binding.model.api.YangSourceDefinition;
21 import org.opendaylight.mdsal.binding.model.api.type.builder.AnnotationTypeBuilder;
22 import org.opendaylight.mdsal.binding.model.api.type.builder.EnumBuilder;
23 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedPropertyBuilder;
24 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder;
25 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder;
26 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase;
27 import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuilder;
28 import org.opendaylight.mdsal.binding.model.util.AbstractBaseType;
29 import org.opendaylight.yangtools.util.LazyCollections;
30
31 abstract class AbstractGeneratedTypeBuilder<T extends GeneratedTypeBuilderBase<T>> extends AbstractBaseType
32         implements GeneratedTypeBuilderBase<T> {
33
34     private List<AnnotationTypeBuilder> annotationBuilders = Collections.emptyList();
35     private List<Type> implementsTypes = Collections.emptyList();
36     private List<EnumBuilder> enumDefinitions = Collections.emptyList();
37     private List<Constant> constants = Collections.emptyList();
38     private List<MethodSignatureBuilder> methodDefinitions = Collections.emptyList();
39     private final List<GeneratedTypeBuilder> enclosedTypes = Collections.emptyList();
40     private List<GeneratedTOBuilder> enclosedTransferObjects = Collections.emptyList();
41     private List<GeneratedPropertyBuilder> properties = Collections.emptyList();
42     private TypeComment comment;
43     private boolean isAbstract;
44     private YangSourceDefinition yangSourceDefinition;
45
46     protected AbstractGeneratedTypeBuilder(final JavaTypeName identifier) {
47         super(identifier);
48     }
49
50     protected TypeComment getComment() {
51         return this.comment;
52     }
53
54     protected List<AnnotationTypeBuilder> getAnnotations() {
55         return this.annotationBuilders;
56     }
57
58     @Override
59     public boolean isAbstract() {
60         return this.isAbstract;
61     }
62
63     @Override
64     public List<Type> getImplementsTypes() {
65         return this.implementsTypes;
66     }
67
68     protected List<EnumBuilder> getEnumerations() {
69         return this.enumDefinitions;
70     }
71
72     protected List<Constant> getConstants() {
73         return this.constants;
74     }
75
76     @Override
77     public List<MethodSignatureBuilder> getMethodDefinitions() {
78         return this.methodDefinitions;
79     }
80
81     protected List<GeneratedTypeBuilder> getEnclosedTypes() {
82         return this.enclosedTypes;
83     }
84
85     protected List<GeneratedTOBuilder> getEnclosedTransferObjects() {
86         return this.enclosedTransferObjects;
87     }
88
89     protected abstract T thisInstance();
90
91     abstract AbstractEnumerationBuilder newEnumerationBuilder(JavaTypeName identifier);
92
93     @Override
94     public GeneratedTOBuilder addEnclosingTransferObject(final String name) {
95         Preconditions.checkArgument(name != null, "Name for Enclosing Generated Transfer Object cannot be null!");
96         final GeneratedTOBuilder builder = new CodegenGeneratedTOBuilder(getIdentifier().createEnclosed(name));
97
98         Preconditions.checkArgument(!this.enclosedTransferObjects.contains(builder),
99             "This generated type already contains equal enclosing transfer object.");
100         this.enclosedTransferObjects = LazyCollections.lazyAdd(this.enclosedTransferObjects, builder);
101         return builder;
102     }
103
104     @Override
105     public T addEnclosingTransferObject(final GeneratedTOBuilder genTOBuilder) {
106         Preconditions.checkArgument(genTOBuilder != null, "Parameter genTOBuilder cannot be null!");
107         Preconditions.checkArgument(!this.enclosedTransferObjects.contains(genTOBuilder),
108             "This generated type already contains equal enclosing transfer object.");
109         this.enclosedTransferObjects = LazyCollections.lazyAdd(this.enclosedTransferObjects, genTOBuilder);
110         return thisInstance();
111     }
112
113     @Override
114     public T addComment(final TypeComment comment) {
115         this.comment = Preconditions.checkNotNull(comment);
116         return thisInstance();
117     }
118
119     @Override
120     public AnnotationTypeBuilder addAnnotation(final JavaTypeName identifier) {
121         final AnnotationTypeBuilder builder = new AnnotationTypeBuilderImpl(identifier);
122
123         Preconditions.checkArgument(!this.annotationBuilders.contains(builder),
124             "This generated type already contains equal annotation.");
125         this.annotationBuilders = LazyCollections.lazyAdd(this.annotationBuilders, builder);
126         return builder;
127     }
128
129     @Override
130     public T setAbstract(final boolean isAbstract) {
131         this.isAbstract = isAbstract;
132         return thisInstance();
133     }
134
135     @Override
136     public T addImplementsType(final Type genType) {
137         Preconditions.checkArgument(genType != null, "Type cannot be null");
138         Preconditions.checkArgument(!this.implementsTypes.contains(genType),
139             "This generated type already contains equal implements type.");
140         this.implementsTypes = LazyCollections.lazyAdd(this.implementsTypes, genType);
141         return thisInstance();
142     }
143
144     @Override
145     public Constant addConstant(final Type type, final String name, final Object value) {
146         Preconditions.checkArgument(type != null, "Returning Type for Constant cannot be null!");
147         Preconditions.checkArgument(name != null, "Name of constant cannot be null!");
148         Preconditions.checkArgument(!containsConstant(name),
149             "This generated type already contains constant with the same name.");
150
151         final Constant constant = new ConstantImpl(this, type, name, value);
152         this.constants = LazyCollections.lazyAdd(this.constants, constant);
153         return constant;
154     }
155
156     public boolean containsConstant(final String name) {
157         Preconditions.checkArgument(name != null, "Parameter name can't be null");
158         for (final Constant constant : this.constants) {
159             if (name.equals(constant.getName())) {
160                 return true;
161             }
162         }
163         return false;
164     }
165
166     @Override
167     public EnumBuilder addEnumeration(String name) {
168         Preconditions.checkArgument(name != null, "Name of enumeration cannot be null!");
169
170         // This enumeration may be generated from a leaf, which may end up colliding with its enclosing type
171         // hierarchy. Check it and assign another name if that should be the case.
172         final boolean canCreate = getIdentifier().canCreateEnclosed(name);
173         if (!canCreate) {
174             // Append a single '$' -- it cannot come from the user, hence it marks our namespace.
175             name = name + '$';
176         }
177
178         final EnumBuilder builder = newEnumerationBuilder(getIdentifier().createEnclosed(name));
179         Preconditions.checkArgument(!this.enumDefinitions.contains(builder),
180             "Generated type %s already contains an enumeration for %s", this, builder);
181         this.enumDefinitions = LazyCollections.lazyAdd(this.enumDefinitions, builder);
182         return builder;
183     }
184
185     @Override
186     public MethodSignatureBuilder addMethod(final String name) {
187         Preconditions.checkArgument(name != null, "Name of method cannot be null!");
188         final MethodSignatureBuilder builder = new MethodSignatureBuilderImpl(name);
189         builder.setAccessModifier(AccessModifier.PUBLIC);
190         builder.setAbstract(true);
191         this.methodDefinitions = LazyCollections.lazyAdd(this.methodDefinitions, builder);
192         return builder;
193     }
194
195     @Override
196     public boolean containsMethod(final String name) {
197         Preconditions.checkArgument(name != null, "Parameter name can't be null");
198         for (final MethodSignatureBuilder methodDefinition : this.methodDefinitions) {
199             if (name.equals(methodDefinition.getName())) {
200                 return true;
201             }
202         }
203         return false;
204     }
205
206     @Override
207     public GeneratedPropertyBuilder addProperty(final String name) {
208         Preconditions.checkArgument(name != null, "Parameter name can't be null");
209         Preconditions.checkArgument(!containsProperty(name),
210             "This generated type already contains property with the same name.");
211
212         final GeneratedPropertyBuilder builder = new GeneratedPropertyBuilderImpl(name);
213         builder.setAccessModifier(AccessModifier.PUBLIC);
214         this.properties = LazyCollections.lazyAdd(this.properties, builder);
215         return builder;
216     }
217
218     @Override
219     public boolean containsProperty(final String name) {
220         Preconditions.checkArgument(name != null, "Parameter name can't be null");
221         for (final GeneratedPropertyBuilder property : this.properties) {
222             if (name.equals(property.getName())) {
223                 return true;
224             }
225         }
226         return false;
227     }
228
229     public Type getParent() {
230         return null;
231     }
232
233     @Override
234     public List<GeneratedPropertyBuilder> getProperties() {
235         return this.properties;
236     }
237
238     @Override
239     public Optional<YangSourceDefinition> getYangSourceDefinition() {
240         return Optional.ofNullable(yangSourceDefinition);
241     }
242
243
244     @Override
245     public void setYangSourceDefinition(final YangSourceDefinition definition) {
246         yangSourceDefinition = Preconditions.checkNotNull(definition);
247     }
248
249     @Override
250     public int hashCode() {
251         final int prime = 31;
252         int result = 1;
253         result = prime * result + Objects.hashCode(getName());
254         result = prime * result + Objects.hashCode(getPackageName());
255         return result;
256     }
257
258     @Override
259     public boolean equals(final Object obj) {
260         if (this == obj) {
261             return true;
262         }
263         if (obj == null) {
264             return false;
265         }
266         if (getClass() != obj.getClass()) {
267             return false;
268         }
269         final AbstractGeneratedTypeBuilder<?> other = (AbstractGeneratedTypeBuilder<?>) obj;
270         return getIdentifier().equals(other.getIdentifier());
271     }
272 }