From 8977d4cbb4175dcf729ac59ed919d7400259980e Mon Sep 17 00:00:00 2001 From: Jozef Gloncak Date: Tue, 13 Aug 2013 09:46:38 +0200 Subject: [PATCH] Comment to binding-generator source code (partially) + bug fixing Bug fix: - in method allNotificationsToGenType was changed implemented type from javax.management.Notification to org.opendaylight.yangtools.yang.binding.Notification - if typedef contain as type other typedef from other module it wasn't generated with input parameter in constructor (now fixed) Change-Id: I8182abc649eef43035acdf5d934917756ab2562d Signed-off-by: Jozef Gloncak --- .../generator/api/BindingGenerator.java | 106 ++-- .../generator/impl/BindingGeneratorImpl.java | 507 ++++++++++++++++-- .../binding/yang/types/TypeProviderImpl.java | 24 +- .../generator/impl/ExtendedTypedefTest.java | 24 +- .../ietf-inet-types@2010-09-24.yang | 418 +++++++++++++++ .../typedef_of_typedef.yang | 12 + .../src/main/yang/typedef_of_typedef.yang | 18 +- 7 files changed, 1002 insertions(+), 107 deletions(-) create mode 100644 code-generator/binding-generator-impl/src/test/resources/typedef-of-typedef/ietf-inet-types@2010-09-24.yang rename code-generator/binding-generator-impl/src/test/resources/{ => typedef-of-typedef}/typedef_of_typedef.yang (89%) diff --git a/code-generator/binding-generator-api/src/main/java/org/opendaylight/yangtools/sal/binding/generator/api/BindingGenerator.java b/code-generator/binding-generator-api/src/main/java/org/opendaylight/yangtools/sal/binding/generator/api/BindingGenerator.java index 9ef4ccde2f..83764119a1 100644 --- a/code-generator/binding-generator-api/src/main/java/org/opendaylight/yangtools/sal/binding/generator/api/BindingGenerator.java +++ b/code-generator/binding-generator-api/src/main/java/org/opendaylight/yangtools/sal/binding/generator/api/BindingGenerator.java @@ -1,53 +1,53 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.sal.binding.generator.api; - -import java.util.List; -import java.util.Set; - -import org.opendaylight.yangtools.sal.binding.model.api.Type; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -/** - * - * - */ -public interface BindingGenerator { - - /** - * Generate Types from whole Schema Context. - *
- * The method will return List of All Generated Types that could be - * Generated from Schema Context. - * - * - * @param context Schema Context - * @return List of Generated Types - * - * @see SchemaContext - */ - public List generateTypes(final SchemaContext context); - - /** - * Generate Types from Schema Context restricted by sub set of specified - * Modules. The Schema Context MUST contain all of the sub modules - * otherwise the there is no guarantee that result List of Generated - * Types will contain correct Generated Types. - * - * @param context Schema Context - * @param modules Sub Set of Modules - * @return List of Generated Types restricted by sub set of Modules - * - * @see Module - * @see SchemaContext - * - */ - public List generateTypes(final SchemaContext context, - final Set modules); -} +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.yangtools.sal.binding.generator.api; + +import java.util.List; +import java.util.Set; + +import org.opendaylight.yangtools.sal.binding.model.api.Type; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Transform Schema Context to Generated types. + * + */ +public interface BindingGenerator { + + /** + * Generate Types from whole Schema Context. + *
+ * The method will return List of All Generated Types that could be + * Generated from Schema Context. + * + * + * @param context Schema Context + * @return List of Generated Types + * + * @see SchemaContext + */ + public List generateTypes(final SchemaContext context); + + /** + * Generate Types from Schema Context restricted by sub set of specified + * Modules. The Schema Context MUST contain all of the sub modules + * otherwise the there is no guarantee that result List of Generated + * Types will contain correct Generated Types. + * + * @param context Schema Context + * @param modules Sub Set of Modules + * @return List of Generated Types restricted by sub set of Modules + * + * @see Module + * @see SchemaContext + * + */ + public List generateTypes(final SchemaContext context, + final Set modules); +} diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java index d0cbc34dd2..48df06b137 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java @@ -41,7 +41,6 @@ import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSigna import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort; import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl; import org.opendaylight.yangtools.yang.binding.DataRoot; -import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -74,15 +73,60 @@ import org.opendaylight.yangtools.yang.model.util.UnionType; public final class BindingGeneratorImpl implements BindingGenerator { + /** + * Outter key represents the package name. Outter value represents map of + * all builders in the same package. Inner key represents the schema node + * name (in JAVA class/interface name format). Inner value represents + * instance of builder for schema node specified in key part. + */ private Map> genTypeBuilders; + + /** + * Provide methods for converting YANG types to JAVA types. + */ private TypeProvider typeProvider; + + /** + * Holds reference to schema context to resolve data of augmented elemnt + * when creating augmentation builder + */ private SchemaContext schemaContext; + + /** + * Each grouping which is converted from schema node to generated type is + * added to this map with its Schema path as key to make it easier to get + * reference to it. In schema nodes in uses attribute there is + * only Schema Path but when building list of implemented interfaces for + * Schema node the object of type Type is required. So in this + * case is used this map. + */ private final Map allGroupings = new HashMap(); + /** + * Only parent constructor is invoked. + */ public BindingGeneratorImpl() { super(); } + /** + * Resolves generated types from context schema nodes of all + * modules. + * + * Generated types are created for modules, groupings, types, containers, + * lists, choices, augments, rpcs, notification, identities. + * + * @param context + * schema context which contains data about all schema nodes + * saved in modules + * @return list of types (usually GeneratedType + * GeneratedTransferObjectwhich are generated from + * context data. + * @throws IllegalArgumentException + * if param context is null + * @throws IllegalStateException + * if context contain no modules + */ @Override public List generateTypes(final SchemaContext context) { if (context == null) { @@ -98,11 +142,11 @@ public final class BindingGeneratorImpl implements BindingGenerator { final Set modules = context.getModules(); genTypeBuilders = new HashMap<>(); for (final Module module : modules) { - + generatedTypes.addAll(allGroupingsToGenTypes(module)); - - if(false == module.getChildNodes().isEmpty()) { - generatedTypes.add(moduleToDataType(module)); + + if (false == module.getChildNodes().isEmpty()) { + generatedTypes.add(moduleToDataType(module)); } generatedTypes.addAll(allTypeDefinitionsToGenTypes(module)); generatedTypes.addAll(allContainersToGenTypes(module)); @@ -117,6 +161,34 @@ public final class BindingGeneratorImpl implements BindingGenerator { return generatedTypes; } + /** + * Resolves generated types from context schema nodes only for + * modules specified in modules + * + * Generated types are created for modules, groupings, types, containers, + * lists, choices, augments, rpcs, notification, identities. + * + * @param context + * schema context which contains data about all schema nodes + * saved in modules + * @param modules + * set of modules for which schema nodes should be generated + * types + * @return list of types (usually GeneratedType or + * GeneratedTransferObject) which: + *
    + *
  • are generated from context schema nodes and
  • + *
  • are also part of some of the module in modules + * set
  • . + *
+ * @throws IllegalArgumentException + *
    + *
  • if param context is null or
  • + *
  • if param modules is null
  • + *
+ * @throws IllegalStateException + * if context contain no modules + */ @Override public List generateTypes(final SchemaContext context, final Set modules) { if (context == null) { @@ -138,8 +210,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { final List generatedTypes = new ArrayList<>(); generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); - if(false == contextModule.getChildNodes().isEmpty()) { - generatedTypes.add(moduleToDataType(contextModule)); + if (false == contextModule.getChildNodes().isEmpty()) { + generatedTypes.add(moduleToDataType(contextModule)); } generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule)); generatedTypes.addAll(allContainersToGenTypes(contextModule)); @@ -157,6 +229,22 @@ public final class BindingGeneratorImpl implements BindingGenerator { return filteredGenTypes; } + /** + * Converts all extended type definitions of module to the list of + * Type objects. + * + * @param module + * module from which is obtained set of type definitions + * @return list of Type which are generated from extended + * definition types (object of type ExtendedType) + * @throws IllegalArgumentException + *
    + *
  • if module equals null
  • + *
  • if name of module equals null
  • + *
  • if type definitions of module equal null
  • + *
+ * + */ private List allTypeDefinitionsToGenTypes(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -181,6 +269,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { return generatedTypes; } + /** + * Converts all containers of the module to the list of + * Type objects. + * + * @param module + * module from which is obtained DataNodeIterator to iterate over + * all containers + * @return list of Type which are generated from containers + * (objects of type ContainerSchemaNode) + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ private List allContainersToGenTypes(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -207,6 +312,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { return generatedTypes; } + /** + * Converts all lists of the module to the list of Type + * objects. + * + * @param module + * module from which is obtained DataNodeIterator to iterate over + * all lists + * @return list of Type which are generated from lists (objects + * of type ListSchemaNode) + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ private List allListsToGenTypes(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -235,6 +357,22 @@ public final class BindingGeneratorImpl implements BindingGenerator { return generatedTypes; } + /** + * Converts all choices of the module to the list of + * Type objects. + * + * @param module + * module from which is obtained DataNodeIterator to iterate over + * all choices + * @return list of Type which are generated from choices + * (objects of type ChoiceNode) + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • * + *
+ * + */ private List allChoicesToGenTypes(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -256,6 +394,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { return generatedTypes; } + /** + * Converts all augmentation of the module to the list + * Type objects. + * + * @param module + * module from which is obtained list of all augmentation objects + * to iterate over them + * @return list of Type which are generated from augments + * (objects of type AugmentationSchema) + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ private List allAugmentsToGenTypes(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -277,6 +432,22 @@ public final class BindingGeneratorImpl implements BindingGenerator { return generatedTypes; } + /** + * Returns list of AugmentationSchema objects. The objects are + * sorted according to the length of their target path from the shortest to + * the longest. + * + * @param module + * module from which is obtained list of all augmentation objects + * @return list of sorted AugmentationSchema objects obtained + * from module + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the set of augmentation equals null
  • + *
+ * + */ private List resolveAugmentations(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -305,13 +476,27 @@ public final class BindingGeneratorImpl implements BindingGenerator { return sortedAugmentations; } + /** + * Converts whole module to GeneratedType object. + * Firstly is created the module builder object from which is finally + * obtained reference to GeneratedType object. + * + * @param module + * module from which are obtained the module name, child nodes, + * uses and is derived package name + * @return GeneratedType which is internal representation of + * the module + * @throws IllegalArgumentException + * if the module equals null + * + */ private GeneratedType moduleToDataType(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); } final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); - addInterfaceDefinition(module, moduleDataTypeBuilder); + addImplementedInterfaceFromUses(module, moduleDataTypeBuilder); moduleDataTypeBuilder.addImplementsType(Types.typeForClass(DataRoot.class)); final String basePackageName = moduleNamespaceToPackageName(module); @@ -322,6 +507,24 @@ public final class BindingGeneratorImpl implements BindingGenerator { return moduleDataTypeBuilder.toInstance(); } + /** + * Converts all rpcs inputs and outputs substatements of the module + * to the list of Type objects. In addition are to containers + * and lists which belong to input or output also part of returning list. + * + * @param module + * module from which is obtained set of all rpc objects to + * iterate over them + * @return list of Type which are generated from rpcs inputs, + * outputs + container and lists which are part of inputs or outputs + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ private List allRPCMethodsToGenType(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -338,11 +541,11 @@ public final class BindingGeneratorImpl implements BindingGenerator { final String basePackageName = moduleNamespaceToPackageName(module); final Set rpcDefinitions = module.getRpcs(); - - if(rpcDefinitions.isEmpty()) { - return Collections.emptyList(); + + if (rpcDefinitions.isEmpty()) { + return Collections.emptyList(); } - + final List genRPCTypes = new ArrayList<>(); final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service"); interfaceBuilder.addImplementsType(Types.typeForClass(RpcService.class)); @@ -362,7 +565,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (input != null) { rpcInOut.add(new DataNodeIterator(input)); GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName); - addInterfaceDefinition(input, inType); + addImplementedInterfaceFromUses(input, inType); inType.addImplementsType(Types.DATA_OBJECT); resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes()); Type inTypeInstance = inType.toInstance(); @@ -374,7 +577,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (output != null) { rpcInOut.add(new DataNodeIterator(output)); GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName); - addInterfaceDefinition(output, outType); + addImplementedInterfaceFromUses(output, outType); outType.addImplementsType(Types.DATA_OBJECT); resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes()); outTypeInstance = outType.toInstance(); @@ -408,6 +611,24 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genRPCTypes; } + /** + * Converts all notifications of the module to the list of + * Type objects. In addition are to this list added containers + * and lists which are part of this notification. + * + * @param module + * module from which is obtained set of all notification objects + * to iterate over them + * @return list of Type which are generated from notification + * (object of type NotificationDefinition + * @throws IllegalArgumentException + *
    + *
  • if the module equals null
  • + *
  • if the name of module equals null
  • + *
  • if the set of child nodes equals null
  • + *
+ * + */ private List allNotificationsToGenType(final Module module) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -444,7 +665,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { } final GeneratedTypeBuilder notificationTypeBuilder = addDefaultInterfaceDefinition(basePackageName, notification); - notificationTypeBuilder.addImplementsType(Types.typeForClass(Notification.class)); + notificationTypeBuilder.addImplementsType(Types + .typeForClass(org.opendaylight.yangtools.yang.binding.Notification.class)); // Notification object resolveDataSchemaNodes(basePackageName, notificationTypeBuilder, notification.getChildNodes()); genNotifyTypes.add(notificationTypeBuilder.toInstance()); @@ -453,6 +675,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genNotifyTypes; } + /** + * Converts all identities of the module to the list of + * Type objects. + * + * @param module + * module from which is obtained set of all identity objects to + * iterate over them + * @param context + * schema context only used as input parameter for method + * {@link identityToGenType} + * @return list of Type which are generated from identities + * (object of type IdentitySchemaNode + * + */ private List allIdentitiesToGenTypes(final Module module, final SchemaContext context) { List genTypes = new ArrayList<>(); @@ -468,6 +704,26 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genTypes; } + /** + * Converts the identity object to GeneratedType. Firstly it is + * created transport object builder. If identity contains base identity then + * reference to base identity is added to superior identity as its extend. + * If identity doesn't contain base identity then only reference to abstract + * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity + * BaseIdentity} is added + * + * @param basePackageName + * string containing package name to which identity belongs + * @param identity + * IdentitySchemaNode which contains data about identity + * @param context + * SchemaContext which is used to get package and name + * information about base of identity + * + * @return GeneratedType which is generated from identity (object of type + * IdentitySchemaNode + * + */ private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity, final SchemaContext context) { if (identity == null) { @@ -494,13 +750,29 @@ public final class BindingGeneratorImpl implements BindingGenerator { return newType.toInstance(); } + /** + * Converts all groupings of the module to the list of + * Type objects. Firstly are groupings sorted according mutual + * dependencies. At least dependend (indepedent) groupings are in the list + * saved at first positions. For every grouping the record is added to map + * {@link BindingGeneratorImpl#allGroupings allGroupings} + * + * @param module + * module from which is obtained set of all grouping objects to + * iterate over them + * @return list of Type which are generated from groupings + * (object of type GroupingDefinition) + * + */ private List allGroupingsToGenTypes(final Module module) { + if (module == null) { + throw new IllegalArgumentException("Module parameter can not be null"); + } final List genTypes = new ArrayList<>(); final String basePackageName = moduleNamespaceToPackageName(module); final Set groupings = module.getGroupings(); List groupingsSortedByDependencies; - // groupingsSortedByDependencies = - // sortGroupingDefinitionsByUses(groupings); + groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings); for (final GroupingDefinition grouping : groupingsSortedByDependencies) { @@ -512,6 +784,18 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genTypes; } + /** + * Converts individual grouping to GeneratedType. Firstly generated type + * builder is created and every child node of grouping is resolved to the + * method. + * + * @param basePackageName + * string containing name of package to which grouping belongs. + * @param grouping + * GroupingDefinition which contains data about grouping + * @return GeneratedType which is generated from grouping (object of type + * GroupingDefinition) + */ private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) { if (grouping == null) { return null; @@ -525,6 +809,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { return typeBuilder.toInstance(); } + /** + * Tries to find EnumTypeDefinition in typeDefinition. If base + * type of typeDefinition is of the type ExtendedType then this + * method is recursivelly called with this base type. + * + * @param typeDefinition + * TypeDefinition in which should be EnumTypeDefinition found as + * base type + * @return EnumTypeDefinition if it is found inside + * typeDefinition or null in other case + */ private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition typeDefinition) { if (typeDefinition != null) { if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) { @@ -536,6 +831,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { return null; } + /** + * Adds enumeration builder created from enumTypeDef to + * typeBuilder. + * + * Each enumTypeDef item is added to builder with its name and + * value. + * + * @param enumTypeDef + * EnumTypeDefinition contains enum data + * @param enumName + * string contains name which will be assigned to enumeration + * builder + * @param typeBuilder + * GeneratedTypeBuilder to which will be enum builder assigned + * @return enumeration builder which contais data from + * enumTypeDef + */ private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName, final GeneratedTypeBuilder typeBuilder) { if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null) @@ -567,6 +879,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { return null; } + /** + * Generates type builder for module. + * + * @param module + * Module which is source of package name for generated type + * builder + * @param postfix + * string which is added to the module class name representation + * as suffix + * @return instance of GeneratedTypeBuilder which represents + * module. + * @throws IllegalArgumentException + * if module equals null + */ private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) { if (module == null) { throw new IllegalArgumentException("Module reference cannot be NULL!"); @@ -578,6 +904,28 @@ public final class BindingGeneratorImpl implements BindingGenerator { } + /** + * Converts augSchema to list of Type which + * contains generated type for augmentation. In addition there are also + * generated types for all containers, list and choices which are child of + * augSchema node or a generated types for cases are added if + * augmented node is choice. + * + * @param augmentPackageName + * string with the name of the package to which the augmentation + * belongs + * @param augSchema + * AugmentationSchema which is contains data about agumentation + * (target path, childs...) + * @return list of Type objects which contains generated type + * for augmentation and for container, list and choice child nodes + * @throws IllegalArgumentException + *
    + *
  • if augmentPackageName equals null
  • + *
  • if augSchema equals null
  • + *
  • if target path of augSchema equals null
  • + *
+ */ private List augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) { if (augmentPackageName == null) { throw new IllegalArgumentException("Package Name cannot be NULL!"); @@ -606,8 +954,6 @@ public final class BindingGeneratorImpl implements BindingGenerator { if (!(targetSchemaNode instanceof ChoiceNode)) { final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, targetPackageName, targetSchemaNodeName, augSchema); - addInterfaceDefinition(augSchema, augTypeBuilder); - final GeneratedType augType = augTypeBuilder.toInstance(); genTypes.add(augType); } else { @@ -615,26 +961,33 @@ public final class BindingGeneratorImpl implements BindingGenerator { parseToClassName(targetSchemaNodeName)); final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode; final Set choiceCaseNodes = choiceTarget.getCases(); - genTypes.addAll(augmentCasesToGenTypes(augmentPackageName, refChoiceType, choiceCaseNodes)); + genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType, + choiceCaseNodes)); } genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName, augChildNodes)); } return genTypes; } - private List augmentCasesToGenTypes(final String augmentPackageName, final Type refChoiceType, - final Set choiceCaseNodes) { - if (augmentPackageName == null) { - throw new IllegalArgumentException("Augment Package Name string cannot be NULL!"); - } - if (choiceCaseNodes == null) { - throw new IllegalArgumentException("Set of Choice Case Nodes cannot be NULL!"); - } - final List genTypes = generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType, - choiceCaseNodes); - return genTypes; - } - + /** + * Returns a generated type builder for an augmentation. + * + * The name of the type builder is equal to the name of augmented node with + * serial number as suffix. + * + * @param augmentPackageName + * string with contains the package name to which the augment + * belongs + * @param targetPackageName + * string with the package name to which the augmented node + * belongs + * @param targetSchemaNodeName + * string with the name of the augmented node + * @param augSchema + * augmentation schema which contains data about the child nodes + * and uses of augment + * @return generated type builder for augment + */ private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName, final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) { final String targetTypeName = parseToClassName(targetSchemaNodeName); @@ -652,12 +1005,26 @@ public final class BindingGeneratorImpl implements BindingGenerator { augTypeBuilder.addImplementsType(Types.DATA_OBJECT); augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); + addImplementedInterfaceFromUses(augSchema, augTypeBuilder); augSchemaNodeToMethods(augmentPackageName, augTypeBuilder, augChildNodes); augmentBuilders.put(augTypeName, augTypeBuilder); return augTypeBuilder; } + /** + * Convert a container, list and choice subnodes (and recursivelly their + * subnodes) of augment to generated types + * + * @param augBasePackageName + * string with the augment package name + * @param augChildNodes + * set of data schema nodes which represents child nodes of the + * augment + * + * @return list of Type which represents container, list and + * choice subnodes of augment + */ private List augmentationBodyToGenTypes(final String augBasePackageName, final Set augChildNodes) { final List genTypes = new ArrayList<>(); @@ -704,6 +1071,18 @@ public final class BindingGeneratorImpl implements BindingGenerator { return genTypes; } + /** + * Returns first unique name for the augment generated type builder. The + * generated type builder name for augment consists from name of augmented + * node and serial number of its augmentation. + * + * @param builders + * map of builders which were created in the package to which the + * augmentation belongs + * @param genTypeName + * string with name of augmented node + * @return string with unique name for augmentation builder + */ private String augGenTypeName(final Map builders, final String genTypeName) { String augTypeName = genTypeName; @@ -715,6 +1094,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { return augTypeName; } + /** + * Converts containerNode to generated type. Firstly the + * generated type builder is created. The subnodes of + * containerNode are added as methods and the instance of + * GeneratedType is returned. + * + * @param basePackageName + * string with name of the package to which the superior node + * belongs + * @param containerNode + * container schema node with the data about childs nodes and + * schema paths + * @return generated type for containerNode + */ private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) { if (containerNode == null) { return null; @@ -728,6 +1121,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { return typeBuilder.toInstance(); } + /** + * + * @param basePackageName + * @param typeBuilder + * @param schemaNodes + * @return + */ private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName, final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { if ((schemaNodes != null) && (typeBuilder != null)) { @@ -842,6 +1242,31 @@ public final class BindingGeneratorImpl implements BindingGenerator { return generatedTypes; } + /** + * Generates list of generated types for all the cases of a choice which are + * added to the choice through the augment. + * + * + * @param basePackageName + * string contains name of package to which augment belongs. If + * an augmented choice is from an other package (pcg1) than an + * augmenting choice (pcg2) then case's of the augmenting choice + * will belong to pcg2. + * @param refChoiceType + * Type which represents the choice to which case belongs. Every + * case has to contain its choice in extend part. + * @param caseNodes + * set of choice case nodes for which is checked if are/aren't + * added to choice through augmentation + * @return list of generated types which represents augmented cases of + * choice refChoiceType + * @throws IllegalArgumentException + *
    + *
  • if basePackageName equals null
  • + *
  • if refChoiceType equals null
  • + *
  • if caseNodes equals null
  • + *
+ */ private List generateTypesFromAugmentedChoiceCases(final String basePackageName, final Type refChoiceType, final Set caseNodes) { if (basePackageName == null) { @@ -1003,7 +1428,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { /** * Method instantiates new Generated Type Builder and sets the implements * definitions of Data Object and Augmentable. - * + * * @param packageName * Generated Type Package Name * @param schemaNode @@ -1018,14 +1443,14 @@ public final class BindingGeneratorImpl implements BindingGenerator { } if (schemaNode instanceof DataNodeContainer) { - addInterfaceDefinition((DataNodeContainer) schemaNode, builder); + addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, builder); } return builder; } /** - * + * * @param packageName * @param schemaNode * @return @@ -1257,7 +1682,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { * Adds the implemented types to type builder. The method passes through the * list of elements which contains {@code dataNodeContainer} and adds them * as implements type to builder - * + * * @param dataNodeContainer * element which contains the list of used YANG groupings * @param builder @@ -1265,13 +1690,14 @@ public final class BindingGeneratorImpl implements BindingGenerator { * dataNodeContainer * @return generated type builder which contains implemented types */ - private GeneratedTypeBuilder addInterfaceDefinition(final DataNodeContainer dataNodeContainer, + private GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer, final GeneratedTypeBuilder builder) { for (UsesNode usesNode : dataNodeContainer.getUses()) { if (usesNode.getGroupingPath() != null) { GeneratedType genType = allGroupings.get(usesNode.getGroupingPath()); - if(genType == null) { - throw new IllegalStateException("Grouping " +usesNode.getGroupingPath() + "is not resolved for " + builder.getName()); + if (genType == null) { + throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for " + + builder.getName()); } builder.addImplementsType(genType); } @@ -1280,4 +1706,3 @@ public final class BindingGeneratorImpl implements BindingGenerator { } } - diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java index ad1d09435b..39062d27e8 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java @@ -52,6 +52,7 @@ import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition; import org.opendaylight.yangtools.yang.model.util.ExtendedType; import org.opendaylight.yangtools.yang.model.util.StringType; import org.opendaylight.yangtools.yang.model.util.UnionType; +import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; public final class TypeProviderImpl implements TypeProvider { @@ -83,7 +84,7 @@ public final class TypeProviderImpl implements TypeProvider { /* * (non-Javadoc) - * + * * @see org.opendaylight.controller.yang.model.type.provider.TypeProvider# * javaTypeForYangType(java.lang.String) */ @@ -368,7 +369,14 @@ public final class TypeProviderImpl implements TypeProvider { if (modules == null) { throw new IllegalArgumentException("Sef of Modules cannot be NULL!"); } - for (final Module module : modules) { + final Module[] modulesArray = new Module[modules.size()]; + int i = 0; + for (Module modul : modules) { + modulesArray[i++] = modul; + } + final List modulesSortedByDependency = ModuleDependencySort.sort(modulesArray); + + for (final Module module : modulesSortedByDependency) { if (module == null) { continue; } @@ -658,7 +666,13 @@ public final class TypeProviderImpl implements TypeProvider { final String lowTypeDef = extendedType.getQName().getLocalName(); final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeDefName); - final Map typeMap = genTypeDefsContextMap.get(moduleName); + final Module parentModule = findParentModuleForTypeDefinition(schemaContext, extendedType); + + Map typeMap = null; + if (parentModule != null) { + typeMap = genTypeDefsContextMap.get(parentModule.getName()); + } + if (typeMap != null) { Type type = typeMap.get(lowTypeDef); if (type instanceof GeneratedTransferObject) { @@ -676,7 +690,7 @@ public final class TypeProviderImpl implements TypeProvider { * equal depth. In next step are lists from this map concatenated to one * list in ascending order according to their depth. All type definitions * are in the list behind all type definitions on which depends. - * + * * @param unsortedTypeDefinitions * represents list of type definitions * @return list of type definitions sorted according their each other @@ -710,7 +724,7 @@ public final class TypeProviderImpl implements TypeProvider { /** * The method return how many immersion is necessary to get from type * definition to base type. - * + * * @param typeDefinition * is type definition for which is depth looked for. * @return how many immersion is necessary to get from type definition to diff --git a/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ExtendedTypedefTest.java b/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ExtendedTypedefTest.java index ccdda2414c..397b88886f 100644 --- a/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ExtendedTypedefTest.java +++ b/code-generator/binding-generator-impl/src/test/java/org/opendaylight/yangtools/sal/binding/generator/impl/ExtendedTypedefTest.java @@ -22,11 +22,17 @@ import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; public class ExtendedTypedefTest { private final static List testModels = new ArrayList(); + private final static String testFolderPath = AugmentedTypeTest.class.getResource("/typedef-of-typedef").getPath(); @BeforeClass public static void loadTestResources() { - final File listModelFile = new File(ExtendedTypedefTest.class.getResource("/typedef_of_typedef.yang").getPath()); - testModels.add(listModelFile); + final File testFolder = new File(testFolderPath); + + for (final File fileEntry : testFolder.listFiles()) { + if (fileEntry.isFile()) { + testModels.add(fileEntry); + } + } } @Test @@ -42,6 +48,7 @@ public class ExtendedTypedefTest { GeneratedTransferObject simpleTypedef4 = null; GeneratedTransferObject extendedTypedefUnion = null; GeneratedTransferObject unionTypedef = null; + GeneratedTransferObject typedefFromImport = null; for (final Type type : genTypes) { if (type instanceof GeneratedTransferObject) { if (type.getName().equals("SimpleTypedef4")) { @@ -50,16 +57,24 @@ public class ExtendedTypedefTest { extendedTypedefUnion = (GeneratedTransferObject) type; } else if (type.getName().equals("UnionTypedef")) { unionTypedef = (GeneratedTransferObject) type; + } else if (type.getName().equals("TypedefFromImport")) { + typedefFromImport = (GeneratedTransferObject) type; } } } + // typedef-from-import + assertNotNull("TypedefFromImport not found", typedefFromImport); + List properties = typedefFromImport.getProperties(); + assertTrue("Properties of TypedefFromImport should be empty", properties.isEmpty()); + assertEquals("TypedefFromImport should be extended", "Ipv4Address", typedefFromImport.getExtends().getName()); + // simple-typedef4 assertNotNull("SimpleTypedef4 not found", simpleTypedef4); assertNotNull("ExtendedTypedefUnion not found", extendedTypedefUnion); assertNotNull("UnionTypedef", unionTypedef); - List properties = simpleTypedef4.getProperties(); + properties = simpleTypedef4.getProperties(); assertTrue("SimpleTypedef4 shouldn't have properties.", properties.isEmpty()); GeneratedTransferObject extendTO = simpleTypedef4.getExtends(); @@ -121,8 +136,7 @@ public class ExtendedTypedefTest { .getReturnType().getName()); assertEquals("Incorrect type for property simpleTypedef1.", "SimpleTypedef1", simpleTypedef1Property .getReturnType().getName()); - assertEquals("Incorrect type for property byteType.", "ByteType", byteTypeProperty - .getReturnType().getName()); + assertEquals("Incorrect type for property byteType.", "ByteType", byteTypeProperty.getReturnType().getName()); assertEquals("Incorrect type for property typedefEnumFruit.", "TypedefEnumFruit", typedefEnumFruitProperty .getReturnType().getName()); } diff --git a/code-generator/binding-generator-impl/src/test/resources/typedef-of-typedef/ietf-inet-types@2010-09-24.yang b/code-generator/binding-generator-impl/src/test/resources/typedef-of-typedef/ietf-inet-types@2010-09-24.yang new file mode 100644 index 0000000000..6a6c7483ec --- /dev/null +++ b/code-generator/binding-generator-impl/src/test/resources/typedef-of-typedef/ietf-inet-types@2010-09-24.yang @@ -0,0 +1,418 @@ + module ietf-inet-types { + + namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types"; + prefix "inet"; + + organization + "IETF NETMOD (NETCONF Data Modeling Language) Working Group"; + + contact + "WG Web: + WG List: + + WG Chair: David Partain + + + WG Chair: David Kessens + + + Editor: Juergen Schoenwaelder + "; + + description + "This module contains a collection of generally useful derived + YANG data types for Internet addresses and related things. + + Copyright (c) 2010 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, is permitted pursuant to, and subject to the license + terms contained in, the Simplified BSD License set forth in Section + 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 6021; see + the RFC itself for full legal notices."; + + revision 2010-09-24 { + description + "Initial revision."; + reference + "RFC 6021: Common YANG Data Types"; + } + + /*** collection of protocol field related types ***/ + + typedef ip-version { + type enumeration { + enum unknown { + value "0"; + description + "An unknown or unspecified version of the Internet protocol."; + } + enum ipv4 { + value "1"; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum ipv6 { + value "2"; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + + In the value set and its semantics, this type is equivalent + to the InetVersion textual convention of the SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + typedef dscp { + type uint8 { + range "0..63"; + } + description + "The dscp type represents a Differentiated Services Code-Point + that may be used for marking packets in a traffic stream. + + In the value set and its semantics, this type is equivalent + to the Dscp textual convention of the SMIv2."; + reference + "RFC 3289: Management Information Base for the Differentiated + Services Architecture + RFC 2474: Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers + RFC 2780: IANA Allocation Guidelines For Values In + the Internet Protocol and Related Headers"; + } + + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The flow-label type represents flow identifier or Flow Label + in an IPv6 packet header that may be used to discriminate + traffic flows. + + In the value set and its semantics, this type is equivalent + to the IPv6FlowLabel textual convention of the SMIv2."; + reference + "RFC 3595: Textual Conventions for IPv6 Flow Label + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification"; + } + + typedef port-number { + type uint16 { + range "0..65535"; + } + description + "The port-number type represents a 16-bit port number of an + Internet transport layer protocol such as UDP, TCP, DCCP, or + SCTP. Port numbers are assigned by IANA. A current list of + all assignments is available from . + + Note that the port number value zero is reserved by IANA. In + situations where the value zero does not make sense, it can + be excluded by subtyping the port-number type. + + In the value set and its semantics, this type is equivalent + to the InetPortNumber textual convention of the SMIv2."; + reference + "RFC 768: User Datagram Protocol + RFC 793: Transmission Control Protocol + RFC 4960: Stream Control Transmission Protocol + RFC 4340: Datagram Congestion Control Protocol (DCCP) + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + /*** collection of autonomous system related types ***/ + + typedef as-number { + type uint32; + description + "The as-number type represents autonomous system numbers + which identify an Autonomous System (AS). An AS is a set + of routers under a single technical administration, using + an interior gateway protocol and common metrics to route + packets within the AS, and using an exterior gateway + protocol to route packets to other ASs'. IANA maintains + the AS number space and has delegated large parts to the + regional registries. + + Autonomous system numbers were originally limited to 16 + bits. BGP extensions have enlarged the autonomous system + number space to 32 bits. This type therefore uses an uint32 + base type without a range restriction in order to support + a larger autonomous system number space. + + In the value set and its semantics, this type is equivalent + to the InetAutonomousSystemNumber textual convention of + the SMIv2."; + reference + "RFC 1930: Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271: A Border Gateway Protocol 4 (BGP-4) + RFC 4893: BGP Support for Four-octet AS Number Space + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + /*** collection of IP address and hostname related types ***/ + + typedef ip-address { + type union { + type inet:ipv4-address; + type inet:ipv6-address; + } + description + "The ip-address type represents an IP address and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + + typedef ipv4-address { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '(%[\p{N}\p{L}]+)?'; + } + description + "The ipv4-address type represents an IPv4 address in + dotted-quad notation. The IPv4 address may include a zone + index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format for the zone index is the numerical + format"; + } + + typedef ipv6-address { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(%[\p{N}\p{L}]+)?'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(%.+)?'; + } + description + "The ipv6-address type represents an IPv6 address in full, + mixed, shortened, and shortened-mixed notation. The IPv6 + address may include a zone index, separated by a % sign. + + The zone index is used to disambiguate identical address + values. For link-local addresses, the zone index will + typically be the interface index number or the name of an + interface. If the zone index is not present, the default + zone of the device will be used. + + The canonical format of IPv6 addresses uses the compressed + format described in RFC 4291, Section 2.2, item 2 with the + following additional rules: the :: substitution must be + applied to the longest sequence of all-zero 16-bit chunks + in an IPv6 address. If there is a tie, the first sequence + of all-zero 16-bit chunks is replaced by ::. Single + all-zero 16-bit chunks are not compressed. The canonical + format uses lowercase characters and leading zeros are + not allowed. The canonical format for the zone index is + the numerical format as described in RFC 4007, Section + 11.2."; + reference + "RFC 4291: IP Version 6 Addressing Architecture + RFC 4007: IPv6 Scoped Address Architecture + RFC 5952: A Recommendation for IPv6 Address Text Representation"; + } + + typedef ip-prefix { + type union { + type inet:ipv4-prefix; + type inet:ipv6-prefix; + } + description + "The ip-prefix type represents an IP prefix and is IP + version neutral. The format of the textual representations + implies the IP version."; + } + + typedef ipv4-prefix { + type string { + pattern + '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}' + + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])' + + '/(([0-9])|([1-2][0-9])|(3[0-2]))'; + } + description + "The ipv4-prefix type represents an IPv4 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal to 32. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The canonical format of an IPv4 prefix has all bits of + the IPv4 address set to zero that are not part of the + IPv4 prefix."; + } + + typedef ipv6-prefix { + type string { + pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}' + + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|' + + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))' + + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))'; + pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|' + + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)' + + '(/.+)'; + } + description + "The ipv6-prefix type represents an IPv6 address prefix. + The prefix length is given by the number following the + slash character and must be less than or equal 128. + + A prefix length value of n corresponds to an IP address + mask that has n contiguous 1-bits from the most + significant bit (MSB) and all other bits set to 0. + + The IPv6 address should have all bits that do not belong + to the prefix set to zero. + + The canonical format of an IPv6 prefix has all bits of + the IPv6 address set to zero that are not part of the + IPv6 prefix. Furthermore, IPv6 address is represented + in the compressed format described in RFC 4291, Section + 2.2, item 2 with the following additional rules: the :: + substitution must be applied to the longest sequence of + all-zero 16-bit chunks in an IPv6 address. If there is + a tie, the first sequence of all-zero 16-bit chunks is + replaced by ::. Single all-zero 16-bit chunks are not + compressed. The canonical format uses lowercase + characters and leading zeros are not allowed."; + reference + "RFC 4291: IP Version 6 Addressing Architecture"; + } + + /*** collection of domain name and URI types ***/ + + typedef domain-name { + type string { + pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.'; + length "1..253"; + } + description + "The domain-name type represents a DNS domain name. The + name SHOULD be fully qualified whenever possible. + + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + + The description clause of schema nodes using the domain-name + type MUST describe when and how these names are resolved to + IP addresses. Note that the resolution of a domain-name value + may require to query multiple DNS records (e.g., A for IPv4 + and AAAA for IPv6). The order of the resolution process and + which DNS record takes precedence can either be defined + explicitely or it may depend on the configuration of the + resolver. + + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be encoded in punycode as described in RFC + 3492"; + reference + "RFC 952: DoD Internet Host Table Specification + RFC 1034: Domain Names - Concepts and Facilities + RFC 1123: Requirements for Internet Hosts -- Application + and Support + RFC 2782: A DNS RR for specifying the location of services + (DNS SRV) + RFC 3492: Punycode: A Bootstring encoding of Unicode for + Internationalized Domain Names in Applications + (IDNA) + RFC 5891: Internationalizing Domain Names in Applications + (IDNA): Protocol"; + } + + typedef host { + type union { + type inet:ip-address; + type inet:domain-name; + } + description + "The host type represents either an IP address or a DNS + domain name."; + } + + typedef uri { + type string; + description + "The uri type represents a Uniform Resource Identifier + (URI) as defined by STD 66. + + Objects using the uri type MUST be in US-ASCII encoding, + and MUST be normalized as described by RFC 3986 Sections + 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary + percent-encoding is removed, and all case-insensitive + characters are set to lowercase except for hexadecimal + digits, which are normalized to uppercase as described in + Section 6.2.2.1. + + The purpose of this normalization is to help provide + unique URIs. Note that this normalization is not + sufficient to provide uniqueness. Two URIs that are + textually distinct after this normalization may still be + equivalent. + + Objects using the uri type may restrict the schemes that + they permit. For example, 'data:' and 'urn:' schemes + might not be appropriate. + + A zero-length URI is not a valid URI. This can be used to + express 'URI absent' where required. + + In the value set and its semantics, this type is equivalent + to the Uri SMIv2 textual convention defined in RFC 5017."; + reference + "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax + RFC 3305: Report from the Joint W3C/IETF URI Planning Interest + Group: Uniform Resource Identifiers (URIs), URLs, + and Uniform Resource Names (URNs): Clarifications + and Recommendations + RFC 5017: MIB Textual Conventions for Uniform Resource + Identifiers (URIs)"; + } + + } \ No newline at end of file diff --git a/code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang b/code-generator/binding-generator-impl/src/test/resources/typedef-of-typedef/typedef_of_typedef.yang similarity index 89% rename from code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang rename to code-generator/binding-generator-impl/src/test/resources/typedef-of-typedef/typedef_of_typedef.yang index fc0bab9f0d..b8558b3426 100644 --- a/code-generator/binding-generator-impl/src/test/resources/typedef_of_typedef.yang +++ b/code-generator/binding-generator-impl/src/test/resources/typedef-of-typedef/typedef_of_typedef.yang @@ -3,6 +3,12 @@ module typedef_typedef { namespace "urn:typedef:typedef"; prefix "sbd"; + import ietf-inet-types { + prefix "inet"; + revision-date 2010-09-24; + } + + organization "OPEN DAYLIGHT"; contact "http://www.opendaylight.org/"; @@ -10,6 +16,12 @@ module typedef_typedef { } + + typedef typedef-from-import { + type inet:ipv4-address; + } + + typedef byte-type { type bits { bit first-bit { diff --git a/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang b/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang index 3aa67705cc..b8558b3426 100644 --- a/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang +++ b/code-generator/samples/maven-code-gen-sample/src/main/yang/typedef_of_typedef.yang @@ -3,6 +3,12 @@ module typedef_typedef { namespace "urn:typedef:typedef"; prefix "sbd"; + import ietf-inet-types { + prefix "inet"; + revision-date 2010-09-24; + } + + organization "OPEN DAYLIGHT"; contact "http://www.opendaylight.org/"; @@ -10,6 +16,12 @@ module typedef_typedef { } + + typedef typedef-from-import { + type inet:ipv4-address; + } + + typedef byte-type { type bits { bit first-bit { @@ -35,7 +47,7 @@ module typedef_typedef { } typedef simple-typedef1 { - type uint8; + type uint8; } typedef simple-typedef2 { @@ -52,7 +64,7 @@ module typedef_typedef { typedef simple-typedef1-1 { type uint16; - } + } typedef union-typedef { @@ -62,7 +74,7 @@ module typedef_typedef { type byte-type; type typedef-enum-fruit; } - } + } typedef extended-typedef-union { type union-typedef; -- 2.36.6