Home | History | Annotate | Download | only in gn
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef TOOLS_GN_INPUT_FILE_MANAGER_H_
      6 #define TOOLS_GN_INPUT_FILE_MANAGER_H_
      7 
      8 #include <set>
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/callback.h"
     14 #include "base/containers/hash_tables.h"
     15 #include "base/files/file_path.h"
     16 #include "base/memory/ref_counted.h"
     17 #include "base/synchronization/lock.h"
     18 #include "base/synchronization/waitable_event.h"
     19 #include "tools/gn/build_settings.h"
     20 #include "tools/gn/input_file.h"
     21 #include "tools/gn/parse_tree.h"
     22 #include "tools/gn/settings.h"
     23 
     24 class Err;
     25 class LocationRange;
     26 class ParseNode;
     27 class Token;
     28 
     29 // Manages loading and parsing files from disk. This doesn't actually have
     30 // any context for executing the results, so potentially multiple configs
     31 // could use the same input file (saving parsing).
     32 //
     33 // This class is threadsafe.
     34 //
     35 // InputFile objects must never be deleted while the program is running since
     36 // various state points into them.
     37 class InputFileManager : public base::RefCountedThreadSafe<InputFileManager> {
     38  public:
     39   // Callback issued when a file is laoded. On auccess, the parse node will
     40   // refer to the root block of the file. On failure, this will be NULL.
     41   typedef base::Callback<void(const ParseNode*)> FileLoadCallback;
     42 
     43   InputFileManager();
     44 
     45   // Loads the given file and executes the callback on the worker pool.
     46   //
     47   // There are two types of errors. For errors known synchronously, the error
     48   // will be set, it will return false, and no work will be scheduled.
     49   //
     50   // For parse errors and such that happen in the future, the error will be
     51   // logged to the scheduler and the callback will be invoked with a null
     52   // ParseNode pointer. The given |origin| will be blamed for the invocation.
     53   bool AsyncLoadFile(const LocationRange& origin,
     54                      const BuildSettings* build_settings,
     55                      const SourceFile& file_name,
     56                      const FileLoadCallback& callback,
     57                      Err* err);
     58 
     59   // Loads and parses the given file synchronously, returning the root block
     60   // corresponding to the parsed result. On error, return NULL and the given
     61   // Err is set.
     62   const ParseNode* SyncLoadFile(const LocationRange& origin,
     63                                 const BuildSettings* build_settings,
     64                                 const SourceFile& file_name,
     65                                 Err* err);
     66 
     67   int GetInputFileCount() const;
     68 
     69   // Fills the vector with all input files.
     70   void GetAllPhysicalInputFileNames(std::vector<base::FilePath>* result) const;
     71 
     72  private:
     73   friend class base::RefCountedThreadSafe<InputFileManager>;
     74 
     75   struct InputFileData {
     76     InputFileData(const SourceFile& file_name);
     77     ~InputFileData();
     78 
     79     // Don't touch this outside the lock until it's marked loaded.
     80     InputFile file;
     81 
     82     bool loaded;
     83 
     84     bool sync_invocation;
     85 
     86     // Lists all invocations that need to be executed when the file completes
     87     // loading.
     88     std::vector<FileLoadCallback> scheduled_callbacks;
     89 
     90     // Event to signal when the load is complete (or fails). This is lazily
     91     // created only when a thread is synchronously waiting for this load (which
     92     // only happens for imports).
     93     scoped_ptr<base::WaitableEvent> completion_event;
     94 
     95     std::vector<Token> tokens;
     96 
     97     // Null before the file is loaded or if loading failed.
     98     scoped_ptr<ParseNode> parsed_root;
     99   };
    100 
    101   virtual ~InputFileManager();
    102 
    103   void BackgroundLoadFile(const LocationRange& origin,
    104                           const BuildSettings* build_settings,
    105                           const SourceFile& name,
    106                           InputFile* file);
    107 
    108   // Loads the given file. On error, sets the Err and return false.
    109   bool LoadFile(const LocationRange& origin,
    110                 const BuildSettings* build_settings,
    111                 const SourceFile& name,
    112                 InputFile* file,
    113                 Err* err);
    114 
    115   mutable base::Lock lock_;
    116 
    117   // Maps repo-relative filenames to the corresponding owned pointer.
    118   typedef base::hash_map<SourceFile, InputFileData*> InputFileMap;
    119   InputFileMap input_files_;
    120 
    121   DISALLOW_COPY_AND_ASSIGN(InputFileManager);
    122 };
    123 
    124 #endif  // TOOLS_GN_INPUT_FILE_MANAGER_H_
    125