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_LOADER_H_ 6 #define TOOLS_GN_LOADER_H_ 7 8 #include <map> 9 #include <set> 10 11 #include "base/callback.h" 12 #include "base/memory/ref_counted.h" 13 #include "tools/gn/label.h" 14 #include "tools/gn/scope.h" 15 16 namespace base { 17 class MessageLoop; 18 } 19 20 class BuildSettings; 21 class Settings; 22 class SourceFile; 23 class Toolchain; 24 25 // The loader manages execution of the different build files. It receives 26 // requests (normally from the Builder) when new references are found, and also 27 // manages loading the build config files. 28 // 29 // This loader class is abstract so it can be mocked out for testing the 30 // Builder. 31 class Loader : public base::RefCountedThreadSafe<Loader> { 32 public: 33 Loader(); 34 35 // Loads the given file in the conext of the given toolchain. The initial 36 // call to this (the one that actually starts the generation) should have an 37 // empty toolchain name, which will trigger the load of the default build 38 // config. 39 virtual void Load(const SourceFile& file, 40 const Label& toolchain_name) = 0; 41 42 // Notification that the given toolchain has loaded. This will unblock files 43 // waiting on this definition. 44 virtual void ToolchainLoaded(const Toolchain* toolchain) = 0; 45 46 // Returns the label of the default toolchain. 47 virtual Label GetDefaultToolchain() const = 0; 48 49 // Returns information about the toolchain with the given label. Will return 50 // false if we haven't processed this toolchain yet. 51 virtual const Settings* GetToolchainSettings(const Label& label) = 0; 52 53 // Helper function that extracts the file and toolchain name from the given 54 // label, and calls Load(). 55 void Load(const Label& label); 56 57 // Returns the build file that the given label references. 58 static SourceFile BuildFileForLabel(const Label& label); 59 60 // When processing the default build config, we want to capture the argument 61 // of set_default_build_config. The implementation of that function uses this 62 // constant as a property key to get the Label* out of the scope where the 63 // label should be stored. 64 static const void* kDefaultToolchainKey; 65 66 protected: 67 friend class base::RefCountedThreadSafe<Loader>; 68 virtual ~Loader(); 69 }; 70 71 class LoaderImpl : public Loader { 72 public: 73 // Callback to emulate InputFileManager::AsyncLoadFile. 74 typedef base::Callback<bool(const LocationRange&, 75 const BuildSettings*, 76 const SourceFile&, 77 const base::Callback<void(const ParseNode*)>&, 78 Err*)> AsyncLoadFileCallback; 79 80 LoaderImpl(const BuildSettings* build_settings); 81 82 // Loader implementation. 83 virtual void Load(const SourceFile& file, 84 const Label& toolchain_name) OVERRIDE; 85 virtual void ToolchainLoaded(const Toolchain* toolchain) OVERRIDE; 86 virtual Label GetDefaultToolchain() const OVERRIDE; 87 virtual const Settings* GetToolchainSettings(const Label& label) OVERRIDE; 88 89 // Sets the message loop corresponding to the main thread. By default this 90 // class will use the thread active during construction, but there is not 91 // a message loop active during construction all the time. 92 void set_main_loop(base::MessageLoop* loop) { main_loop_ = loop; } 93 94 // The complete callback is called whenever there are no more pending loads. 95 // Called on the main thread only. This may be called more than once if the 96 // queue is drained, but then more stuff gets added. 97 void set_complete_callback(const base::Closure& cb) { 98 complete_callback_ = cb; 99 } 100 101 // This callback is used when the loader finds it wants to load a file. 102 void set_async_load_file(const AsyncLoadFileCallback& cb) { 103 async_load_file_ = cb; 104 } 105 106 const Label& default_toolchain_label() const { 107 return default_toolchain_label_; 108 } 109 110 private: 111 struct LoadID; 112 struct ToolchainRecord; 113 114 virtual ~LoaderImpl(); 115 116 // Schedules the input file manager to load the given file. 117 void ScheduleLoadFile(const Settings* settings, 118 const SourceFile& file); 119 void ScheduleLoadBuildConfig( 120 Settings* settings, 121 const Scope::KeyValueMap& toolchain_overrides); 122 123 // Runs the given file on the background thread. These are called by the 124 // input file manager. 125 void BackgroundLoadFile(const Settings* settings, 126 const SourceFile& file_name, 127 const ParseNode* root); 128 void BackgroundLoadBuildConfig( 129 Settings* settings, 130 const Scope::KeyValueMap& toolchain_overrides, 131 const ParseNode* root); 132 133 // Posted to the main thread when any file other than a build config file 134 // file has completed running. 135 void DidLoadFile(); 136 137 // Posted to the main thread when any build config file has completed 138 // running. The label should be the name of the toolchain. 139 // 140 // If there is no defauled toolchain loaded yet, we'll assume that the first 141 // call to this indicates to the default toolchain, and this function will 142 // set the default toolchain name to the given label. 143 void DidLoadBuildConfig(const Label& label); 144 145 // Decrements the pending_loads_ variable and issues the complete callback if 146 // necessary. 147 void DecrementPendingLoads(); 148 149 // Forwards to the appropriate location to load the file. 150 bool AsyncLoadFile(const LocationRange& origin, 151 const BuildSettings* build_settings, 152 const SourceFile& file_name, 153 const base::Callback<void(const ParseNode*)>& callback, 154 Err* err); 155 156 base::MessageLoop* main_loop_; 157 158 int pending_loads_; 159 base::Closure complete_callback_; 160 161 // When non-null, use this callback instead of the InputFileManager for 162 // mocking purposes. 163 AsyncLoadFileCallback async_load_file_; 164 165 typedef std::set<LoadID> LoadIDSet; 166 LoadIDSet invocations_; 167 168 const BuildSettings* build_settings_; 169 Label default_toolchain_label_; 170 171 // Records for the build config file loads. 172 // Owning pointers. 173 typedef std::map<Label, ToolchainRecord*> ToolchainRecordMap; 174 ToolchainRecordMap toolchain_records_; 175 }; 176 177 #endif // TOOLS_GN_LOADER_H_ 178