refactor: parser returns parsed document

Parser::Parse returns AidlDocument. After parsing a document,
AidlDocument is added to AidlTypenames and managed by it. So we don't
need to keep a parser instance.

This enables caching so that when loading a document which is already
parsed then Parse() can simply return the AidlDocument.

Bug: 188878102
Test: aidl_unittests
Change-Id: Ifc50bc20b48e3a2c7a8a614ed8c8a179cd6dd9c9
diff --git a/parser.cpp b/parser.cpp
index 732de59..c7fd61a 100644
--- a/parser.cpp
+++ b/parser.cpp
@@ -25,9 +25,15 @@
 YY_BUFFER_STATE yy_scan_buffer(char*, size_t, void*);
 void yy_delete_buffer(YY_BUFFER_STATE, void*);
 
-std::unique_ptr<Parser> Parser::Parse(const std::string& filename,
-                                      const android::aidl::IoDelegate& io_delegate,
-                                      AidlTypenames& typenames) {
+const AidlDocument* Parser::Parse(const std::string& filename,
+                                  const android::aidl::IoDelegate& io_delegate,
+                                  AidlTypenames& typenames) {
+  // reuse pre-parsed document from typenames
+  for (auto& doc : typenames.AllDocuments()) {
+    if (doc->GetLocation().GetFile() == filename) {
+      return doc.get();
+    }
+  }
   // Make sure we can read the file first, before trashing previous state.
   unique_ptr<string> raw_buffer = io_delegate.GetFileContents(filename);
   if (raw_buffer == nullptr) {
@@ -39,13 +45,13 @@
   // nulls at the end.
   raw_buffer->append(2u, '\0');
 
-  std::unique_ptr<Parser> parser(new Parser(filename, *raw_buffer, typenames));
+  Parser parser(filename, *raw_buffer, typenames);
 
-  if (yy::parser(parser.get()).parse() != 0 || parser->HasError()) {
+  if (yy::parser(&parser).parse() != 0 || parser.HasError()) {
     return nullptr;
   }
 
-  return parser;
+  return parser.ParsedDocument();
 }
 
 void Parser::SetTypeParameters(AidlTypeSpecifier* type,
@@ -63,9 +69,8 @@
 
 class ReferenceResolver : public AidlVisitor {
  public:
-  ReferenceResolver(const AidlDefinedType* scope, const AidlTypenames& typenames,
-                    TypeResolver& resolver, bool* success)
-      : scope_(scope), typenames_(typenames), resolver_(resolver), success_(success) {}
+  ReferenceResolver(const AidlDefinedType* scope, TypeResolver& resolver, bool* success)
+      : scope_(scope), resolver_(resolver), success_(success) {}
 
   void Visit(const AidlTypeSpecifier& t) override {
     // We're visiting the same node again. This can happen when two constant references
@@ -75,7 +80,7 @@
     }
 
     AidlTypeSpecifier& type = const_cast<AidlTypeSpecifier&>(t);
-    if (!resolver_(typenames_.GetDocumentFor(scope_), &type)) {
+    if (!resolver_(scope_, &type)) {
       AIDL_ERROR(type) << "Failed to resolve '" << type.GetUnresolvedName() << "'";
       *success_ = false;
     }
@@ -139,18 +144,17 @@
   }
 
   const AidlDefinedType* scope_;
-  const AidlTypenames& typenames_;
   TypeResolver& resolver_;
   bool* success_;
   std::vector<StackElem> stack_ = {};
 };
 
 // Resolve "unresolved" types in the "main" document.
-bool Parser::Resolve(TypeResolver& type_resolver) {
+bool ResolveReferences(const AidlDocument& document, TypeResolver& type_resolver) {
   bool success = true;
 
-  for (const auto& type : document_->DefinedTypes()) {
-    ReferenceResolver ref_resolver{type.get(), typenames_, type_resolver, &success};
+  for (const auto& type : document.DefinedTypes()) {
+    ReferenceResolver ref_resolver{type.get(), type_resolver, &success};
     VisitBottomUp(ref_resolver, *type);
   }