def interpret()

in python/profilo/importer/interpreter.py [0:0]


    def interpret(self):
        self.parents, self.children = self.__calculate_parents_children()

        self.trace = Trace(
            begin=min(
                (
                    x.timestamp
                    for x in self.trace_file.entries
                    if hasattr(x, "timestamp")
                )
            ),
            end=max(
                (
                    x.timestamp
                    for x in self.trace_file.entries
                    if hasattr(x, "timestamp")
                )
            ),
            id=self.trace_file.headers.get("id"),
        )
        thread_items = {}
        framework_frames = {}  # method_id -> full name
        for entry in self.trace_file.entries:
            if entry.type == "JAVA_FRAME_NAME":
                for child in self.children[entry]:
                    framework_frames[entry.arg3] = child.data
                continue
            if isinstance(entry, StandardEntry):
                thread_items.setdefault(entry.tid, []).append(entry)
            # BytesEntries will be processed as children of the above.

        BLOCK_START_ENTRIES = ["MARK_PUSH", "IO_START", "BINDER_START"]
        BLOCK_END_ENTRIES = ["MARK_POP", "IO_END", "BINDER_END"]

        THREAD_METADATA_ENTRIES = ["TRACE_THREAD_NAME", "TRACE_THREAD_PRI"]

        for tid, items in thread_items.items():
            entries = list(sorted(items, key=cmp_to_key(entry_compare)))
            unit = self.ensure_unit(tid)

            stacks = {}  # timestamp -> [addresses]

            # First, build blocks.
            for entry in entries:
                block = None
                if entry.type in BLOCK_START_ENTRIES:
                    block = unit.push_block(entry.timestamp)
                    self.block_entries.setdefault(block, BlockEntries()).begin = entry
                elif entry.type in BLOCK_END_ENTRIES:
                    block = unit.pop_block(entry.timestamp)
                    self.block_entries.setdefault(block, BlockEntries()).end = entry
                elif entry.type == "STACK_FRAME":
                    # While we're here, build the stack trace maps.
                    stacks.setdefault(entry.timestamp, []).append(entry.arg3)
                elif entry.type in THREAD_METADATA_ENTRIES:
                    self.process_thread_metadata(entry)

                if block:
                    block_entries = self.block_entries[block]
                    self.assign_name(
                        block,
                        entries=[
                            block_entries.begin,
                            block_entries.end,
                        ],
                    )

            unit.normalize_blocks()

            """Attach single points. We can't do this as part of the
            block-building pass due to this edge case of unbalanced pops:

            PUSH(1)  POP(2)  COUNTER(3)  POP(4)

            We want this to create the following:
            [        (3) (4)]
            [(1) (2)]

            This is impossible to achieve in a single pass because we can't
            create the block ending in (4) at the time we visit (3).
            """
            for entry in entries:
                if entry.type == "COUNTER":
                    item = unit.add_point(entry.timestamp)
                    item.properties.add_counter(
                        name=COUNTER_NAMES[entry.arg1],
                        value=entry.arg3,
                    )

                    self.assign_name(item, entries=[entry])
                elif entry.type == "STACK_FRAME":
                    if entry.timestamp in stacks:
                        # we haven't written this stack trace yet, proceed
                        item = unit.add_point(entry.timestamp)
                        self.assign_name(item, entries=[entry])
                        stacktrace = StackTrace()
                        for frame in stacks[entry.timestamp]:
                            symbol = None
                            if self.symbols:
                                symbol = self.symbols.method_index.get(frame, None)
                                if symbol is None:
                                    # Let's see if it's a framework frame
                                    symbol = framework_frames.get(frame, None)
                            stacktrace.append(identifier=frame, symbol=symbol)

                        item.properties.stackTraces.update(
                            {
                                "stacks": stacktrace,
                            }
                        )

                        # clear the entry in the map so we don't add a point
                        # for every frame
                        del stacks[entry.timestamp]
                        pass

        return self.trace