c++-impl: remove version from namespace

When people explicitly specify versions in their interfaces, it
makes it much easier to update later. It's quite problematic when
people have "Foo" (meaning V1_0::Foo) and then this type is moved
into a new namespace (then Foo has to be found and changed to
V1_0::Foo). However, if people refer to V1_0::Foo from the start,
they can immediately start referring to V1_1::Foo in the future.

Currently, it seems types' full namespaces are output (e.g.
we have sp<android::hardware::foo::V1_0::INfc> in the output).
Ideally this would be sp<V1_0::INfc> only, but more refactoring
would be required to implement this (this has been the case
since e30ee9b06ac578006161e84633db91289f889068).

Fixes: 145814082
Test: ./test/run_all_host_tests.sh

Change-Id: Ic8b4a1e2b5b2ea52a65e9b88699b9ca158378d00
diff --git a/generateCppImpl.cpp b/generateCppImpl.cpp
index bad6151..fe9b3e1 100644
--- a/generateCppImpl.cpp
+++ b/generateCppImpl.cpp
@@ -24,12 +24,13 @@
 #include "ScalarType.h"
 #include "Scope.h"
 
-#include <algorithm>
-#include <hidl-util/Formatter.h>
 #include <android-base/logging.h>
+#include <android-base/strings.h>
+#include <hidl-util/Formatter.h>
+#include <algorithm>
+#include <set>
 #include <string>
 #include <vector>
-#include <set>
 
 namespace android {
 
@@ -68,6 +69,12 @@
     return;
 }
 
+static std::string getImplNamespace(const FQName& fqName) {
+    std::vector<std::string> components = fqName.getPackageComponents();
+    components.push_back("implementation");
+    return base::Join(components, "::");
+}
+
 void AST::generateCppImplHeader(Formatter& out) const {
     if (!AST::isInterface()) {
         // types.hal does not get a stub header.
@@ -85,8 +92,8 @@
     out << "#include <hidl/MQDescriptor.h>\n";
     out << "#include <hidl/Status.h>\n\n";
 
-    enterLeaveNamespace(out, true /* enter */);
-    out << "namespace implementation {\n\n";
+    const std::string nspace = getImplNamespace(mPackage);
+    out << "namespace " << nspace << " {\n\n";
 
     out << "using ::android::hardware::hidl_array;\n";
     out << "using ::android::hardware::hidl_memory;\n";
@@ -98,7 +105,8 @@
 
     out << "\n";
 
-    out << "struct " << baseName << " : public " << iface->definedName() << " {\n";
+    out << "struct " << baseName << " : public " << iface->fqName().sanitizedVersion()
+        << "::" << iface->definedName() << " {\n";
 
     out.indent();
 
@@ -121,8 +129,7 @@
     generateFetchSymbol(out, iface->definedName());
     out << "(const char* name);\n\n";
 
-    out << "}  // namespace implementation\n";
-    enterLeaveNamespace(out, false /* leave */);
+    out << "}  // namespace " << nspace << "\n";
 }
 
 void AST::generateCppImplSource(Formatter& out) const {
@@ -137,8 +144,8 @@
     out << "// FIXME: your file license if you have one\n\n";
     out << "#include \"" << baseName << ".h\"\n\n";
 
-    enterLeaveNamespace(out, true /* enter */);
-    out << "namespace implementation {\n\n";
+    const std::string nspace = getImplNamespace(mPackage);
+    out << "namespace " << nspace << " {\n\n";
 
     generateMethods(out, [&](const Method* method, const Interface*) {
         generateStubImplMethod(out, baseName, method);
@@ -154,8 +161,7 @@
     out << "}\n\n";
     out.popLinePrefix();
 
-    out << "}  // namespace implementation\n";
-    enterLeaveNamespace(out, false /* leave */);
+    out << "}  // namespace " << nspace << "\n";
 }
 
 }  // namespace android