Example #1
0
    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)
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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)
Example #7
0
    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)
Example #8
0
    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)