parse_xml.cpp: Deserilization does not touch lastError()

The global mLastError fields for each converters can
potentially cause a segfault when a program with multiple
threads tries to deserialize a bad file at the same time.

- deserialization APIs that touches the mLastError field are
  marked as non-const APIs
- const variants are provided (error is provided as an output
  parameter)
- Functionalities are equivalent (tests ensure this).

Test: libvintf_test
Test: vintf_object_test
Fixes: 71874788

Change-Id: I416de909b32809a4ac377d9da998c48d7d409457
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 3f097f7..e89ca56 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -295,11 +295,9 @@
         }
 
         auto it = results.emplace(results.end());
-        if (!gCompatibilityMatrixConverter(&it->object, content)) {
+        if (!gCompatibilityMatrixConverter(&it->object, content, error)) {
             if (error) {
-                // TODO(b/71874788): do not use lastError() because it is not thread-safe.
-                *error +=
-                    "Ignore file " + path + ": " + gCompatibilityMatrixConverter.lastError() + "\n";
+                *error += "Ignore file " + path + ": " + *error + "\n";
             }
             results.erase(it);
             continue;
@@ -368,7 +366,7 @@
 static ParseStatus tryParse(const std::string &xml, const XmlConverter<T> &parse,
         std::shared_ptr<T> *fwk, std::shared_ptr<T> *dev) {
     std::shared_ptr<T> ret = std::make_shared<T>();
-    if (!parse(ret.get(), xml)) {
+    if (!parse(ret.get(), xml, nullptr /* error */)) {
         return ParseStatus::PARSE_ERROR;
     }
     if (ret->type() == SchemaType::FRAMEWORK) {