PEL: Print SRC section into JSON

For BMC created errors, look up the reason code in
the message registry for error description and also
meaning of data stored in hexwords 6-9 (if any).

Added registry message field in peltool list output.

"Primary SRC": {
    "Section Version":          "1",
    "Sub-section type":         "1",
    "Created by":               "0x1000",
    "SRC Version":              "0x02",
    "SRC Format":               "0x55",
    "Power Control Net Fault":  "False",
    "Error Details": {
        "Message":              "PS 0x64 had a PGOOD Fault",
        "PS_NUM":               "0x64"
    },
    "Valid Word Count":         "0x09",
    "Reference Code":           "BD8D1001",
    "Hex Word 2":               "00000055",
    "Hex Word 3":               "00000010",
    "Hex Word 4":               "00000000",
    "Hex Word 5":               "00000000",
    "Hex Word 6":               "00000064",
    "Hex Word 7":               "00000000",
    "Hex Word 8":               "00000000",
    "Hex Word 9":               "00000000"
}

"Primary SRC": {
    "Section Version":          "1",
    "Sub-section type":         "0",
    "Created by":               "0x4552",
    "SRC Version":              "0x02",
    "SRC Format":               "0x2008000",
    "Power Control Net Fault":  "False",
    "Valid Word Count":         "0x04",
    "Reference Code":           "B2001020",
    "Hex Word 2":               "02008000",
    "Hex Word 3":               "00000000",
    "Hex Word 4":               "00000012",
    "Callout Section": {
        "Callout Count":        "1",
        "Callouts": [{
            "FRU Type":         "Symbolic FRU",
            "Priority":         "Medium Priority",
            "Part Number":      "NEXTLVL"
        }]
    }
}

Testing: Manually run peltool and verified out. All unit tests passed.
Signed-off-by: Harisuddin Mohamed Isa <harisuddin@gmail.com>
Change-Id: I124627ba785413ebda02305b7d9f95431922e714
diff --git a/extensions/openpower-pels/registry.hpp b/extensions/openpower-pels/registry.hpp
index d75c30a..0a75d8e 100644
--- a/extensions/openpower-pels/registry.hpp
+++ b/extensions/openpower-pels/registry.hpp
@@ -13,6 +13,39 @@
 {
 
 constexpr auto registryFileName = "message_registry.json";
+enum class LookupType
+{
+    name = 0,
+    reasonCode = 1
+};
+
+/**
+ * @brief Represents the Documentation related fields in the message registry.
+ *        It is part of the 'Entry' structure that will be filled in when
+ *        an error is looked up in the registry.
+ *
+ * If a field is wrapped by std::optional, it means the field is
+ * optional in the JSON and higher level code knows how to handle it.
+ */
+struct DOC
+{
+    /**
+     * @brief Description of error
+     */
+    std::string description;
+
+    /**
+     * @brief Error message field
+     */
+    std::string message;
+
+    /**
+     * @brief An optional vector of SRC word 6-9 to use as the source of the
+     *        numeric arguments that will be substituted into any placeholder
+     *        in the Message field.
+     */
+    std::optional<std::vector<std::string>> messageArgSources;
+};
 
 /**
  * @brief Represents the SRC related fields in the message registry.
@@ -123,6 +156,11 @@
      * The SRC related fields.
      */
     SRC src;
+
+    /**
+     * The Documentation related fields.
+     */
+    DOC doc;
 };
 
 /**
@@ -155,24 +193,42 @@
     }
 
     /**
-     * @brief Find a registry entry based on its error name.
+     * @brief Find a registry entry based on its error name or reason code.
      *
      * This function does do some basic sanity checking on the JSON contents,
      * but there is also an external program that enforces a schema on the
      * registry JSON that should catch all of these problems ahead of time.
      *
      * @param[in] name - The error name, like xyz.openbmc_project.Error.Foo
-     *
+     *                 - OR
+     *                 - The reason code, like 0x1001
+     * @param[in] type - LookupType enum value
+     * @param[in] toCache - boolean to cache registry in memory
      * @return optional<Entry> A filled in message registry structure if
      *                         found, otherwise an empty optional object.
      */
-    std::optional<Entry> lookup(const std::string& name);
+    std::optional<Entry> lookup(const std::string& name, LookupType type,
+                                bool toCache = false);
 
   private:
     /**
+     * @brief Parse message registry file using nlohmann::json
+     * @param[in] registryFile - The message registry JSON file
+     * @return optional<nlohmann::json> The full message registry object or an
+     *                                  empty optional object upon failure.
+     */
+    std::optional<nlohmann::json>
+        readRegistry(const std::filesystem::path& registryFile);
+
+    /**
      * @brief The path to the registry JSON file.
      */
     std::filesystem::path _registryFile;
+
+    /**
+     * @brief The full message registry object.
+     */
+    std::optional<nlohmann::json> _registry;
 };
 
 namespace helper