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.yang.types;
11 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
12 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameWithNamespacePrefix;
13 import static org.opendaylight.mdsal.binding.javav2.generator.util.Types.getOuterClassPackageName;
14 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.addStringRegExAsConstant;
15 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.baseTypeDefForExtendedType;
16 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.getAllTypedefs;
17 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.getParentModule;
18 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.makeSerializable;
19 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.provideGeneratedTOFromExtendedType;
20 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.provideTypeForEnum;
21 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.resolveRegExpressionsFromTypedef;
22 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.sortTypeDefinitionAccordingDepth;
23 import static org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeGenHelper.wrapJavaTypeIntoTO;
24 import static org.opendaylight.mdsal.binding.javav2.util.BindingMapping.getRootPackageName;
25 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
26 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
27 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
29 import com.google.common.annotations.Beta;
30 import com.google.common.base.Preconditions;
31 import com.google.common.base.Strings;
32 import com.google.common.collect.Sets;
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.List;
39 import java.util.Objects;
40 import java.util.Optional;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
44 import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext;
45 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
46 import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
47 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
48 import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormalizer;
49 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
50 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
51 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
52 import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier;
53 import org.opendaylight.mdsal.binding.javav2.model.api.Enumeration;
54 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedProperty;
55 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
56 import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
57 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
58 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.EnumBuilder;
59 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedPropertyBuilder;
60 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTOBuilder;
61 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilderBase;
62 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignatureBuilder;
63 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
64 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
65 import org.opendaylight.yangtools.yang.common.QName;
66 import org.opendaylight.yangtools.yang.common.Revision;
67 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
68 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
69 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
70 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
71 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
72 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
73 import org.opendaylight.yangtools.yang.model.api.Module;
74 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
75 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
76 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
77 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
78 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
79 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
80 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
81 import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
82 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
83 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
84 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
85 import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
86 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
87 import org.opendaylight.yangtools.yang.model.util.ModuleDependencySort;
88 import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
89 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
94 public final class TypeProviderImpl implements TypeProvider {
96 private static final Logger LOG = LoggerFactory.getLogger(TypeProviderImpl.class);
97 private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z");
100 * Contains the schema data red from YANG files.
102 private final SchemaContext schemaContext;
105 * Map<moduleName, Map<moduleDate, Map<typeName, type>>>
107 private final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap;
110 * Map which maps schema paths to JAVA <code>Type</code>.
112 private final Map<SchemaPath, Type> referencedTypes;
115 * Map for additional types e.g unions
117 private final Map<Module, Set<Type>> additionalTypes;
120 * Creates new instance of class <code>TypeProviderImpl</code>.
122 * @param schemaContext
123 * contains the schema data red from YANG files
124 * @throws IllegalArgumentException
125 * if <code>schemaContext</code> equal null.
127 public TypeProviderImpl(final SchemaContext schemaContext) {
128 this.schemaContext = schemaContext;
129 this.genTypeDefsContextMap = new HashMap<>();
130 this.referencedTypes = new HashMap<>();
131 this.additionalTypes = new HashMap<>();
132 resolveTypeDefsFromContext(schemaContext, this.genTypeDefsContextMap, this.additionalTypes);
136 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode,
137 final ModuleContext context) {
138 return javaTypeForSchemaDefinitionType(type, parentNode, null, context);
142 * Converts schema definition type <code>typeDefinition</code> to JAVA
146 * type definition which is converted to JAVA type
147 * @throws IllegalArgumentException
149 * <li>if <code>typeDefinition</code> equal null</li>
150 * <li>if QName of <code>typeDefinition</code> equal null</li>
151 * <li>if name of <code>typeDefinition</code> equal null</li>
155 public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> type, final SchemaNode parentNode, final
156 Restrictions restrictions, final ModuleContext context) {
157 return javaTypeForSchemaDefType(type, parentNode, restrictions, this.schemaContext, this
158 .genTypeDefsContextMap, context);
162 public String getTypeDefaultConstruction(final LeafSchemaNode node) {
167 public String getConstructorPropertyName(final SchemaNode node) {
172 public String getParamNameFromType(final TypeDefinition<?> type) {
176 public Map<String, Map<Optional<Revision>, Map<String, Type>>> getGenTypeDefsContextMap() {
177 return this.genTypeDefsContextMap;
181 * Passes through all modules and through all its type definitions and
182 * convert it to generated types.
184 * The modules are firstly sorted by mutual dependencies. The modules are
185 * sequentially passed. All type definitions of a module are at the
186 * beginning sorted so that type definition with less amount of references
187 * to other type definition are processed first.<br />
188 * For each module is created mapping record in the map
189 * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap}
190 * which map current module name to the map which maps type names to
191 * returned types (generated types).
194 private void resolveTypeDefsFromContext(final SchemaContext schemaContext,
195 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
196 final Map<Module, Set<Type>> additionalTypes) {
198 final Set<Module> modules = schemaContext.getModules();
199 Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!");
200 final List<Module> modulesSortedByDependency = ModuleDependencySort.sort(modules);
202 for (final Module module : modulesSortedByDependency) {
203 Map<Optional<Revision>, Map<String, Type>> dateTypeMap = genTypeDefsContextMap.get(module.getName());
204 if (dateTypeMap == null) {
205 dateTypeMap = new HashMap<>();
207 dateTypeMap.put(module.getRevision(), Collections.emptyMap());
208 genTypeDefsContextMap.put(module.getName(), dateTypeMap);
211 modulesSortedByDependency.stream().filter(Objects::nonNull).forEach(module -> {
212 ModuleContext context = new ModuleContext();
213 final String basePackageName = packageNameWithNamespacePrefix(getRootPackageName(module),
214 BindingNamespaceType.Typedef);
215 final List<TypeDefinition<?>> typeDefinitions = getAllTypedefs(module);
216 for (TypeDefinition<?> typedef : sortTypeDefinitionAccordingDepth(typeDefinitions)) {
217 typedefToGeneratedType(basePackageName, module, typedef, genTypeDefsContextMap,
218 additionalTypes, schemaContext, context);
224 * Converts <code>typeDefinition</code> to concrete JAVA <code>Type</code>.
226 * @param typeDefinition
227 * type definition which should be converted to JAVA
229 * @return JAVA <code>Type</code> which represents
230 * <code>typeDefinition</code>
231 * @throws IllegalArgumentException
233 * <li>if <code>typeDefinition</code> equal null</li>
234 * <li>if Q name of <code>typeDefinition</code></li>
235 * <li>if name of <code>typeDefinition</code></li>
238 public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition,
239 final SchemaNode parentNode) {
240 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
241 Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
242 "Type Definitions Local Name cannot be NULL!");
244 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
245 if (!(baseTypeDef instanceof LeafrefTypeDefinition) && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
246 final Module module = findParentModule(this.schemaContext, parentNode);
248 if (module != null) {
249 final Map<Optional<Revision>, Map<String, Type>> modulesByDate =
250 this.genTypeDefsContextMap.get(module.getName());
251 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
252 if (genTOs != null) {
253 return genTOs.get(typeDefinition.getQName().getLocalName());
261 * Puts <code>refType</code> to map with key <code>refTypePath</code>
264 * schema path used as the map key
266 * type which represents the map value
267 * @throws IllegalArgumentException
269 * <li>if <code>refTypePath</code> equal null</li>
270 * <li>if <code>refType</code> equal null</li>
274 public void putReferencedType(final SchemaPath refTypePath, final Type refType) {
275 Preconditions.checkArgument(refTypePath != null,
276 "Path reference of Enumeration Type Definition cannot be NULL!");
277 Preconditions.checkArgument(refType != null, "Reference to Enumeration Type cannot be NULL!");
278 this.referencedTypes.put(refTypePath, refType);
282 * Converts <code>typeDef</code> which should be of the type
283 * <code>BitsTypeDefinition</code> to <code>GeneratedTOBuilder</code>.
285 * All the bits of the typeDef are added to returning generated TO as
288 * @param basePackageName
289 * string with name of package to which the module belongs
291 * type definition from which is the generated TO builder created
293 * string with the name for generated TO builder
294 * @return generated TO builder which represents <code>typeDef</code>
295 * @throws IllegalArgumentException
297 * <li>if <code>typeDef</code> equals null</li>
298 * <li>if <code>basePackageName</code> equals null</li>
301 @SuppressWarnings({ "rawtypes", "unchecked" })
302 public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName,
303 final TypeDefinition<?> typeDef, final String typeDefName, final String moduleName,
304 final ModuleContext context) {
306 Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");
307 Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
309 if (typeDef instanceof BitsTypeDefinition) {
310 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
312 final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName,
313 true, false, context);
314 final String typedefDescription = encodeAngleBrackets(typeDef.getDescription().orElse(null));
316 genTOBuilder.setDescription(typedefDescription);
317 typeDef.getReference().ifPresent(genTOBuilder::setReference);
318 genTOBuilder.setSchemaPath((List) typeDef.getPath().getPathFromRoot());
319 genTOBuilder.setModuleName(moduleName);
320 genTOBuilder.setBaseType(typeDef);
322 final List<Bit> bitList = bitsTypeDefinition.getBits();
323 GeneratedPropertyBuilder genPropertyBuilder;
324 for (final Bit bit : bitList) {
325 final String name = bit.getName();
326 genPropertyBuilder = genTOBuilder.addProperty(
327 JavaIdentifierNormalizer.normalizeSpecificIdentifier(name, JavaIdentifier.METHOD));
328 genPropertyBuilder.setReadOnly(true);
329 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
331 genTOBuilder.addEqualsIdentity(genPropertyBuilder);
332 genTOBuilder.addHashIdentity(genPropertyBuilder);
333 genTOBuilder.addToStringProperty(genPropertyBuilder);
342 * Converts <code>typedef</code> to generated TO with
343 * <code>typeDefName</code>. Every union type from <code>typedef</code> is
344 * added to generated TO builder as property.
346 * @param basePackageName
347 * string with name of package to which the module belongs
349 * type definition which should be of type
350 * <code>UnionTypeDefinition</code>
352 * string with name for generated TO
353 * @return generated TO builder which represents <code>typedef</code>
354 * @throws NullPointerException
356 * <li>if <code>basePackageName</code> is null</li>
357 * <li>if <code>typedef</code> is null</li>
358 * <li>if QName of <code>typedef</code> is null</li>
361 @SuppressWarnings({ "rawtypes", "unchecked" })
362 public List<GeneratedTOBuilder> provideGeneratedTOBuildersForUnionTypeDef(final String basePackageName,
363 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode,
364 final SchemaContext schemaContext,
365 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
366 final ModuleContext context) {
367 Preconditions.checkNotNull(basePackageName, "Base Package Name cannot be NULL!");
368 Preconditions.checkNotNull(typedef, "Type Definition cannot be NULL!");
369 Preconditions.checkNotNull(typedef.getQName(), "Type definition QName cannot be NULL!");
371 final List<GeneratedTOBuilder> generatedTOBuilders = new ArrayList<>();
372 final List<TypeDefinition<?>> unionTypes = typedef.getTypes();
373 final Module module = findParentModule(schemaContext, parentNode);
375 final GeneratedTOBuilderImpl unionGenTOBuilder;
376 unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName, true, false,
378 final String typedefDescription = encodeAngleBrackets(typedef.getDescription().orElse(null));
379 unionGenTOBuilder.setDescription(typedefDescription);
380 typedef.getReference().ifPresent(unionGenTOBuilder::setReference);
381 unionGenTOBuilder.setSchemaPath((List) typedef.getPath().getPathFromRoot());
382 unionGenTOBuilder.setModuleName(module.getName());
384 generatedTOBuilders.add(unionGenTOBuilder);
385 unionGenTOBuilder.setIsUnion(true);
386 final Map<String, String> expressions = new HashMap<>();
387 for (final TypeDefinition<?> unionType : unionTypes) {
388 final String unionTypeName = unionType.getQName().getLocalName();
389 if (unionType.getBaseType() != null) {
390 resolveExtendedSubtypeAsUnion(unionGenTOBuilder, unionType, expressions,
391 parentNode, schemaContext, genTypeDefsContextMap);
392 } else if (unionType instanceof UnionTypeDefinition) {
393 generatedTOBuilders.add(resolveUnionSubtypeAsUnion(unionGenTOBuilder, (UnionTypeDefinition) unionType,
394 unionGenTOBuilder.getFullyQualifiedName(), parentNode, schemaContext, genTypeDefsContextMap,
396 } else if (unionType instanceof EnumTypeDefinition) {
397 final Enumeration enumeration = addInnerEnumerationToTypeBuilder((EnumTypeDefinition) unionType,
398 unionTypeName, unionGenTOBuilder, context);
399 updateUnionTypeAsProperty(unionGenTOBuilder, enumeration, unionTypeName);
401 final Type javaType = javaTypeForSchemaDefType(unionType, parentNode, null, schemaContext,
402 genTypeDefsContextMap, context);
403 updateUnionTypeAsProperty(unionGenTOBuilder, javaType, unionTypeName);
406 if (!expressions.isEmpty()) {
407 addStringRegExAsConstant(unionGenTOBuilder, expressions);
410 //storeGenTO(typedef, unionGenTOBuilder, parentNode);
412 return generatedTOBuilders;
415 public Map<Module, Set<Type>> getAdditionalTypes() {
416 return this.additionalTypes;
419 public static void addUnitsToGenTO(final GeneratedTOBuilder to, final String units) {
420 if (!Strings.isNullOrEmpty(units)) {
421 to.addConstant(Types.STRING, "_UNITS", "\"" + units + "\"");
422 final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS");
423 prop.setReturnType(Types.STRING);
424 to.addToStringProperty(prop);
428 private Type javaTypeForSchemaDefType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
429 final Restrictions r, final SchemaContext schemaContext,
430 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
431 final ModuleContext context) {
432 Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
433 final String typedefName = typeDefinition.getQName().getLocalName();
434 Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!");
436 // Deal with base types
437 if (typeDefinition.getBaseType() == null) {
438 // We have to deal with differing handling of decimal64. The old parser used a fixed Decimal64 type
439 // and generated an enclosing ExtendedType to hold any range constraints. The new parser instantiates
440 // a base type which holds these constraints.
441 if (typeDefinition instanceof DecimalTypeDefinition) {
442 final Type ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType
443 (typeDefinition, parentNode, r, context);
449 // Deal with leafrefs/identityrefs
450 Type ret = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode, schemaContext,
451 genTypeDefsContextMap, context);
456 ret = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition, parentNode,
459 LOG.debug("Failed to resolve Java type for {}", typeDefinition);
465 Type returnType = javaTypeForExtendedType(typeDefinition, schemaContext, genTypeDefsContextMap, context);
466 if (r != null && !r.isEmpty() && returnType instanceof GeneratedTransferObject) {
467 final GeneratedTransferObject gto = (GeneratedTransferObject) returnType;
468 final Module module = findParentModule(schemaContext, parentNode);
469 final Module module1 = findParentModule(schemaContext, typeDefinition);
470 final String basePackageName = BindingMapping.getRootPackageName(module);
471 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, typeDefinition
472 .getPath(), BindingNamespaceType.Typedef);
473 final String genTOName =
474 JavaIdentifierNormalizer.normalizeSpecificIdentifier(typedefName, JavaIdentifier.CLASS);
475 final String name = packageName + "." + genTOName;
476 if (module.equals(module1) && !returnType.getFullyQualifiedName().equals(name)) {
477 returnType = shadedTOWithRestrictions(gto, r, context);
485 * @param basePackageName
486 * string with name of package to which the module belongs
488 * string with the name of the module for to which the
489 * <code>typedef</code> belongs
491 * type definition of the node for which should be creted JAVA
492 * <code>Type</code> (usually generated TO)
493 * @return JAVA <code>Type</code> representation of <code>typedef</code> or
494 * <code>null</code> value if <code>basePackageName</code> or
495 * <code>modulName</code> or <code>typedef</code> or Q name of
496 * <code>typedef</code> equals <code>null</code>
498 private Type typedefToGeneratedType(final String basePackageName, final Module module,
499 final TypeDefinition<?> typedef,
500 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
501 final Map<Module, Set<Type>> additionalTypes, final SchemaContext schemaContext,
502 final ModuleContext context) {
503 final String moduleName = module.getName();
504 final Optional<Revision> moduleRevision = module.getRevision();
505 if (basePackageName != null && moduleName != null && typedef != null) {
506 final String typedefName = typedef.getQName().getLocalName();
507 final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
508 if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
509 && !(innerTypeDefinition instanceof IdentityrefTypeDefinition)) {
511 if (innerTypeDefinition.getBaseType() != null) {
512 returnType = provideGeneratedTOFromExtendedType(typedef, innerTypeDefinition, basePackageName,
513 module.getName(), schemaContext, genTypeDefsContextMap, context);
514 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
515 final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
516 (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef, schemaContext,
517 genTypeDefsContextMap, context);
518 genTOBuilder.setTypedef(true);
519 genTOBuilder.setIsUnion(true);
520 addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null));
521 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
522 returnType = genTOBuilder.toInstance();
523 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
524 // enums are automatically Serializable
525 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
526 // TODO units for typedef enum
527 returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef, schemaContext, context);
528 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
529 final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
530 final GeneratedTOBuilder genTOBuilder =
531 provideGeneratedTOBuilderForBitsTypeDefinition(
532 basePackageName, bitsTypeDefinition, typedefName, module.getName(), context);
533 genTOBuilder.setTypedef(true);
534 addUnitsToGenTO(genTOBuilder, typedef.getUnits().orElse(null));
535 makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
536 returnType = genTOBuilder.toInstance();
538 final Type javaType = javaTypeForSchemaDefType(innerTypeDefinition, typedef, null,
539 schemaContext, genTypeDefsContextMap, context);
540 returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName(), context);
542 if (returnType != null) {
543 final Map<Optional<Revision>, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(moduleName);
544 Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
545 if (typeMap != null) {
546 if (typeMap.isEmpty()) {
547 typeMap = new HashMap<>(4);
548 modulesByDate.put(moduleRevision, typeMap);
550 typeMap.put(typedefName, returnType);
560 * Returns JAVA <code>Type</code> for instances of the type
561 * <code>ExtendedType</code>.
563 * @param typeDefinition
564 * type definition which is converted to JAVA <code>Type</code>
565 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
567 private Type javaTypeForExtendedType(final TypeDefinition<?> typeDefinition, final SchemaContext schemaContext,
568 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap, final ModuleContext context) {
570 final String typedefName = typeDefinition.getQName().getLocalName();
571 final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
572 Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition, schemaContext,
573 genTypeDefsContextMap, context);
574 if (returnType == null) {
575 final Module module = findParentModule(schemaContext, typeDefinition);
576 final Restrictions r = BindingGeneratorUtil.getRestrictions(typeDefinition);
577 if (module != null) {
578 final Map<Optional<Revision>, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(module.getName());
579 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
580 if (genTOs != null) {
581 returnType = genTOs.get(typedefName);
583 if (returnType == null) {
584 returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
585 baseTypeDef, typeDefinition, r, context);
593 * Returns JAVA <code>Type</code> for instances of the type
594 * <code>LeafrefTypeDefinition</code> or
595 * <code>IdentityrefTypeDefinition</code>.
597 * @param typeDefinition
598 * type definition which is converted to JAVA <code>Type</code>
599 * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
601 private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
602 final SchemaContext schemaContext,
603 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
604 final ModuleContext context) {
605 if (typeDefinition instanceof LeafrefTypeDefinition) {
606 final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
607 Preconditions.checkArgument(!isLeafRefSelfReference(leafref, parentNode, schemaContext),
608 "Leafref %s is referencing itself, incoming StackOverFlowError detected.", leafref);
609 return provideTypeForLeafref(leafref, parentNode, schemaContext, genTypeDefsContextMap, context);
610 } else if (typeDefinition instanceof IdentityrefTypeDefinition) {
611 final IdentityrefTypeDefinition idref = (IdentityrefTypeDefinition) typeDefinition;
612 return provideTypeForIdentityref(idref, schemaContext);
619 * Converts <code>leafrefType</code> to JAVA <code>Type</code>.
621 * The path of <code>leafrefType</code> is followed to find referenced node
622 * and its <code>Type</code> is returned.
625 * leafref type definition for which is the type sought
626 * @return JAVA <code>Type</code> of data schema node which is referenced in
627 * <code>leafrefType</code>
628 * @throws IllegalArgumentException
630 * <li>if <code>leafrefType</code> equal null</li>
631 * <li>if path statement of <code>leafrefType</code> equal null</li>
635 public Type provideTypeForLeafref(final LeafrefTypeDefinition leafrefType, final SchemaNode parentNode,
636 final SchemaContext schemaContext,
637 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
638 final ModuleContext context) {
639 Type returnType = null;
640 Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
642 Preconditions.checkArgument(leafrefType.getPathStatement() != null,
643 "The Path Statement for Leafref Type Definition cannot be NULL!");
645 final RevisionAwareXPath xpath = leafrefType.getPathStatement();
646 final String strXPath = xpath.toString();
647 if (strXPath != null) {
648 if (strXPath.indexOf('[') == -1) {
650 final SchemaNode actualParentSchemaNode;
651 if (parentNode instanceof DerivableSchemaNode && ((DerivableSchemaNode) parentNode).isAddedByUses()) {
652 final Optional<? extends SchemaNode> originalNode = ((DerivableSchemaNode) parentNode).getOriginal();
653 Preconditions.checkArgument(originalNode.isPresent(), "originalNode can not be null.");
654 actualParentSchemaNode = originalNode.get();
655 module = findParentModule(schemaContext, originalNode.get());
657 actualParentSchemaNode = parentNode;
658 module = findParentModule(schemaContext, parentNode);
660 Preconditions.checkArgument(module != null, "Failed to find module for parent %s", parentNode);
662 final SchemaNode dataNode;
663 if (xpath.isAbsolute()) {
664 dataNode = findDataSchemaNode(schemaContext, module, xpath);
666 dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, actualParentSchemaNode, xpath);
668 Preconditions.checkArgument(dataNode != null, "Failed to find leafref target: %s in module %s (%s)",
669 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
671 if (leafContainsEnumDefinition(dataNode)) {
672 returnType = this.referencedTypes.get(dataNode.getPath());
673 } else if (leafListContainsEnumDefinition(dataNode)) {
674 returnType = Types.listTypeFor(this.referencedTypes.get(dataNode.getPath()));
676 returnType = resolveTypeFromDataSchemaNode(dataNode, schemaContext, genTypeDefsContextMap, context);
679 returnType = Types.typeForClass(Object.class);
682 Preconditions.checkArgument(returnType != null, "Failed to find leafref target: %s in module %s (%s)",
683 strXPath, getParentModule(parentNode, schemaContext).getName(), parentNode.getQName().getModule());
688 * Checks if <code>dataNode</code> is <code>LeafSchemaNode</code> and if it
689 * so then checks if it is of type <code>EnumTypeDefinition</code>.
692 * data schema node for which is checked if it is leaf and if it
694 * @return boolean value
696 * <li>true - if <code>dataNode</code> is leaf of type enumeration</li>
697 * <li>false - other cases</li>
700 private static boolean leafContainsEnumDefinition(final SchemaNode dataNode) {
701 if (dataNode instanceof LeafSchemaNode) {
702 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
703 //CompatUtils is not used here anymore
704 if (leaf.getType() instanceof EnumTypeDefinition) {
712 * Checks if <code>dataNode</code> is <code>LeafListSchemaNode</code> and if
713 * it so then checks if it is of type <code>EnumTypeDefinition</code>.
716 * data schema node for which is checked if it is leaflist and if
718 * @return boolean value
720 * <li>true - if <code>dataNode</code> is leaflist of type
722 * <li>false - other cases</li>
725 private static boolean leafListContainsEnumDefinition(final SchemaNode dataNode) {
726 if (dataNode instanceof LeafListSchemaNode) {
727 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
728 if (leafList.getType() instanceof EnumTypeDefinition) {
736 * Converts <code>dataNode</code> to JAVA <code>Type</code>.
739 * contains information about YANG type
740 * @return JAVA <code>Type</code> representation of <code>dataNode</code>
742 private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode, final SchemaContext schemaContext,
743 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
744 final ModuleContext context) {
745 Type returnType = null;
746 if (dataNode != null) {
747 if (dataNode instanceof LeafSchemaNode) {
748 final LeafSchemaNode leaf = (LeafSchemaNode) dataNode;
749 //not using CompatUtils here anymore
750 final TypeDefinition<?> type = leaf.getType();
751 returnType = javaTypeForSchemaDefType(type, leaf, null, schemaContext, genTypeDefsContextMap, context);
752 } else if (dataNode instanceof LeafListSchemaNode) {
753 final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode;
754 returnType = javaTypeForSchemaDefType(leafList.getType(), leafList, null, schemaContext,
755 genTypeDefsContextMap, context);
762 * Seeks for identity reference <code>idref</code> the JAVA
763 * <code>type</code>.<br />
767 * If identy which is referenced via <code>idref</code> has name <b>Idn</b>
768 * then returning type is <b>{@code Class<? extends Idn>}</b></i>
771 * identityref type definition for which JAVA <code>Type</code>
773 * @return JAVA <code>Type</code> of the identity which is refrenced through
776 private static Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref,
777 final SchemaContext schemaContext) {
778 //TODO: incompatibility with Binding spec v2, get first or only one
779 final QName baseIdQName = idref.getIdentities().iterator().next().getQName();
780 final Module module = schemaContext.findModule(baseIdQName.getModule()).orElse(null);
781 IdentitySchemaNode identity = null;
782 for (final IdentitySchemaNode id : module.getIdentities()) {
783 if (id.getQName().equals(baseIdQName)) {
787 Preconditions.checkArgument(identity != null, "Target identity '" + baseIdQName + "' do not exists");
789 final String basePackageName = BindingMapping.getRootPackageName(module);
790 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName, identity.getPath
791 (), BindingNamespaceType.Identity);
793 final String genTypeName = JavaIdentifierNormalizer.normalizeSpecificIdentifier(identity.getQName().getLocalName(),
794 JavaIdentifier.CLASS);
796 final Type baseType = Types.typeForClass(Class.class);
797 final Type paramType = Types.wildcardTypeFor(packageName, genTypeName, true, true, null);
798 return Types.parameterizedTypeFor(baseType, paramType);
801 private static GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto,
802 final Restrictions r, final ModuleContext context) {
803 final GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName(), context);
804 final GeneratedTransferObject parent = gto.getSuperType();
805 if (parent != null) {
806 gtob.setExtendsType(parent);
808 gtob.setRestrictions(r);
809 for (final GeneratedProperty gp : gto.getProperties()) {
810 final GeneratedPropertyBuilder gpb = gtob.addProperty(gp.getName());
811 gpb.setValue(gp.getValue());
812 gpb.setReadOnly(gp.isReadOnly());
813 gpb.setAccessModifier(gp.getAccessModifier());
814 gpb.setReturnType(gp.getReturnType());
815 gpb.setFinal(gp.isFinal());
816 gpb.setStatic(gp.isStatic());
818 return gtob.toInstance();
822 * Adds a new property with the name <code>propertyName</code> and with type
823 * <code>type</code> to <code>unonGenTransObject</code>.
825 * @param unionGenTransObject
826 * generated TO to which should be property added
828 * JAVA <code>type</code> of the property which should be added
829 * to <code>unionGentransObject</code>
830 * @param propertyName
831 * string with name of property which should be added to
832 * <code>unionGentransObject</code>
834 private static void updateUnionTypeAsProperty(final GeneratedTOBuilder unionGenTransObject, final Type type,
835 final String propertyName) {
836 if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
837 final GeneratedPropertyBuilder propBuilder = unionGenTransObject
838 .addProperty(JavaIdentifierNormalizer.normalizeSpecificIdentifier(propertyName, JavaIdentifier.METHOD));
839 propBuilder.setReturnType(type);
841 unionGenTransObject.addEqualsIdentity(propBuilder);
842 unionGenTransObject.addHashIdentity(propBuilder);
843 unionGenTransObject.addToStringProperty(propBuilder);
848 * Wraps code which handle case when union subtype is also of the type
849 * <code>UnionType</code>.
851 * In this case the new generated TO is created for union subtype (recursive
853 * {@link #provideGeneratedTOBuilderForUnionTypeDef(String, UnionTypeDefinition, String, SchemaNode, SchemaContext, Map, ModuleContext)}
854 * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder
855 * <code>parentUnionGenTOBuilder</code> is created property which type is
856 * equal to new generated TO.
858 * @param parentUnionGenTOBuilder
859 * generated TO builder to which is the property with the child
860 * union subtype added
861 * @param basePackageName
862 * string with the name of the module package
863 * @param unionSubtype
864 * type definition which represents union subtype
865 * @return list of generated TO builders. The number of the builders can be
866 * bigger one due to recursive call of
867 * <code>provideGeneratedTOBuildersForUnionTypeDef</code> method.
869 private GeneratedTOBuilder resolveUnionSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
870 final UnionTypeDefinition unionSubtype, final String basePackageName, final SchemaNode parentNode,
871 final SchemaContext schemaContext,
872 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
873 final ModuleContext context) {
874 final String newTOBuilderName = provideAvailableNameForGenTOBuilder(parentUnionGenTOBuilder.getName());
875 final GeneratedTOBuilder subUnionGenTOBUilder = provideGeneratedTOBuilderForUnionTypeDef(
876 basePackageName, unionSubtype, newTOBuilderName, parentNode, schemaContext, genTypeDefsContextMap,
879 final GeneratedPropertyBuilder propertyBuilder;
880 propertyBuilder = parentUnionGenTOBuilder.addProperty(
881 JavaIdentifierNormalizer.normalizeSpecificIdentifier(newTOBuilderName, JavaIdentifier.METHOD));
882 propertyBuilder.setReturnType(subUnionGenTOBUilder);
883 parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
884 parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
886 return subUnionGenTOBUilder;
890 * Converts output list of generated TO builders to one TO builder (first
891 * from list) which contains the remaining builders as its enclosing TO.
893 * @param basePackageName
894 * string with name of package to which the module belongs
896 * type definition which should be of type
897 * <code>UnionTypeDefinition</code>
899 * string with name for generated TO
900 * @return generated TO builder with the list of enclosed generated TO
903 public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
904 final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode,
905 final SchemaContext schemaContext,
906 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap,
907 final ModuleContext context) {
909 final List<GeneratedTOBuilder> builders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
910 typedef, typeDefName, parentNode, schemaContext, genTypeDefsContextMap, context);
911 Preconditions.checkState(!builders.isEmpty(), "No GeneratedTOBuilder objects generated from union %s", typedef);
913 final GeneratedTOBuilder resultTOBuilder = builders.remove(0);
914 for (final GeneratedTOBuilder genTOBuilder : builders) {
915 resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
918 final GeneratedPropertyBuilder genPropBuilder;
920 genPropBuilder = resultTOBuilder.addProperty("value").setReturnType(Types.CHAR_ARRAY).setReadOnly(false);
921 resultTOBuilder.addEqualsIdentity(genPropBuilder);
922 resultTOBuilder.addHashIdentity(genPropBuilder);
923 resultTOBuilder.addToStringProperty(genPropBuilder);
925 provideGeneratedTOBuilderForUnionBuilder(findParentModule(schemaContext, parentNode), resultTOBuilder);
927 return resultTOBuilder;
931 private GeneratedTOBuilder provideGeneratedTOBuilderForUnionBuilder(final Module parentModule,
932 final GeneratedTOBuilder genTOBuilder) {
933 final String outerCls = Types.getOuterClassName(genTOBuilder);
934 final StringBuilder name;
935 if (outerCls != null) {
936 name = new StringBuilder(outerCls);
938 name = new StringBuilder();
940 name.append(genTOBuilder.getName());
941 name.append("Builder");
942 final GeneratedTOBuilderImpl unionBuilder = new GeneratedTOBuilderImpl(getOuterClassPackageName(genTOBuilder),
943 name.toString(), true);
944 unionBuilder.setIsUnionBuilder(true);
946 final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
947 method.setReturnType(genTOBuilder);
948 method.addParameter(Types.STRING, "defaultValue");
949 method.setAccessModifier(AccessModifier.PUBLIC);
950 method.setStatic(true);
952 final Set<Type> types = this.getAdditionalTypes().get(parentModule);
954 this.getAdditionalTypes().put(parentModule,
955 Sets.newHashSet(unionBuilder.toInstance()));
957 types.add(unionBuilder.toInstance());
964 * Wraps code which handle case when union subtype is of the type
965 * <code>ExtendedType</code>.
967 * If TO for this type already exists it is used for the creation of the
968 * property in <code>parentUnionGenTOBuilder</code>. In other case the base
969 * type is used for the property creation.
971 * @param parentUnionGenTOBuilder
972 * generated TO builder in which new property is created
973 * @param unionSubtype
974 * type definition of the <code>ExtendedType</code> type which
975 * represents union subtype
977 * map of strings with the regular expressions
979 * parent Schema Node for Extended Subtype
982 private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
983 final TypeDefinition<?> unionSubtype, final Map<String, String> expressions, final SchemaNode parentNode,
984 final SchemaContext schemaContext,
985 final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap) {
986 final String unionTypeName = unionSubtype.getQName().getLocalName();
987 final Type genTO = findGenTO(unionTypeName, unionSubtype, schemaContext, genTypeDefsContextMap);
989 updateUnionTypeAsProperty(parentUnionGenTOBuilder, genTO, unionTypeName);
993 final TypeDefinition<?> baseType = baseTypeDefForExtendedType(unionSubtype);
994 if (unionTypeName.equals(baseType.getQName().getLocalName())) {
995 final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(baseType,
997 if (javaType != null) {
998 updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType, unionTypeName);
1000 } else if (baseType instanceof LeafrefTypeDefinition) {
1001 final Type javaType = javaTypeForSchemaDefinitionType(baseType,
1003 boolean typeExist = false;
1004 for (final GeneratedPropertyBuilder generatedPropertyBuilder : parentUnionGenTOBuilder
1006 final Type origType = ((GeneratedPropertyBuilderImpl) generatedPropertyBuilder).getReturnType();
1007 if (origType != null && javaType != null && javaType == origType) {
1012 if (!typeExist && javaType != null) {
1013 updateUnionTypeAsProperty(parentUnionGenTOBuilder, javaType,
1014 javaType.getName() + parentUnionGenTOBuilder.getName() + "Value");
1017 if (baseType instanceof StringTypeDefinition) {
1018 expressions.putAll(resolveRegExpressionsFromTypedef(unionSubtype));
1023 * Returns string which contains the same value as <code>name</code> but
1024 * integer suffix is incremented by one. If <code>name</code> contains no
1025 * number suffix then number 1 is added.
1028 * string with name of augmented node
1029 * @return string with the number suffix incremented by one (or 1 is added)
1031 private static String provideAvailableNameForGenTOBuilder(final String name) {
1032 final Matcher mtch = NUMBERS_PATTERN.matcher(name);
1034 final int newSuffix = Integer.valueOf(name.substring(mtch.start())) + 1;
1035 return name.substring(0, mtch.start()) + newSuffix;
1042 * Searches for generated TO for <code>searchedTypeDef</code> type
1043 * definition in {@link #genTypeDefsContextMap genTypeDefsContextMap}
1045 * @param searchedTypeName
1046 * string with name of <code>searchedTypeDef</code>
1047 * @return generated TO for <code>searchedTypeDef</code> or
1048 * <code>null</code> it it doesn't exist
1050 private static Type findGenTO(final String searchedTypeName, final SchemaNode parentNode,
1051 final SchemaContext schemaContext, final Map<String, Map<Optional<Revision>, Map<String, Type>>> genTypeDefsContextMap) {
1053 final Module typeModule = findParentModule(schemaContext, parentNode);
1054 if (typeModule != null && typeModule.getName() != null) {
1055 final Map<Optional<Revision>, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(typeModule.getName());
1056 final Map<String, Type> genTOs = modulesByDate.get(typeModule.getRevision());
1057 if (genTOs != null) {
1058 return genTOs.get(searchedTypeName);
1065 * Adds enumeration to <code>typeBuilder</code>. The enumeration data are
1066 * taken from <code>enumTypeDef</code>.
1068 * @param enumTypeDef
1069 * enumeration type definition is source of enumeration data for
1070 * <code>typeBuilder</code>
1072 * string with the name of enumeration
1073 * @param typeBuilder
1074 * generated type builder to which is enumeration added
1075 * @return enumeration type which contains enumeration data form
1076 * <code>enumTypeDef</code>
1077 * @throws IllegalArgumentException
1079 * <li>if <code>enumTypeDef</code> equals null</li>
1080 * <li>if enum values of <code>enumTypeDef</code> equal null</li>
1081 * <li>if Q name of <code>enumTypeDef</code> equal null</li>
1082 * <li>if name of <code>enumTypeDef</code> equal null</li>
1083 * <li>if name of <code>typeBuilder</code> equal null</li>
1087 private static Enumeration addInnerEnumerationToTypeBuilder(final EnumTypeDefinition enumTypeDef,
1088 final String enumName, final GeneratedTypeBuilderBase<?> typeBuilder, final ModuleContext context) {
1089 Preconditions.checkArgument(enumTypeDef != null, "EnumTypeDefinition reference cannot be NULL!");
1090 Preconditions.checkArgument(enumTypeDef.getQName().getLocalName() != null,
1091 "Local Name in EnumTypeDefinition QName cannot be NULL!");
1092 Preconditions.checkArgument(typeBuilder != null, "Generated Type Builder reference cannot be NULL!");
1094 final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumName, context);
1095 final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription().orElse(null));
1096 enumBuilder.setDescription(enumTypedefDescription);
1097 enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
1098 return enumBuilder.toInstance(enumBuilder);
1101 private static boolean isLeafRefSelfReference(final LeafrefTypeDefinition leafref, final SchemaNode parentNode,
1102 final SchemaContext schemaContext) {
1103 final SchemaNode leafRefValueNode;
1104 final RevisionAwareXPath leafRefXPath = leafref.getPathStatement();
1105 final RevisionAwareXPath leafRefStrippedXPath = new RevisionAwareXPathImpl(leafRefXPath.toString()
1106 .replaceAll("\\[(.*?)\\]", ""), leafRefXPath.isAbsolute());
1108 ///// skip leafrefs in augments - they're checked once augments are resolved
1109 final Iterator<QName> iterator = parentNode.getPath().getPathFromRoot().iterator();
1110 boolean isAugmenting = false;
1111 DataNodeContainer current = null;
1112 DataSchemaNode dataChildByName;
1114 while (iterator.hasNext() && !isAugmenting) {
1115 final QName next = iterator.next();
1116 if (current == null) {
1117 dataChildByName = schemaContext.getDataChildByName(next);
1119 dataChildByName = current.getDataChildByName(next);
1121 if (dataChildByName != null) {
1122 isAugmenting = dataChildByName.isAugmenting();
1126 if (dataChildByName instanceof DataNodeContainer) {
1127 current = (DataNodeContainer) dataChildByName;
1135 final Module parentModule = getParentModule(parentNode, schemaContext);
1136 if (!leafRefStrippedXPath.isAbsolute()) {
1137 leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule,
1138 parentNode, leafRefStrippedXPath);
1140 leafRefValueNode = SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, leafRefStrippedXPath);
1142 return leafRefValueNode != null && leafRefValueNode.equals(parentNode);