pw_snapshot: Add reason token in snapshot report

Extracts the tokenized value of the "Reason" string in a snapshot to
make it easier to associate a snapshot with a given tokenized string.

Requires: pigweed-internal:32420
Change-Id: I363259d8fc66a3898a68db1131a509e754600e04
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/105043
Reviewed-by: Rob Mohr <mohrr@google.com>
Commit-Queue: Armando Montanez <amontanez@google.com>
diff --git a/pw_snapshot/py/metadata_test.py b/pw_snapshot/py/metadata_test.py
index 3152833..3a0f28a 100644
--- a/pw_snapshot/py/metadata_test.py
+++ b/pw_snapshot/py/metadata_test.py
@@ -86,6 +86,7 @@
             'Snapshot capture reason:',
             '    Assert failed: 1+1 == 42',
             '',
+            'Reason token:      0x3a9bc4c3',
             'Project name:      gShoe',
             'Device:            hyper-fast-gshoe',
             'Device FW version: gShoe-debug-1.2.1-6f23412b+',
@@ -106,6 +107,7 @@
             'Device crash cause:',
             '    Assert failed: 1+1 == 42',
             '',
+            'Reason token:      0x3a9bc4c3',
             'Project name:      gShoe',
             'Device:            hyper-fast-gshoe',
             'Device FW version: gShoe-debug-1.2.1-6f23412b+',
@@ -137,6 +139,7 @@
             'Snapshot capture reason:',
             '    Assert failed: 1+1 == 42',
             '',
+            'Reason token:      0x3a9bc4c3',
             'Project name:      gShoe',
             'Device:            hyper-fast-gshoe',
             'Device FW version: gShoe-debug-1.2.1-6f23412b+',
diff --git a/pw_snapshot/py/pw_snapshot_metadata/metadata.py b/pw_snapshot/py/pw_snapshot_metadata/metadata.py
index ea39380..2d471f3 100644
--- a/pw_snapshot/py/pw_snapshot_metadata/metadata.py
+++ b/pw_snapshot/py/pw_snapshot_metadata/metadata.py
@@ -65,6 +65,8 @@
         self._metadata = metadata
         self._tokenizer_db = (tokenizer_db if tokenizer_db is not None else
                               pw_tokenizer.Detokenizer(None))
+        self._reason_token = self._tokenizer_db.detokenize(
+            metadata.reason).token
         self._format_width = _PRETTY_FORMAT_DEFAULT_WIDTH
         proto_detokenizer.detokenize_fields(self._tokenizer_db, self._metadata)
 
@@ -80,6 +82,10 @@
 
         return f'{log.file}: {log.message}' if log.file else log.message
 
+    def reason_token(self) -> Optional[int]:
+        """If the snapshot `reason` is tokenized, the value of the token."""
+        return self._reason_token
+
     def project_name(self) -> str:
         return self._metadata.project_name.decode()
 
@@ -119,6 +125,8 @@
             '    ' + self.reason(),
             '',
         ))
+        if self.reason_token():
+            output.append(f'Reason token:      0x{self.reason_token():x}')
 
         if self._metadata.project_name:
             output.append(f'Project name:      {self.project_name()}')