Generate error messages source

This file has gotten desynced from the standard, and maintaining it is
a pain.  refactor the parse_registries.py script to generate this file
and update all wrong instances to the correct types.

To the extent possible, the generated code tries to be replaced with
1:1 identical structures to make review simpler.

Tested: On last patch in series.

Change-Id: Ic203a93fd26e0487475ce82c62beb6a22612368a
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index 91b565f..dffa2ca 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -1,18 +1,13 @@
-/*
-Copyright (c) 2018 Intel Corporation
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
+/****************************************************************
+ *                 READ THIS WARNING FIRST
+ * This is an auto-generated header which contains definitions
+ * for Redfish DMTF defined messages.
+ * DO NOT modify this registry outside of running the
+ * parse_registries.py script.  The definitions contained within
+ * this file are owned by DMTF.  Any modifications to these files
+ * should be first pushed to the relevant registry in the DMTF
+ * github organization.
+ ***************************************************************/
 #include "error_messages.hpp"
 
 #include "http_response.hpp"
@@ -33,6 +28,11 @@
 #include <string>
 #include <string_view>
 
+// Clang can't seem to decide whether this header needs to be included or not,
+// and is inconsistent.  Include it for now
+// NOLINTNEXTLINE(misc-include-cleaner)
+#include <utility>
+
 namespace redfish
 {
 
@@ -205,8 +205,8 @@
  */
 nlohmann::json resourceMissingAtURI(const boost::urls::url_view_base& arg1)
 {
-    std::array<std::string_view, 1> args{arg1.buffer()};
-    return getLog(redfish::registries::base::Index::resourceMissingAtURI, args);
+    return getLog(redfish::registries::base::Index::resourceMissingAtURI,
+                  std::to_array<std::string_view>({arg1.buffer()}));
 }
 
 void resourceMissingAtURI(crow::Response& res,
@@ -472,8 +472,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyValueFormatError message into JSON for the specified
- * property
+ * @brief Formats PropertyValueFormatError message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -496,13 +495,11 @@
 
 /**
  * @internal
- * @brief Formats PropertyValueNotInList message into JSON for the specified
- * property
+ * @brief Formats PropertyValueNotInList message into JSON
  *
  * See header file for more information
  * @endinternal
  */
-
 nlohmann::json propertyValueNotInList(const nlohmann::json& arg1,
                                       std::string_view arg2)
 {
@@ -650,9 +647,9 @@
  */
 nlohmann::json stringValueTooLong(std::string_view arg1, int arg2)
 {
-    std::string arg2String = std::to_string(arg2);
+    std::string arg2Str = std::to_string(arg2);
     return getLog(redfish::registries::base::Index::stringValueTooLong,
-                  std::to_array({arg1, std::string_view(arg2String)}));
+                  std::to_array<std::string_view>({arg1, arg2Str}));
 }
 
 void stringValueTooLong(crow::Response& res, std::string_view arg1, int arg2)
@@ -748,7 +745,7 @@
  */
 nlohmann::json chassisPowerStateOnRequired(std::string_view arg1)
 {
-    return getLog(redfish::registries::base::Index::resetRequired,
+    return getLog(redfish::registries::base::Index::chassisPowerStateOnRequired,
                   std::to_array({arg1}));
 }
 
@@ -812,7 +809,6 @@
 {
     std::string arg2Str =
         arg2.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
-
     return getLog(
         redfish::registries::base::Index::propertyValueResourceConflict,
         std::to_array<std::string_view>({arg1, arg2Str, arg3.buffer()}));
@@ -839,7 +835,6 @@
 {
     std::string arg2Str =
         arg2.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);
-
     return getLog(
         redfish::registries::base::Index::propertyValueExternalConflict,
         std::to_array<std::string_view>({arg1, arg2Str}));
@@ -988,8 +983,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyValueTypeError message into JSON for the specified
- * property
+ * @brief Formats PropertyValueTypeError message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1012,8 +1006,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyValueError message into JSON for the specified
- * property
+ * @brief Formats PropertyValueError message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1021,7 +1014,7 @@
 nlohmann::json propertyValueError(std::string_view arg1)
 {
     return getLog(redfish::registries::base::Index::propertyValueError,
-                  std::to_array<std::string_view>({arg1}));
+                  std::to_array({arg1}));
 }
 
 void propertyValueError(crow::Response& res, std::string_view arg1)
@@ -1032,7 +1025,7 @@
 
 /**
  * @internal
- * @brief Formats ResourceNotFound message into JSONd
+ * @brief Formats ResourceNotFound message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1073,8 +1066,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyNotWritable message into JSON for the specified
- * property
+ * @brief Formats PropertyNotWritable message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1326,8 +1318,6 @@
 
 void success(crow::Response& res)
 {
-    // don't set res.result here because success is the default and any
-    // error should overwrite the default
     addMessageToJsonRoot(res.jsonValue, success());
 }
 
@@ -1369,8 +1359,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyUnknown message into JSON for the specified
- * property
+ * @brief Formats PropertyUnknown message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1470,7 +1459,7 @@
 
 /**
  * @internal
- * @brief Formats actionParameterValueError message into JSON
+ * @brief Formats ActionParameterValueError message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1727,8 +1716,7 @@
 
 /**
  * @internal
- * @brief Formats PropertyMissing message into JSON for the specified
- * property
+ * @brief Formats PropertyMissing message into JSON
  *
  * See header file for more information
  * @endinternal
@@ -1804,12 +1792,6 @@
                           queryParameterOutOfRange(arg1, arg2, arg3));
 }
 
-nlohmann::json passwordChangeRequired(const boost::urls::url_view_base& arg1)
-{
-    return getLog(redfish::registries::base::Index::passwordChangeRequired,
-                  std::to_array<std::string_view>({arg1.buffer()}));
-}
-
 /**
  * @internal
  * @brief Formats PasswordChangeRequired message into JSON
@@ -1817,10 +1799,16 @@
  * See header file for more information
  * @endinternal
  */
+nlohmann::json passwordChangeRequired(const boost::urls::url_view_base& arg1)
+{
+    return getLog(redfish::registries::base::Index::passwordChangeRequired,
+                  std::to_array<std::string_view>({arg1.buffer()}));
+}
+
 void passwordChangeRequired(crow::Response& res,
                             const boost::urls::url_view_base& arg1)
 {
-    messages::addMessageToJsonRoot(res.jsonValue, passwordChangeRequired(arg1));
+    addMessageToJsonRoot(res.jsonValue, passwordChangeRequired(arg1));
 }
 
 /**
@@ -1879,12 +1867,6 @@
     addMessageToErrorJson(res.jsonValue, arraySizeTooLong(arg1, arg2));
 }
 
-nlohmann::json generateSecretKeyRequired(const boost::urls::url_view_base& arg1)
-{
-    return getLog(redfish::registries::base::Index::generateSecretKeyRequired,
-                  std::to_array<std::string_view>({arg1.buffer()}));
-}
-
 /**
  * @internal
  * @brief Formats GenerateSecretKeyRequired message into JSON
@@ -1892,13 +1874,563 @@
  * See header file for more information
  * @endinternal
  */
+nlohmann::json generateSecretKeyRequired(const boost::urls::url_view_base& arg1)
+{
+    return getLog(redfish::registries::base::Index::generateSecretKeyRequired,
+                  std::to_array<std::string_view>({arg1.buffer()}));
+}
+
 void generateSecretKeyRequired(crow::Response& res,
                                const boost::urls::url_view_base& arg1)
 {
-    messages::addMessageToJsonRoot(res.jsonValue,
-                                   generateSecretKeyRequired(arg1));
+    res.result(boost::beast::http::status::forbidden);
+    addMessageToErrorJson(res.jsonValue, generateSecretKeyRequired(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PropertyNotUpdated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyNotUpdated(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::propertyNotUpdated,
+                  std::to_array({arg1}));
+}
+
+void propertyNotUpdated(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, propertyNotUpdated(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats InvalidJSON message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json invalidJSON(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::invalidJSON,
+                  std::to_array({arg1}));
+}
+
+void invalidJSON(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, invalidJSON(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats ActionParameterValueOutOfRange message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json actionParameterValueOutOfRange(
+    std::string_view arg1, std::string_view arg2, std::string_view arg3)
+{
+    return getLog(
+        redfish::registries::base::Index::actionParameterValueOutOfRange,
+        std::to_array({arg1, arg2, arg3}));
+}
+
+void actionParameterValueOutOfRange(crow::Response& res, std::string_view arg1,
+                                    std::string_view arg2,
+                                    std::string_view arg3)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue,
+                          actionParameterValueOutOfRange(arg1, arg2, arg3));
+}
+
+/**
+ * @internal
+ * @brief Formats ArraySizeTooShort message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json arraySizeTooShort(std::string_view arg1, std::string_view arg2)
+{
+    return getLog(redfish::registries::base::Index::arraySizeTooShort,
+                  std::to_array({arg1, arg2}));
+}
+
+void arraySizeTooShort(crow::Response& res, std::string_view arg1,
+                       std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, arraySizeTooShort(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats QueryParameterValueError message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json queryParameterValueError(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::queryParameterValueError,
+                  std::to_array({arg1}));
+}
+
+void queryParameterValueError(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, queryParameterValueError(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats QueryParameterUnsupported message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json queryParameterUnsupported(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::queryParameterUnsupported,
+                  std::to_array({arg1}));
+}
+
+void queryParameterUnsupported(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, queryParameterUnsupported(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PayloadTooLarge message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json payloadTooLarge()
+{
+    return getLog(redfish::registries::base::Index::payloadTooLarge, {});
+}
+
+void payloadTooLarge(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, payloadTooLarge());
+}
+
+/**
+ * @internal
+ * @brief Formats MissingOrMalformedPart message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json missingOrMalformedPart()
+{
+    return getLog(redfish::registries::base::Index::missingOrMalformedPart, {});
+}
+
+void missingOrMalformedPart(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, missingOrMalformedPart());
+}
+
+/**
+ * @internal
+ * @brief Formats InvalidURI message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json invalidURI(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::invalidURI,
+                  std::to_array({arg1}));
+}
+
+void invalidURI(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, invalidURI(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats StringValueTooShort message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json stringValueTooShort(std::string_view arg1, std::string_view arg2)
+{
+    return getLog(redfish::registries::base::Index::stringValueTooShort,
+                  std::to_array({arg1, arg2}));
+}
+
+void stringValueTooShort(crow::Response& res, std::string_view arg1,
+                         std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, stringValueTooShort(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats ResetRecommended message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json resetRecommended(std::string_view arg1, std::string_view arg2)
+{
+    return getLog(redfish::registries::base::Index::resetRecommended,
+                  std::to_array({arg1, arg2}));
+}
+
+void resetRecommended(crow::Response& res, std::string_view arg1,
+                      std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, resetRecommended(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats ActionParameterValueConflict message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json
+    actionParameterValueConflict(std::string_view arg1, std::string_view arg2)
+{
+    return getLog(
+        redfish::registries::base::Index::actionParameterValueConflict,
+        std::to_array({arg1, arg2}));
+}
+
+void actionParameterValueConflict(crow::Response& res, std::string_view arg1,
+                                  std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue,
+                          actionParameterValueConflict(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats HeaderMissing message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json headerMissing(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::headerMissing,
+                  std::to_array({arg1}));
+}
+
+void headerMissing(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, headerMissing(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats HeaderInvalid message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json headerInvalid(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::headerInvalid,
+                  std::to_array({arg1}));
+}
+
+void headerInvalid(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, headerInvalid(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats UndeterminedFault message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json undeterminedFault(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::undeterminedFault,
+                  std::to_array({arg1}));
+}
+
+void undeterminedFault(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, undeterminedFault(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats ConditionInRelatedResource message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json conditionInRelatedResource()
+{
+    return getLog(redfish::registries::base::Index::conditionInRelatedResource,
+                  {});
+}
+
+void conditionInRelatedResource(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, conditionInRelatedResource());
+}
+
+/**
+ * @internal
+ * @brief Formats RestrictedRole message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json restrictedRole(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::restrictedRole,
+                  std::to_array({arg1}));
+}
+
+void restrictedRole(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, restrictedRole(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats RestrictedPrivilege message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json restrictedPrivilege(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::restrictedPrivilege,
+                  std::to_array({arg1}));
+}
+
+void restrictedPrivilege(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, restrictedPrivilege(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PropertyDeprecated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyDeprecated(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::propertyDeprecated,
+                  std::to_array({arg1}));
+}
+
+void propertyDeprecated(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, propertyDeprecated(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats ResourceDeprecated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json resourceDeprecated(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::resourceDeprecated,
+                  std::to_array({arg1}));
+}
+
+void resourceDeprecated(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, resourceDeprecated(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PropertyValueDeprecated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyValueDeprecated(std::string_view arg1,
+                                       std::string_view arg2)
+{
+    return getLog(redfish::registries::base::Index::propertyValueDeprecated,
+                  std::to_array({arg1, arg2}));
+}
+
+void propertyValueDeprecated(crow::Response& res, std::string_view arg1,
+                             std::string_view arg2)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, propertyValueDeprecated(arg1, arg2));
+}
+
+/**
+ * @internal
+ * @brief Formats ActionDeprecated message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json actionDeprecated(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::actionDeprecated,
+                  std::to_array({arg1}));
+}
+
+void actionDeprecated(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, actionDeprecated(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats NetworkNameResolutionNotConfigured message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json networkNameResolutionNotConfigured()
+{
+    return getLog(
+        redfish::registries::base::Index::networkNameResolutionNotConfigured,
+        {});
+}
+
+void networkNameResolutionNotConfigured(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, networkNameResolutionNotConfigured());
+}
+
+/**
+ * @internal
+ * @brief Formats NetworkNameResolutionNotSupported message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json networkNameResolutionNotSupported()
+{
+    return getLog(
+        redfish::registries::base::Index::networkNameResolutionNotSupported,
+        {});
+}
+
+void networkNameResolutionNotSupported(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, networkNameResolutionNotSupported());
+}
+
+/**
+ * @internal
+ * @brief Formats AuthenticationTokenRequired message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json authenticationTokenRequired()
+{
+    return getLog(redfish::registries::base::Index::authenticationTokenRequired,
+                  {});
+}
+
+void authenticationTokenRequired(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, authenticationTokenRequired());
+}
+
+/**
+ * @internal
+ * @brief Formats OneTimePasscodeSent message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json oneTimePasscodeSent(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::oneTimePasscodeSent,
+                  std::to_array({arg1}));
+}
+
+void oneTimePasscodeSent(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, oneTimePasscodeSent(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats LicenseRequired message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json licenseRequired(std::string_view arg1)
+{
+    return getLog(redfish::registries::base::Index::licenseRequired,
+                  std::to_array({arg1}));
+}
+
+void licenseRequired(crow::Response& res, std::string_view arg1)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, licenseRequired(arg1));
+}
+
+/**
+ * @internal
+ * @brief Formats PropertyModified message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+nlohmann::json propertyModified()
+{
+    return getLog(redfish::registries::base::Index::propertyModified, {});
+}
+
+void propertyModified(crow::Response& res)
+{
+    res.result(boost::beast::http::status::bad_request);
+    addMessageToErrorJson(res.jsonValue, propertyModified());
 }
 
 } // namespace messages
-
 } // namespace redfish
diff --git a/scripts/parse_registries.py b/scripts/parse_registries.py
index 194f134..573f8a7 100755
--- a/scripts/parse_registries.py
+++ b/scripts/parse_registries.py
@@ -188,6 +188,54 @@
 )
 
 
+def get_response_code(entry_id, entry):
+    codes = {
+        "InternalError": "internal_server_error",
+        "OperationTimeout": "internal_server_error",
+        "PropertyValueResourceConflict": "conflict",
+        "ResourceInUse": "service_unavailable",
+        "ServiceTemporarilyUnavailable": "service_unavailable",
+        "ResourceCannotBeDeleted": "method_not_allowed",
+        "PropertyValueModified": "ok",
+        "InsufficientPrivilege": "forbidden",
+        "AccountForSessionNoLongerExists": "forbidden",
+        "ServiceDisabled": "service_unavailable",
+        "ServiceInUnknownState": "service_unavailable",
+        "EventSubscriptionLimitExceeded": "service_unavailable",
+        "ResourceAtUriUnauthorized": "unauthorized",
+        "SessionTerminated": "ok",
+        "SubscriptionTerminated": "ok",
+        "PropertyNotWritable": "forbidden",
+        "MaximumErrorsExceeded": "internal_server_error",
+        "GeneralError": "internal_server_error",
+        "PreconditionFailed": "precondition_failed",
+        "OperationFailed": "bad_gateway",
+        "ServiceShuttingDown": "service_unavailable",
+        "AccountRemoved": "ok",
+        "PropertyValueExternalConflict": "conflict",
+        "InsufficientStorage": "insufficient_storage",
+        "OperationNotAllowed": "method_not_allowed",
+        "ResourceNotFound": "not_found",
+        "CouldNotEstablishConnection": "not_found",
+        "AccessDenied": "forbidden",
+        "Success": None,
+        "Created": "created",
+        "NoValidSession": "forbidden",
+        "SessionLimitExceeded": "service_unavailable",
+        "ResourceExhaustion": "service_unavailable",
+        "AccountModified": "ok",
+        "PasswordChangeRequired": None,
+        "ResourceInStandby": "service_unavailable",
+        "GenerateSecretKeyRequired": "forbidden",
+    }
+
+    code = codes.get(entry_id, "NOCODE")
+    if code != "NOCODE":
+        return code
+
+    return "bad_request"
+
+
 def get_old_index(entry):
     old_order = [
         "ResourceInUse",
@@ -285,7 +333,7 @@
         return 999999
 
 
-def create_error_registry(entry):
+def make_error_function(entry_id, entry, is_header):
 
     arg_as_url = {
         "AccessDenied": [1],
@@ -329,6 +377,128 @@
         "InvalidIndex": [1],
     }
 
+    out = ""
+    args = []
+    argtypes = []
+    for arg_index, arg in enumerate(entry.get("ParamTypes", [])):
+        arg_index += 1
+        if arg_index in arg_as_url.get(entry_id, []):
+            typename = "const boost::urls::url_view_base&"
+        elif arg_index in arg_as_json.get(entry_id, []):
+            typename = "const nlohmann::json&"
+        elif arg_index in arg_as_int.get(entry_id, []):
+            typename = "int"
+        elif arg_index in arg_as_uint64.get(entry_id, []):
+            typename = "uint64_t"
+        elif arg_index in arg_as_int64.get(entry_id, []):
+            typename = "int64_t"
+        else:
+            typename = "std::string_view"
+        argtypes.append(typename)
+        args.append(f"{typename} arg{arg_index}")
+    function_name = entry_id[0].lower() + entry_id[1:]
+    arg = ", ".join(args)
+    out += f"nlohmann::json {function_name}({arg})"
+
+    if is_header:
+        out += ";\n\n"
+    else:
+        out += "\n{\n"
+        to_array_type = ""
+        if argtypes:
+            outargs = []
+            for index, typename in enumerate(argtypes):
+                index += 1
+                if typename == "const nlohmann::json&":
+                    out += f"std::string arg{index}Str = arg{index}.dump(-1, ' ', true, nlohmann::json::error_handler_t::replace);\n"
+                elif typename in ("int64_t", "int", "uint64_t"):
+                    out += f"std::string arg{index}Str = std::to_string(arg{index});\n"
+
+            for index, typename in enumerate(argtypes):
+                index += 1
+                if typename == "const boost::urls::url_view_base&":
+                    outargs.append(f"arg{index}.buffer()")
+                    to_array_type = "<std::string_view>"
+                elif typename == "const nlohmann::json&":
+                    outargs.append(f"arg{index}Str")
+                    to_array_type = "<std::string_view>"
+                elif typename in ("int64_t", "int", "uint64_t"):
+                    outargs.append(f"arg{index}Str")
+                    to_array_type = "<std::string_view>"
+                else:
+                    outargs.append(f"arg{index}")
+            argstring = ", ".join(outargs)
+            # out += f"    std::array<std::string_view, {len(argtypes)}> args{{{argstring}}};\n"
+
+        if argtypes:
+            arg_param = f"std::to_array{to_array_type}({{{argstring}}})"
+        else:
+            arg_param = "{}"
+        out += f"    return getLog(redfish::registries::base::Index::{function_name}, {arg_param});"
+        out += "\n}\n\n"
+    args.insert(0, "crow::Response& res")
+    if entry_id == "InternalError":
+        if is_header:
+            args.append(
+                "std::source_location location = std::source_location::current()"
+            )
+        else:
+            args.append("const std::source_location location")
+    arg = ", ".join(args)
+    out += f"void {function_name}({arg})"
+    if is_header:
+        out += ";\n"
+    else:
+        out += "\n{\n"
+        if entry_id == "InternalError":
+            out += """BMCWEB_LOG_CRITICAL("Internal Error {}({}:{}) `{}`: ", location.file_name(),
+                        location.line(), location.column(),
+                        location.function_name());\n"""
+
+        if entry_id == "ServiceTemporarilyUnavailable":
+            out += (
+                "res.addHeader(boost::beast::http::field::retry_after, arg1);"
+            )
+
+        res = get_response_code(entry_id, entry)
+        if res:
+            out += f"    res.result(boost::beast::http::status::{res});\n"
+        args_out = ", ".join([f"arg{x+1}" for x in range(len(argtypes))])
+
+        addMessageToJson = {
+            "PropertyDuplicate": 1,
+            "ResourceAlreadyExists": 2,
+            "CreateFailedMissingReqProperties": 1,
+            "PropertyValueFormatError": 2,
+            "PropertyValueNotInList": 2,
+            "PropertyValueTypeError": 2,
+            "PropertyValueError": 1,
+            "PropertyNotWritable": 1,
+            "PropertyValueModified": 1,
+            "PropertyMissing": 1,
+        }
+
+        addMessageToRoot = [
+            "SessionTerminated",
+            "SubscriptionTerminated",
+            "AccountRemoved",
+            "Created",
+            "Success",
+            "PasswordChangeRequired",
+        ]
+
+        if entry_id in addMessageToJson:
+            out += f"    addMessageToJson(res.jsonValue, {function_name}({args_out}), arg{addMessageToJson[entry_id]});\n"
+        elif entry_id in addMessageToRoot:
+            out += f"    addMessageToJsonRoot(res.jsonValue, {function_name}({args_out}));\n"
+        else:
+            out += f"    addMessageToErrorJson(res.jsonValue, {function_name}({args_out}));\n"
+        out += "}\n"
+    out += "\n"
+    return out
+
+
+def create_error_registry(entry):
     file, json_dict, namespace, url = entry
 
     messages = OrderedDict(
@@ -396,35 +566,191 @@
             out.write("*\n")
             out.write(f"* @returns Message {entry_id} formatted to JSON */\n")
 
-            args = []
-            for arg_index, arg in enumerate(entry.get("ParamTypes", [])):
-                arg_index += 1
-                if arg_index in arg_as_url.get(entry_id, []):
-                    typename = "const boost::urls::url_view_base&"
-                elif arg_index in arg_as_json.get(entry_id, []):
-                    typename = "const nlohmann::json&"
-                elif arg_index in arg_as_int.get(entry_id, []):
-                    typename = "int"
-                elif arg_index in arg_as_uint64.get(entry_id, []):
-                    typename = "uint64_t"
-                elif arg_index in arg_as_int64.get(entry_id, []):
-                    typename = "int64_t"
-                else:
-                    typename = "std::string_view"
-                args.append(f"{typename} arg{arg_index}")
-            function_name = entry_id[0].lower() + entry_id[1:]
-            arg = ", ".join(args)
-            out.write(f"nlohmann::json {function_name}({arg});\n\n")
-            args.insert(0, "crow::Response& res")
-            if entry_id == "InternalError":
-                args.append(
-                    "std::source_location location = std::source_location::current()"
-                )
-            arg = ", ".join(args)
-            out.write(f"void {function_name}({arg});\n\n")
+            out.write(make_error_function(entry_id, entry, True))
         out.write("    }\n")
         out.write("}\n")
-    os.system(f"clang-format -i {error_messages_hpp}")
+
+    error_messages_cpp = os.path.join(
+        SCRIPT_DIR, "..", "redfish-core", "src", "error_messages.cpp"
+    )
+    with open(
+        error_messages_cpp,
+        "w",
+    ) as out:
+        out.write(WARNING)
+        out.write(
+            """
+#include "error_messages.hpp"
+
+#include "http_response.hpp"
+#include "logging.hpp"
+#include "registries.hpp"
+#include "registries/base_message_registry.hpp"
+
+#include <boost/beast/http/field.hpp>
+#include <boost/beast/http/status.hpp>
+#include <boost/url/url_view_base.hpp>
+#include <nlohmann/json.hpp>
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <source_location>
+#include <span>
+#include <string>
+#include <string_view>
+
+// Clang can't seem to decide whether this header needs to be included or not,
+// and is inconsistent.  Include it for now
+// NOLINTNEXTLINE(misc-include-cleaner)
+#include <utility>
+
+namespace redfish
+{
+
+namespace messages
+{
+
+static void addMessageToErrorJson(nlohmann::json& target,
+                                  const nlohmann::json& message)
+{
+    auto& error = target["error"];
+
+    // If this is the first error message, fill in the information from the
+    // first error message to the top level struct
+    if (!error.is_object())
+    {
+        auto messageIdIterator = message.find("MessageId");
+        if (messageIdIterator == message.end())
+        {
+            BMCWEB_LOG_CRITICAL(
+                "Attempt to add error message without MessageId");
+            return;
+        }
+
+        auto messageFieldIterator = message.find("Message");
+        if (messageFieldIterator == message.end())
+        {
+            BMCWEB_LOG_CRITICAL("Attempt to add error message without Message");
+            return;
+        }
+        error["code"] = *messageIdIterator;
+        error["message"] = *messageFieldIterator;
+    }
+    else
+    {
+        // More than 1 error occurred, so the message has to be generic
+        error["code"] = std::string(messageVersionPrefix) + "GeneralError";
+        error["message"] = "A general error has occurred. See Resolution for "
+                           "information on how to resolve the error.";
+    }
+
+    // This check could technically be done in the default construction
+    // branch above, but because we need the pointer to the extended info field
+    // anyway, it's more efficient to do it here.
+    auto& extendedInfo = error[messages::messageAnnotation];
+    if (!extendedInfo.is_array())
+    {
+        extendedInfo = nlohmann::json::array();
+    }
+
+    extendedInfo.push_back(message);
+}
+
+void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source)
+{
+    if (!source.is_object())
+    {
+        return;
+    }
+    auto errorIt = source.find("error");
+    if (errorIt == source.end())
+    {
+        // caller puts error message in root
+        messages::addMessageToErrorJson(target, source);
+        source.clear();
+        return;
+    }
+    auto extendedInfoIt = errorIt->find(messages::messageAnnotation);
+    if (extendedInfoIt == errorIt->end())
+    {
+        return;
+    }
+    const nlohmann::json::array_t* extendedInfo =
+        (*extendedInfoIt).get_ptr<const nlohmann::json::array_t*>();
+    if (extendedInfo == nullptr)
+    {
+        source.erase(errorIt);
+        return;
+    }
+    for (const nlohmann::json& message : *extendedInfo)
+    {
+        addMessageToErrorJson(target, message);
+    }
+    source.erase(errorIt);
+}
+
+static void addMessageToJsonRoot(nlohmann::json& target,
+                                 const nlohmann::json& message)
+{
+    if (!target[messages::messageAnnotation].is_array())
+    {
+        // Force object to be an array
+        target[messages::messageAnnotation] = nlohmann::json::array();
+    }
+
+    target[messages::messageAnnotation].push_back(message);
+}
+
+static void addMessageToJson(nlohmann::json& target,
+                             const nlohmann::json& message,
+                             std::string_view fieldPath)
+{
+    std::string extendedInfo(fieldPath);
+    extendedInfo += messages::messageAnnotation;
+
+    nlohmann::json& field = target[extendedInfo];
+    if (!field.is_array())
+    {
+        // Force object to be an array
+        field = nlohmann::json::array();
+    }
+
+    // Object exists and it is an array so we can just push in the message
+    field.push_back(message);
+}
+
+static nlohmann::json getLog(redfish::registries::base::Index name,
+                             std::span<const std::string_view> args)
+{
+    size_t index = static_cast<size_t>(name);
+    if (index >= redfish::registries::base::registry.size())
+    {
+        return {};
+    }
+    return getLogFromRegistry(redfish::registries::base::header,
+                              redfish::registries::base::registry, index, args);
+}
+
+"""
+        )
+        for entry_id, entry in messages.items():
+            out.write(
+                f"""/**
+ * @internal
+ * @brief Formats {entry_id} message into JSON
+ *
+ * See header file for more information
+ * @endinternal
+ */
+"""
+            )
+            message = entry["Message"]
+            out.write(make_error_function(entry_id, entry, False))
+
+        out.write("    }\n")
+        out.write("}\n")
+    os.system(f"clang-format -i {error_messages_hpp} {error_messages_cpp}")
 
 
 def make_privilege_registry():