def _add_leaf_leaflist_prop(self, stmt, parent_element): prop = Property() stmt.i_property = prop prop.stmt = stmt parent_element.owned_elements.append(prop) prop.owner = parent_element # for inlined enum types where leaf { type enumeration { enum_type = self.types_extractor.get_enum_type_stmt(stmt) bits_type = self.types_extractor.get_bits_type_stmt(stmt) union_type = self.types_extractor.get_union_type_stmt(stmt) # if the type statement is totally self contained # then we need to extract this type if enum_type is not None and enum_type == stmt.search_one('type'): # we have to create the enum enum_class = Enum() enum_class.stmt = enum_type parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element prop.property_type = enum_class elif bits_type is not None and bits_type == stmt.search_one('type'): # we have to create the specific subclass of FixedBitsDict bits_class = Bits() bits_class.stmt = bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element prop.property_type = bits_class elif union_type is not None and union_type == stmt.search_one('type'): def _add_union_type(union_type_stmt, parent_element): for contained_type in union_type_stmt.i_type_spec.types: contained_enum_type = self.types_extractor.get_enum_type_stmt( contained_type) contained_bits_type = self.types_extractor.get_bits_type_stmt( contained_type) contained_union_type = self.types_extractor.get_union_type_stmt( contained_type) if contained_enum_type is not None and contained_enum_type == contained_type: enum_class = Enum() enum_class.stmt = contained_enum_type parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element contained_enum_type.i_enum = enum_class if contained_bits_type is not None and contained_bits_type == contained_type: bits_class = Bits() bits_class.stmt = contained_bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element contained_bits_type.i_bits = bits_class if contained_union_type is not None and contained_union_type == contained_type: _add_union_type(contained_union_type, parent_element) # is this embedded ? if union_type == stmt.search_one('type'): # we need to check for the types under the union to see if # any of them need to be handled differently _add_union_type(union_type, parent_element)
def _add_leaf_leaflist_prop(self, stmt, parent_element): prop = Property() stmt.i_property = prop prop.stmt = stmt parent_element.owned_elements.append(prop) prop.owner = parent_element # for inlined enum types where leaf { type enumeration { enum_type = self.types_extractor.get_enum_type_stmt(stmt) bits_type = self.types_extractor.get_bits_type_stmt(stmt) union_type = self.types_extractor.get_union_type_stmt(stmt) # if the type statement is totally self contained # then we need to extract this type if enum_type is not None and enum_type == stmt.search_one('type'): # we have to create the enum enum_class = Enum() enum_class.stmt = enum_type parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element prop.property_type = enum_class elif bits_type is not None and bits_type == stmt.search_one('type'): # we have to create the specific subclass of FixedBitsDict bits_class = Bits() bits_class.stmt = bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element prop.property_type = bits_class elif union_type is not None and union_type == stmt.search_one('type'): def _add_union_type(union_type_stmt, parent_element): for contained_type in union_type_stmt.i_type_spec.types: contained_enum_type = self.types_extractor.get_enum_type_stmt(contained_type) contained_bits_type = self.types_extractor.get_bits_type_stmt(contained_type) contained_union_type = self.types_extractor.get_union_type_stmt(contained_type) if contained_enum_type is not None and contained_enum_type == contained_type: enum_class = Enum() enum_class.stmt = contained_enum_type parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element contained_enum_type.i_enum = enum_class if contained_bits_type is not None and contained_bits_type == contained_type: bits_class = Bits() bits_class.stmt = contained_bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element contained_bits_type.i_bits = bits_class if contained_union_type is not None and contained_union_type == contained_type: _add_union_type(contained_union_type, parent_element) # is this embedded ? if union_type == stmt.search_one('type'): # we need to check for the types under the union to see if # any of them need to be handled differently _add_union_type(union_type, parent_element)
def _create_grouping_class_api_model(self, stmt, parent_element): """ Converts the stmt to an Element in the api_model according to the grouping as class algorithm. In the grouping as class code generations strategy a grouping in YANG is converted to a class. Every class that represents a container or a list or a grouping that has a uses statement in it , inherits from the grouping class that corresponds to the grouping in the uses statement. for example grouping abc { class Abc_Grouping(object):... .... } container A { class A(Abc_Grouping): ... uses abc; } In the first pass Elements that encapsulate the references are created this is done for all the stmts we are interested after this is done, resolve cross references is called on all the elements to resolve all the cross references (examples include super classes extends field in a class) :param `pyang.statements.Statement` stmt The statement to convert :param `Element` The parent element. """ # process typedefs first so that they are resolved # when we have to use them element = parent_element # identities if hasattr(stmt, 'i_identities'): for identity_stmt in stmt.i_identities.values(): identity_class = Class(self.iskeyword) identity_class.stmt = identity_stmt identity_class.owner = parent_element parent_element.owned_elements.append(identity_class) identity_stmt.i_class = identity_class if hasattr(stmt, 'i_typedefs'): for typedef_stmt_name in stmt.i_typedefs: typedef_stmt = stmt.i_typedefs[typedef_stmt_name] self._add_enums_and_bits(typedef_stmt, parent_element) # walk the groupings first if hasattr(stmt, 'i_groupings'): for grouping_name in stmt.i_groupings: self._create_grouping_class_api_model( stmt.i_groupings[grouping_name], element) if stmt.keyword == 'grouping': clazz = Class(self.iskeyword) stmt.i_class = clazz clazz.stmt = stmt parent_element.owned_elements.append(clazz) clazz.set_owner(parent_element, self.language) element = clazz elif stmt.keyword == 'container' or stmt.keyword == 'list': clazz = Class(self.iskeyword) stmt.i_class = clazz clazz.stmt = stmt parent_element.owned_elements.append(clazz) clazz.set_owner(parent_element, self.language) element = clazz if not isinstance(parent_element, Package): # create a property along with the class prop = Property(self.iskeyword) stmt.i_property = prop prop.stmt = stmt prop.property_type = clazz parent_element.owned_elements.append(prop) prop.owner = parent_element elif stmt.keyword == 'leaf' or stmt.keyword == 'leaf-list': prop = Property(self.iskeyword) stmt.i_property = prop prop.stmt = stmt parent_element.owned_elements.append(prop) prop.owner = parent_element # for inlined enum types where leaf { type enumeration { enum_type = self.types_extractor.get_enum_type_stmt(stmt) bits_type = self.types_extractor.get_bits_type_stmt(stmt) if enum_type is not None: if enum_type == stmt.search_one('type'): # we have to create the enum enum_class = Enum(self.iskeyword) enum_class.stmt = enum_type parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element prop.property_type = enum_class enum_type.parent.i_enum = enum_class enum_type.i_enum = enum_class elif bits_type is not None: if bits_type == stmt.search_one('type'): # we have to create the specific subclass of FixedBitsDict bits_class = Bits(self.iskeyword) bits_class.stmt = bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element prop.property_type = bits_class # walk the children if hasattr(stmt, 'i_children'): grouping_stmt_names = [] if stmt.keyword != 'module': uses_stmts = stmt.search('uses') groupings_used = [] for uses_stmt in uses_stmts: groupings_used.append(uses_stmt.i_grouping) for grouping in groupings_used: grouping_stmt_names.extend( [s.arg for s in grouping.i_children]) chs = [ ch for ch in stmt.i_children if (ch.keyword in statements.data_definition_keywords and ch.arg not in grouping_stmt_names) ] for child_stmt in chs: self._create_grouping_class_api_model(child_stmt, element)
def _create_expanded_api_model(self, stmt, parent_element, deviation_packages): """ Converts the stmt to an Element in the api_model according to the expanded code generation algorithm. The expanded code generation algorithm uses the tree view of the YANG models to generate the API. For each data node in the YANG model a corresponding Class element will be created. In the first pass Elements that encapsulate the references are created this is done for all the stmts we are interested after this is done, resolve cross references is called on all the elements to resolve all the cross references (examples include super classes extends field in a class) :param `pyang.statements.Statement` stmt The statement to convert :param `Element` The parent element. :param list of 'Package' The deviation packages. """ # process typedefs first so that they are resolved # when we have to use them element = parent_element # identities if hasattr(stmt, 'i_identities'): for identity_stmt in stmt.i_identities.values(): identity_class = Class(self.iskeyword) identity_class.stmt = identity_stmt identity_class.owner = parent_element parent_element.owned_elements.append(identity_class) identity_stmt.i_class = identity_class if hasattr(stmt, 'i_typedefs'): for typedef_stmt_name in stmt.i_typedefs: typedef_stmt = stmt.i_typedefs[typedef_stmt_name] self._add_enums_and_bits(typedef_stmt, parent_element) if stmt.keyword == 'module': pass elif stmt.keyword in ('container', 'list', 'rpc', 'input', 'output'): if stmt.keyword in ('input', 'output') and len(stmt.substmts) == 0: pass else: clazz = Class(self.iskeyword) stmt.i_class = clazz clazz.stmt = stmt for e in parent_element.owned_elements: if e.name == clazz.name: clazz.name = clazz.name + '_' parent_element.owned_elements.append(clazz) clazz.set_owner(parent_element, self.language) if self.language == 'cpp' and name_matches_ancestor( clazz.name, parent_element): clazz.name = clazz.name + '_' element = clazz if not isinstance(parent_element, Package): # create a property along with the class prop = Property(self.iskeyword) stmt.i_property = prop prop.stmt = stmt prop.property_type = clazz for e in parent_element.owned_elements: if isinstance(e, Property): s = snake_case(e.stmt.arg) if snake_case(prop.stmt.arg) == s: prop.name = prop.name + '_' parent_element.owned_elements.append(prop) prop.owner = parent_element elif stmt.keyword == 'leaf' or stmt.keyword == 'leaf-list' or stmt.keyword == 'anyxml': self._add_leaf_leaflist_prop(stmt, parent_element) if hasattr(stmt, 'i_deviation'): self._add_to_deviation_package(stmt, parent_element, deviation_packages) # walk the children _keywords = statements.data_definition_keywords + [ 'case', 'rpc', 'input', 'output' ] if hasattr(stmt, 'i_children'): self._sanitize_namespace(stmt) child_stmts = [] if hasattr(stmt, 'i_key') and stmt.i_key is not None: child_stmts.extend([s for s in stmt.i_key]) if stmt.keyword == 'rpc' and self.language == 'cpp': child_stmts = self._walk_children(stmt, _keywords) else: _children = [child for child in stmt.i_children \ if (child not in child_stmts and child.keyword in _keywords)] child_stmts.extend(_children) for child_stmt in child_stmts: self._create_expanded_api_model(child_stmt, element, deviation_packages)
def _add_leaf_leaflist_prop(self, stmt, parent_element): prop = Property(self.iskeyword) stmt.i_property = prop prop.stmt = stmt for element in parent_element.owned_elements: if element.name == prop.name: prop.name = prop.name + '_' parent_element.owned_elements.append(prop) prop.owner = parent_element # for inlined enum types where leaf { type enumeration { enum_type = self.types_extractor.get_enum_type_stmt(stmt) bits_type = self.types_extractor.get_bits_type_stmt(stmt) union_type = self.types_extractor.get_union_type_stmt(stmt) # if the type statement is totally self contained # then we need to extract this type if stmt.keyword == 'anyxml': anyxml = AnyXml() anyxml.stmt = stmt # parent_element.owned_elements.append(anyxml) # anyxml.owner = parent_element prop.property_type = anyxml elif enum_type is not None and enum_type == stmt.search_one('type'): # we have to create the enum enum_class = Enum(self.iskeyword) enum_class.stmt = enum_type disambiguate_class_name_from_ancestors_and_siblings( self.language, enum_class, parent_element) parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element prop.property_type = enum_class enum_type.i_enum = enum_class enum_type.parent.i_enum = enum_class elif bits_type is not None and bits_type == stmt.search_one('type'): # we have to create the specific subclass of FixedBitsDict bits_class = Bits(self.iskeyword) bits_class.stmt = bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element prop.property_type = bits_class elif union_type is not None and union_type == stmt.search_one('type'): def _add_union_type(union_type_stmt, parent_element): for contained_type in union_type_stmt.i_type_spec.types: contained_enum_type = self.types_extractor.get_enum_type_stmt( contained_type) contained_bits_type = self.types_extractor.get_bits_type_stmt( contained_type) contained_union_type = self.types_extractor.get_union_type_stmt( contained_type) if contained_enum_type is not None and contained_enum_type == contained_type: enum_class = Enum(self.iskeyword) enum_class.stmt = contained_enum_type disambiguate_class_name_from_ancestors_and_siblings( self.language, enum_class, parent_element) parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element contained_enum_type.i_enum = enum_class contained_enum_type.parent.i_enum = enum_class if contained_bits_type is not None and contained_bits_type == contained_type: bits_class = Bits(self.iskeyword) bits_class.stmt = contained_bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element contained_bits_type.i_bits = bits_class if contained_union_type is not None and contained_union_type == contained_type: _add_union_type(contained_union_type, parent_element) # is this embedded ? if union_type == stmt.search_one('type'): # we need to check for the types under the union to see if # any of them need to be handled differently _add_union_type(union_type, parent_element)
def _create_grouping_class_api_model(self, stmt, parent_element): """ Converts the stmt to an Element in the api_model according to the grouping as class algorithm. In the grouping as class code generations strategy a grouping in YANG is converted to a class. Every class that represents a container or a list or a grouping that has a uses statement in it , inherits from the grouping class that corresponds to the grouping in the uses statement. for example grouping abc { class Abc_Grouping(object):... .... } container A { class A(Abc_Grouping): ... uses abc; } In the first pass Elements that encapsulate the references are created this is done for all the stmts we are interested after this is done, resolve cross references is called on all the elements to resolve all the cross references (examples include super classes extends field in a class) :param `pyang.statements.Statement` stmt The statement to convert :param `Element` The parent element. """ # process typedefs first so that they are resolved # when we have to use them element = parent_element # identities if hasattr(stmt, 'i_identities'): for identity_stmt in stmt.i_identities.values(): identity_class = Class() identity_class.stmt = identity_stmt identity_class.owner = parent_element parent_element.owned_elements.append(identity_class) identity_stmt.i_class = identity_class if hasattr(stmt, 'i_typedefs'): for typedef_stmt_name in stmt.i_typedefs: typedef_stmt = stmt.i_typedefs[typedef_stmt_name] self._add_enums_and_bits(typedef_stmt, parent_element) # walk the groupings first if hasattr(stmt, 'i_groupings'): for grouping_name in stmt.i_groupings: self._create_grouping_class_api_model( stmt.i_groupings[grouping_name], element) if stmt.keyword == 'grouping': clazz = Class() stmt.i_class = clazz clazz.stmt = stmt parent_element.owned_elements.append(clazz) clazz.owner = parent_element element = clazz elif stmt.keyword == 'container' or stmt.keyword == 'list': clazz = Class() stmt.i_class = clazz clazz.stmt = stmt parent_element.owned_elements.append(clazz) clazz.owner = parent_element element = clazz if not isinstance(parent_element, Package): # create a property along with the class prop = Property() stmt.i_property = prop prop.stmt = stmt prop.property_type = clazz parent_element.owned_elements.append(prop) prop.owner = parent_element elif stmt.keyword == 'leaf' or stmt.keyword == 'leaf-list': prop = Property() stmt.i_property = prop prop.stmt = stmt parent_element.owned_elements.append(prop) prop.owner = parent_element # for inlined enum types where leaf { type enumeration { enum_type = self.types_extractor.get_enum_type_stmt(stmt) bits_type = self.types_extractor.get_bits_type_stmt(stmt) if enum_type is not None: if enum_type == stmt.search_one('type'): # we have to create the enum enum_class = Enum() enum_class.stmt = enum_type parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element prop.property_type = enum_class enum_type.parent.i_enum = enum_class elif bits_type is not None: if bits_type == stmt.search_one('type'): # we have to create the specific subclass of FixedBitsDict bits_class = Bits() bits_class.stmt = bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element prop.property_type = bits_class # walk the children if hasattr(stmt, 'i_children'): grouping_stmt_names = [] if stmt.keyword != 'module': uses_stmts = stmt.search('uses') groupings_used = [] for uses_stmt in uses_stmts: groupings_used.append(uses_stmt.i_grouping) for grouping in groupings_used: grouping_stmt_names.extend( [s.arg for s in grouping.i_children]) chs = [ch for ch in stmt.i_children if ch.keyword in statements.data_definition_keywords and ch.arg not in grouping_stmt_names] for child_stmt in chs: self._create_grouping_class_api_model(child_stmt, element)
def _create_expanded_api_model(self, stmt, parent_element, deviation_packages): """ Converts the stmt to an Element in the api_model according to the expanded code generation algorithm. The expanded code generation algorithm uses the tree view of the YANG models to generate the API. For each data node in the YANG model a corresponding Class element will be created. In the first pass Elements that encapsulate the references are created this is done for all the stmts we are interested after this is done, resolve cross references is called on all the elements to resolve all the cross references (examples include super classes extends field in a class) :param `pyang.statements.Statement` stmt The statement to convert :param `Element` The parent element. :param list of 'Package' The deviation packages. """ # process typedefs first so that they are resolved # when we have to use them element = parent_element # identities if hasattr(stmt, 'i_identities'): for identity_stmt in stmt.i_identities.values(): identity_class = Class() identity_class.stmt = identity_stmt identity_class.owner = parent_element parent_element.owned_elements.append(identity_class) identity_stmt.i_class = identity_class if hasattr(stmt, 'i_typedefs'): for typedef_stmt_name in stmt.i_typedefs: typedef_stmt = stmt.i_typedefs[typedef_stmt_name] self._add_enums_and_bits(typedef_stmt, parent_element) if stmt.keyword == 'module': pass elif stmt.keyword == 'container' or stmt.keyword == 'list' or stmt.keyword == 'rpc' or stmt.keyword == 'input' or stmt.keyword == 'output': if (stmt.keyword == 'input' or stmt.keyword == 'output') and len(stmt.substmts) == 0: pass else: clazz = Class() stmt.i_class = clazz clazz.stmt = stmt parent_element.owned_elements.append(clazz) clazz.owner = parent_element element = clazz if not isinstance(parent_element, Package): # create a property along with the class prop = Property() stmt.i_property = prop prop.stmt = stmt prop.property_type = clazz parent_element.owned_elements.append(prop) prop.owner = parent_element elif stmt.keyword == 'leaf' or stmt.keyword == 'leaf-list' or stmt.keyword == 'anyxml': self._add_leaf_leaflist_prop(stmt, parent_element) if hasattr(stmt, 'i_deviation'): self._add_to_deviation_package(stmt, parent_element, deviation_packages) # walk the children if hasattr(stmt, 'i_children'): self._sanitize_namespace(stmt) chs = [child for child in stmt.i_children if child.keyword in statements.data_definition_keywords or child.keyword == 'case' or child.keyword == 'rpc' or child.keyword == 'input' or child.keyword == 'output'] for child_stmt in chs: self._create_expanded_api_model(child_stmt, element, deviation_packages)
def _add_leaf_leaflist_prop(self, stmt, parent_element): prop = Property(self.iskeyword) stmt.i_property = prop prop.stmt = stmt for element in parent_element.owned_elements: if element.name == prop.name: prop.name = prop.name + '_' parent_element.owned_elements.append(prop) prop.owner = parent_element # for inlined enum types where leaf { type enumeration { enum_type = self.types_extractor.get_enum_type_stmt(stmt) bits_type = self.types_extractor.get_bits_type_stmt(stmt) union_type = self.types_extractor.get_union_type_stmt(stmt) # if the type statement is totally self contained # then we need to extract this type if stmt.keyword == 'anyxml': anyxml = AnyXml() anyxml.stmt = stmt # parent_element.owned_elements.append(anyxml) # anyxml.owner = parent_element prop.property_type = anyxml elif enum_type is not None and enum_type == stmt.search_one('type'): # we have to create the enum enum_class = Enum(self.iskeyword) enum_class.stmt = enum_type disambiguate_class_name_from_ancestors_and_siblings(self.language, enum_class, parent_element) parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element prop.property_type = enum_class enum_type.i_enum = enum_class enum_type.parent.i_enum = enum_class elif bits_type is not None and bits_type == stmt.search_one('type'): # we have to create the specific subclass of FixedBitsDict bits_class = Bits(self.iskeyword) bits_class.stmt = bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element prop.property_type = bits_class elif union_type is not None and union_type == stmt.search_one('type'): def _add_union_type(union_type_stmt, parent_element): for contained_type in union_type_stmt.i_type_spec.types: contained_enum_type = self.types_extractor.get_enum_type_stmt(contained_type) contained_bits_type = self.types_extractor.get_bits_type_stmt(contained_type) contained_union_type = self.types_extractor.get_union_type_stmt(contained_type) if contained_enum_type is not None and contained_enum_type == contained_type: enum_class = Enum(self.iskeyword) enum_class.stmt = contained_enum_type disambiguate_class_name_from_ancestors_and_siblings(self.language, enum_class, parent_element) parent_element.owned_elements.append(enum_class) enum_class.owner = parent_element contained_enum_type.i_enum = enum_class contained_enum_type.parent.i_enum = enum_class if contained_bits_type is not None and contained_bits_type == contained_type: bits_class = Bits(self.iskeyword) bits_class.stmt = contained_bits_type parent_element.owned_elements.append(bits_class) bits_class.owner = parent_element contained_bits_type.i_bits = bits_class if contained_union_type is not None and contained_union_type == contained_type: _add_union_type(contained_union_type, parent_element) # is this embedded ? if union_type == stmt.search_one('type'): # we need to check for the types under the union to see if # any of them need to be handled differently _add_union_type(union_type, parent_element)