Allow duplicate types from preprocessed

When compiling for SDK stub sources, we need to load documents which are
also a part of preprocessed framework.aidl, which results in inevitable
type duplication.

We allow duplicate types only if one of them is from preprocessed
document.

Bug: 192211616
Test: aidl_unittests
Change-Id: I21fc66d7305df824d2cc84308b84b9c9e9213d13
diff --git a/aidl_language.cpp b/aidl_language.cpp
index 83dfe74..7ea1bb8 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -906,7 +906,7 @@
 AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
                                  const Comments& comments, const std::string& package,
                                  std::vector<std::unique_ptr<AidlMember>>* members)
-    : AidlAnnotatable(location, comments), name_(name), package_(package) {
+    : AidlAnnotatable(location, comments), AidlScope(this), name_(name), package_(package) {
   // adjust name/package when name is fully qualified (for preprocessed files)
   if (package_.empty() && name_.find('.') != std::string::npos) {
     // Note that this logic is absolutely wrong.  Given a parcelable
@@ -1030,6 +1030,25 @@
   return GetEnclosingScope()->ResolveName(name);
 }
 
+template <typename T>
+const T* AidlCast(const AidlNode& node) {
+  struct CastVisitor : AidlVisitor {
+    const T* cast = nullptr;
+    void Visit(const T& t) override { cast = &t; }
+  } visitor;
+  node.DispatchVisit(visitor);
+  return visitor.cast;
+}
+
+const AidlDocument& AidlDefinedType::GetDocument() const {
+  // TODO(b/182508839): resolve with nested types when we support nested types
+  auto scope = GetEnclosingScope();
+  AIDL_FATAL_IF(!scope, this) << "no scope defined.";
+  auto doc = AidlCast<AidlDocument>(scope->GetNode());
+  AIDL_FATAL_IF(!doc, this) << "scope is not a document.";
+  return *doc;
+}
+
 AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
                                const std::string& package, const Comments& comments,
                                const std::string& cpp_header, std::vector<std::string>* type_params,
@@ -1524,10 +1543,13 @@
 
 AidlDocument::AidlDocument(const AidlLocation& location, const Comments& comments,
                            std::vector<std::unique_ptr<AidlImport>> imports,
-                           std::vector<std::unique_ptr<AidlDefinedType>> defined_types)
+                           std::vector<std::unique_ptr<AidlDefinedType>> defined_types,
+                           bool is_preprocessed)
     : AidlCommentable(location, comments),
+      AidlScope(this),
       imports_(std::move(imports)),
-      defined_types_(std::move(defined_types)) {
+      defined_types_(std::move(defined_types)),
+      is_preprocessed_(is_preprocessed) {
   for (const auto& t : defined_types_) {
     t->SetEnclosingScope(this);
   }