def __init__(self, name, bb_attrs, bir_headers, bir_tables, 
                 bir_other_modules, ncs_parser, inst_parser):
        check_attributes(name, bb_attrs, BasicBlock.required_attributes)
        logging.debug("Adding basic_block {0}".format(name))

        # set the name
        self.name = name
        self.local_header = None
        self.local_table = None
        self.instructions = []
        self.instructions = bb_attrs['instructions']

        self.next_offset = []   # based on 'next_control_state'
        self.next_state = []    # based on 'next_control_state'
        self._handle_next_control_state(bb_attrs['next_control_state'])

        self.other_modules = bir_other_modules
        self.inst_parser = inst_parser
        self.ncs_parser = ncs_parser

        # set the local_header
        header_name = bb_attrs.get('local_header', None)
        if header_name:
            if  header_name not in bir_headers.keys():
                raise BIRRefError(header_name, self.name)
            self.local_header = bir_headers[header_name]

        # set the local_table
        table_name = bb_attrs.get('local_table', None)
        if table_name:
            if  table_name not in bir_tables.keys():
                raise BIRRefError(table_name, self.name)
            self.local_table = bir_tables[table_name]
    def __init__(self, name, control_flow_attrs, basic_blocks, bir_parser):
        super(ControlFlow, self,).__init__(name)
        check_attributes(name, control_flow_attrs, 
                         ControlFlow.required_attributes)
        logging.debug("Adding Control Flow {0}".format(name))

        self.basic_blocks = basic_blocks

        cf = control_flow_attrs['start_control_state']
        check_control_state(self.name, cf)
        self.control_state = ControlState(cf, None, bir_parser)
    def __init__(self, name, table_attrs):
        check_attributes(name, table_attrs, Table.required_attributes)
        logging.debug("Adding table {0}".format(name)) 

        self.name = name
        self.match_type = table_attrs['match_type']
        self.depth = table_attrs['depth']
        # FIXME: unused, but could be used for type checking?
        self.req_attrs = {'type':'metadata', 'values':table_attrs['request']}
        self.resp_attrs = {'type':'metadata', 'values':table_attrs['response']}
        self.operations = table_attrs.get('operations', None )
        
        # The list of table entries
        self.entries = []
    def __init__(self, name, control_flow_attrs, basic_blocks):
        super(ControlFlow, self,).__init__(name)
        check_attributes(name, control_flow_attrs, 
                         ControlFlow.required_attributes)
        logging.debug("Adding Control Flow {0}".format(name))

        start_control_state = control_flow_attrs['start_control_state']
        if (len(start_control_state) != 2 or
            not isinstance(start_control_state[0],int)):
            raise BIRControlStateError(self.name)

        self.start_offset = []   # based on 'start_control_state'
        self.start_state = []    # based on 'start_control_state'
        self._handle_control_state(control_flow_attrs['start_control_state'])
        self.basic_blocks = basic_blocks
    def __init__(self, name, struct_attrs):
        check_attributes(name, struct_attrs, BIRStruct.required_attributes)
        logging.debug("Adding bir_struct {0}".format(name))

        self.name = name
        self.length = 0
        self.fields = OrderedDict()
        self.field_offsets = OrderedDict()

        for tmp_field in struct_attrs['fields']:
            for name, size in tmp_field.items():
                self.fields[name] = size

            self.field_offsets[name] = self.length
            self.length += size
    def __init__(self, name, struct_attrs):
        check_attributes(name, struct_attrs, BIRStruct.required_attributes)
        logging.debug("Adding bir_struct {0}".format(name))

        self.name = name
        self.length = 0
        self.fields = OrderedDict()
        self.field_offsets = OrderedDict()

        for tmp_field in struct_attrs['fields']:
            for name, size in tmp_field.items():
                self.fields[name] = size

            self.field_offsets[name] = self.length
            self.length += size
    def __init__(self, name, metadata_attrs, bir_structs, buf=None, 
                 bit_offset=0):
        check_attributes(name, metadata_attrs, 
                         MetadataInstance.required_attributes)

        logging.debug("Adding metadata {0}".format(name))
        self.name = name
        self.values = OrderedDict()
        # FIXME: used for syntactic checking
        self.visibility = metadata_attrs['visibility']

        struct_name = metadata_attrs['values']
        for f_name, f_size in bir_structs[struct_name].fields.items():
            self.values[f_name] = ValueInstance(f_name, f_size)

        if buf:
            self.extract(buf, bit_offset)
    def __init__(self, name, table_attrs):
        check_attributes(name, table_attrs, Table.required_attributes)
        logging.debug("Adding table {0}".format(name))

        self.name = name
        self.match_type = table_attrs['match_type']
        self.depth = table_attrs['depth']
        # FIXME: unused, but could be used for type checking?
        self.req_attrs = {'type': 'metadata', 'values': table_attrs['request']}
        self.resp_attrs = {
            'type': 'metadata',
            'values': table_attrs['response']
        }
        self.operations = table_attrs.get('operations', None)

        # The list of table entries
        self.entries = []
    def __init__(self, name, table_attrs):
        check_attributes(name, table_attrs, Table.required_attributes)
        logging.debug("Adding table {0}".format(name)) 

        # TODO: support types in meta_ir.common.meta_ir_valid_match_types
        if table_attrs['match_type'] != 'exact':
            raise BIRTableTypeError(name)

        self.name = name
        self.match_type = table_attrs['match_type']
        self.depth = table_attrs['depth']
        # FIXME: unused, but could be used for type checking?
        self.req_attrs = {'type':'metadata', 'values':table_attrs['request']}
        self.resp_attrs = {'type':'metadata', 'values':table_attrs['response']}
        self.operations = table_attrs.get('operations', None )
        
        # The list of table entries
        self.entries = []
    def __init__(self, name, bb_attrs, bir_headers, bir_tables, 
                 bir_other_modules, bir_parser):
        check_attributes(name, bb_attrs, BasicBlock.required_attributes)
        logging.debug("Adding basic_block {0}".format(name))

        self.name = name
        self.local_header = self._get_header(bb_attrs, bir_headers)
        self.local_table = self._get_table(bb_attrs, bir_tables)

        check_instructions(self.name, bb_attrs['instructions'])
        self.instructions = Instructions(bb_attrs['instructions'],
                                         self.local_table,
                                         self.local_header,
                                         bir_other_modules,
                                         bir_parser)

        check_control_state(self.name, bb_attrs['next_control_state'])
        self.control_state = ControlState(bb_attrs['next_control_state'],
                                          self.local_header,
                                          bir_parser)
    def __init__(self,
                 name,
                 metadata_attrs,
                 bir_structs,
                 buf=None,
                 bit_offset=0):
        check_attributes(name, metadata_attrs,
                         MetadataInstance.required_attributes)

        logging.debug("Adding metadata {0}".format(name))
        self.name = name
        self.values = OrderedDict()
        # FIXME: used for syntactic checking
        self.visibility = metadata_attrs['visibility']

        struct_name = metadata_attrs['values']
        for f_name, f_size in bir_structs[struct_name].fields.items():
            self.values[f_name] = ValueInstance(f_name, f_size)

        if buf:
            self.extract(buf, bit_offset)