Emit toString functions for all types.

* toString() is mainly for debugging purposes only.

* For HIDL internal types (hidl_string, hidl_vec, etc.)
  toString() is found in ::android::hardware::details.

* For a user defined type
  android.hardware.foo@1.0::IFoo.Type,
  toString() is found in ::android::hardware::foo::V1_0.

* For bitfield<::anroid::hardware::foo::V1_0::T>
  that gets translated to the underlying
  numeric type of T, it doesn't make sense to override toString().
  A templated toString() function for each user-defined HIDL enum \
  is introduced into the same namespace; call it with
    using namespace ::android::hardware::foo::V1_0;
    toString<IFoo::MyEnumType>(value);

Test: hidl_test and look at the output of logcat

Bug: 33459772

Change-Id: I70eee018e31d700bf1376334276dbd343af5615f
diff --git a/Interface.cpp b/Interface.cpp
index 9fd8954..9d7cc89 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -500,6 +500,53 @@
     }
 }
 
+status_t Interface::emitGlobalTypeDeclarations(Formatter &out) const {
+    status_t status = Scope::emitGlobalTypeDeclarations(out);
+    if (status != OK) {
+        return status;
+    }
+    out << "std::string toString("
+        << getCppArgumentType()
+        << ");\n";
+    return OK;
+}
+
+
+status_t Interface::emitTypeDefinitions(
+        Formatter &out, const std::string prefix) const {
+    std::string space = prefix.empty() ? "" : (prefix + "::");
+    status_t err = Scope::emitTypeDefinitions(out, space + localName());
+    if (err != OK) {
+        return err;
+    }
+
+    out << "std::string toString("
+        << getCppArgumentType()
+        << " o) ";
+
+    out.block([&] {
+        out << "std::string os;\nbool ok = false;\n";
+        // TODO b/34136228 use interfaceDescriptor instead
+        out << "auto ret = o->interfaceChain([&os, &ok] (const auto &chain) ";
+        out.block([&] {
+            out.sIf("chain.size() >= 1", [&] {
+                out << "os += chain[0].c_str();\n"
+                    << "ok = true;\n";
+            }).endl();
+        });
+        out << ");\n";
+        out.sIf("!ret.isOk() || !ok", [&] {
+            out << "os += \"[class or subclass of \";\n"
+                << "os += " << fullName() << "::descriptor;\n"
+                << "os += \"]\";\n";
+        }).endl();
+        out << "os += o->isRemote() ? \"@remote\" : \"@local\";\n"
+            << "return os;\n";
+    }).endl().endl();
+
+    return OK;
+}
+
 void Interface::emitJavaReaderWriter(
         Formatter &out,
         const std::string &parcelObj,