1# Formatters for classes that derive from Message.
2#
3# Usage:
4#   command script import ./example.py
5#   type summary add --expand --recognizer-function --python-function example.message_summary example.is_message_type
6#   type synth add --recognizer-function --python-class example.MessageChildProvider example.is_message_type
7
8import sys
9
10def is_message_type(t, internal_dict):
11  for base in t.get_bases_array():
12    if base.GetName() == "Message":
13      return True
14  return False
15
16def message_summary(value, internal_dict):
17  # Could have used a summary string as well. All the work is done by the child
18  # provider.
19  return "Message"
20
21class MessageChildProvider:
22  def __init__(self, value, internal_dict):
23    self.value = value
24    self.synthetic_children = self._analyze_children(value)
25
26  def has_children(self):
27    return self.num_children() > 0
28
29  def num_children(self):
30    return len(self.synthetic_children)
31
32  def get_child_index(self, name):
33    for index, child in enumerate(self.synthetic_children):
34      if child.GetName() == name:
35        return index
36    return None
37
38  def get_child_at_index(self, index):
39    return self.synthetic_children[index]
40
41  def _rename_sbvalue(self, value):
42    # We want to display the field with its original name without a trailing
43    # underscore. So we create a new SBValue with the same type and address but
44    # a different name.
45    name = value.GetName()
46    assert name.endswith("_")
47    new_name = name[:-1]
48    return value.CreateValueFromAddress(new_name, value.GetLoadAddress(),
49                                        value.GetType())
50
51  def _analyze_children(self, value):
52    result = []
53    for i in range(value.GetNumChildren()):
54      child = value.GetChildAtIndex(i)
55      child_name = child.GetName()
56      if child_name.startswith("_"):
57        continue  # Internal field, skip
58      # Normal field. Check presence bit.
59      presence_bit = value.GetChildMemberWithName("_has_" + child_name)
60      if presence_bit.GetValueAsUnsigned() != 0:
61        result.append(self._rename_sbvalue(child))
62    return result
63
64