regex-instance: HalInterface: add regex API and hide public fields

<regex-instance> is added under an <interface> tag,
which is represented by an HalInterface object. Add
API for looping over all <regex-instance>s / <instance>s
under it.

With this API, HalInterface can hide its public fields.

Bug: 73738616
Test: libvintf_test
Test: vintf_object_test
Test: vts_treble_vintf_test

Change-Id: Ia072dd7e946c28789797db8a46fd968bc7872dca
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 38a09b4..3d67e1c 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -473,22 +473,24 @@
 struct HalInterfaceConverter : public XmlNodeConverter<HalInterface> {
     std::string elementName() const override { return "interface"; }
     void mutateNode(const HalInterface &intf, NodeType *root, DocType *d) const override {
-        appendTextElement(root, "name", intf.name, d);
-        appendTextElements(root, "instance", intf.instances, d);
+        appendTextElement(root, "name", intf.name(), d);
+        appendTextElements(root, "instance", intf.mInstances, d);
     }
     bool buildObject(HalInterface* intf, NodeType* root, std::string* error) const override {
         std::vector<std::string> instances;
-        if (!parseTextElement(root, "name", &intf->name, error) ||
+        if (!parseTextElement(root, "name", &intf->mName, error) ||
             !parseTextElements(root, "instance", &instances, error)) {
             return false;
         }
-        intf->instances.clear();
-        intf->instances.insert(instances.begin(), instances.end());
-        if (intf->instances.size() != instances.size()) {
-            *error = "Duplicated instances in " + intf->name;
-            return false;
+        bool success = true;
+        for (const auto& e : instances) {
+            if (!intf->insertInstance(e, false /* isRegex */)) {
+                if (!error->empty()) *error += "\n";
+                *error += "Duplicated instance '" + e + "' in " + intf->name();
+                success = false;
+            }
         }
-        return true;
+        return success;
     }
 };
 
@@ -514,7 +516,7 @@
             return false;
         }
         for (auto&& interface : interfaces) {
-            std::string name{interface.name};
+            std::string name{interface.name()};
             auto res = object->interfaces.emplace(std::move(name), std::move(interface));
             if (!res.second) {
                 *error = "Duplicated interface entry \"" + res.first->first +
@@ -663,8 +665,7 @@
 
         object->interfaces.clear();
         for (auto &&interface : interfaces) {
-            auto res = object->interfaces.emplace(interface.name,
-                                                  std::move(interface));
+            auto res = object->interfaces.emplace(interface.name(), std::move(interface));
             if (!res.second) {
                 *error = "Duplicated interface entry \"" + res.first->first +
                          "\"; if additional instances are needed, add them to the "