pseq: Parsing support for chassis_template element

Add JSON parsing support for the new chassis_template element in the
phosphor-power-sequencer configuration file.

Also move the type alias 'json = nlohmann::json' from
config_file_parse.cpp to config_file_parser.hpp. This simplifies the
function declarations and allows them to textually match the function
definitions.

Tested:
* Ran automated tests.

Change-Id: I666ae0a6382ffec6643d3e268117d006b6c4dd2a
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/phosphor-power-sequencer/src/config_file_parser.cpp b/phosphor-power-sequencer/src/config_file_parser.cpp
index 4539eb7..6d9b169 100644
--- a/phosphor-power-sequencer/src/config_file_parser.cpp
+++ b/phosphor-power-sequencer/src/config_file_parser.cpp
@@ -29,7 +29,6 @@
 
 using namespace phosphor::power::json_parser_utils;
 using ConfigFileParserError = phosphor::power::util::ConfigFileParserError;
-using json = nlohmann::json;
 namespace fs = std::filesystem;
 
 namespace phosphor::power::sequencer::config_file_parser
@@ -95,6 +94,44 @@
 namespace internal
 {
 
+std::tuple<std::string, JSONRefWrapper> parseChassisTemplate(
+    const json& element)
+{
+    verifyIsObject(element);
+    unsigned int propertyCount{0};
+
+    // Optional comments property; value not stored
+    if (element.contains("comments"))
+    {
+        ++propertyCount;
+    }
+
+    // Required id property
+    const json& idElement = getRequiredProperty(element, "id");
+    std::string id = parseString(idElement);
+    ++propertyCount;
+
+    // Required number property
+    // Just verify it exists; cannot be parsed without variable values
+    getRequiredProperty(element, "number");
+    ++propertyCount;
+
+    // Required inventory_path property
+    // Just verify it exists; cannot be parsed without variable values
+    getRequiredProperty(element, "inventory_path");
+    ++propertyCount;
+
+    // Required power_sequencers property
+    // Just verify it exists; cannot be parsed without variable values
+    getRequiredProperty(element, "power_sequencers");
+    ++propertyCount;
+
+    // Verify no invalid properties exist
+    verifyPropertyCount(element, propertyCount);
+
+    return {id, JSONRefWrapper{element}};
+}
+
 GPIO parseGPIO(const json& element,
                const std::map<std::string, std::string>& variables)
 {
diff --git a/phosphor-power-sequencer/src/config_file_parser.hpp b/phosphor-power-sequencer/src/config_file_parser.hpp
index fcae99a..b2a18ca 100644
--- a/phosphor-power-sequencer/src/config_file_parser.hpp
+++ b/phosphor-power-sequencer/src/config_file_parser.hpp
@@ -23,12 +23,15 @@
 
 #include <cstdint>
 #include <filesystem>
+#include <functional> // for reference_wrapper
 #include <map>
 #include <memory>
 #include <string>
 #include <tuple>
 #include <vector>
 
+using json = nlohmann::json;
+
 namespace phosphor::power::sequencer::config_file_parser
 {
 
@@ -80,6 +83,21 @@
 namespace internal
 {
 
+using JSONRefWrapper = std::reference_wrapper<const json>;
+
+/**
+ * Parses a JSON element containing a chassis_template object.
+ *
+ * Returns the template ID and a C++ reference_wrapper to the JSON element.
+ *
+ * Throws an exception if parsing fails.
+ *
+ * @param element JSON element
+ * @return template ID and reference_wrapper to JSON element
+ */
+std::tuple<std::string, JSONRefWrapper> parseChassisTemplate(
+    const json& element);
+
 /**
  * Parses a JSON element containing a GPIO.
  *
@@ -91,7 +109,7 @@
  * @param variables variables map used to expand variables in element value
  * @return GPIO object
  */
-GPIO parseGPIO(const nlohmann::json& element,
+GPIO parseGPIO(const json& element,
                const std::map<std::string, std::string>& variables);
 
 /**
@@ -106,8 +124,7 @@
  * @return tuple containing bus and address
  */
 std::tuple<uint8_t, uint16_t> parseI2CInterface(
-    const nlohmann::json& element,
-    const std::map<std::string, std::string>& variables);
+    const json& element, const std::map<std::string, std::string>& variables);
 
 /**
  * Parses a JSON element containing a power_sequencer object.
@@ -118,12 +135,12 @@
  *
  * @param element JSON element
  * @param variables variables map used to expand variables in element value
- * @param services System services like hardware presence and the journal
+ * @param services system services like hardware presence and the journal
  * @return PowerSequencerDevice object
  */
 std::unique_ptr<PowerSequencerDevice> parsePowerSequencer(
-    const nlohmann::json& element,
-    const std::map<std::string, std::string>& variables, Services& services);
+    const json& element, const std::map<std::string, std::string>& variables,
+    Services& services);
 
 /**
  * Parses a JSON element containing an array of power_sequencer objects.
@@ -134,12 +151,12 @@
  *
  * @param element JSON element
  * @param variables variables map used to expand variables in element value
- * @param services System services like hardware presence and the journal
+ * @param services system services like hardware presence and the journal
  * @return vector of PowerSequencerDevice objects
  */
 std::vector<std::unique_ptr<PowerSequencerDevice>> parsePowerSequencerArray(
-    const nlohmann::json& element,
-    const std::map<std::string, std::string>& variables, Services& services);
+    const json& element, const std::map<std::string, std::string>& variables,
+    Services& services);
 
 /**
  * Parses a JSON element containing a rail.
@@ -153,8 +170,7 @@
  * @return Rail object
  */
 std::unique_ptr<Rail> parseRail(
-    const nlohmann::json& element,
-    const std::map<std::string, std::string>& variables);
+    const json& element, const std::map<std::string, std::string>& variables);
 
 /**
  * Parses a JSON element containing an array of rails.
@@ -168,8 +184,7 @@
  * @return vector of Rail objects
  */
 std::vector<std::unique_ptr<Rail>> parseRailArray(
-    const nlohmann::json& element,
-    const std::map<std::string, std::string>& variables);
+    const json& element, const std::map<std::string, std::string>& variables);
 
 /**
  * Parses the JSON root element of the entire configuration file.
@@ -181,7 +196,7 @@
  * @param element JSON element
  * @return vector of Rail objects
  */
-std::vector<std::unique_ptr<Rail>> parseRoot(const nlohmann::json& element);
+std::vector<std::unique_ptr<Rail>> parseRoot(const json& element);
 
 } // namespace internal