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.
5 #ifndef TOOLS_GN_LOADER_H_
6 #define TOOLS_GN_LOADER_H_
11 #include "base/callback.h"
12 #include "base/memory/ref_counted.h"
13 #include "tools/gn/label.h"
14 #include "tools/gn/scope.h"
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.
29 // This loader class is abstract so it can be mocked out for testing the
31 class Loader
: public base::RefCountedThreadSafe
<Loader
> {
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
39 virtual void Load(const SourceFile
& file
,
40 const Label
& toolchain_name
) = 0;
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;
46 // Returns the label of the default toolchain.
47 virtual Label
GetDefaultToolchain() const = 0;
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
) const = 0;
53 // Helper function that extracts the file and toolchain name from the given
54 // label, and calls Load().
55 void Load(const Label
& label
);
57 // Returns the build file that the given label references.
58 static SourceFile
BuildFileForLabel(const Label
& label
);
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
;
67 friend class base::RefCountedThreadSafe
<Loader
>;
71 class LoaderImpl
: public Loader
{
73 // Callback to emulate InputFileManager::AsyncLoadFile.
74 typedef base::Callback
<bool(const LocationRange
&,
77 const base::Callback
<void(const ParseNode
*)>&,
78 Err
*)> AsyncLoadFileCallback
;
80 LoaderImpl(const BuildSettings
* build_settings
);
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(
88 const Label
& label
) const OVERRIDE
;
90 // Sets the message loop corresponding to the main thread. By default this
91 // class will use the thread active during construction, but there is not
92 // a message loop active during construction all the time.
93 void set_main_loop(base::MessageLoop
* loop
) { main_loop_
= loop
; }
95 // The complete callback is called whenever there are no more pending loads.
96 // Called on the main thread only. This may be called more than once if the
97 // queue is drained, but then more stuff gets added.
98 void set_complete_callback(const base::Closure
& cb
) {
99 complete_callback_
= cb
;
102 // This callback is used when the loader finds it wants to load a file.
103 void set_async_load_file(const AsyncLoadFileCallback
& cb
) {
104 async_load_file_
= cb
;
107 const Label
& default_toolchain_label() const {
108 return default_toolchain_label_
;
113 struct ToolchainRecord
;
115 virtual ~LoaderImpl();
117 // Schedules the input file manager to load the given file.
118 void ScheduleLoadFile(const Settings
* settings
,
119 const SourceFile
& file
);
120 void ScheduleLoadBuildConfig(
122 const Scope::KeyValueMap
& toolchain_overrides
);
124 // Runs the given file on the background thread. These are called by the
125 // input file manager.
126 void BackgroundLoadFile(const Settings
* settings
,
127 const SourceFile
& file_name
,
128 const ParseNode
* root
);
129 void BackgroundLoadBuildConfig(
131 const Scope::KeyValueMap
& toolchain_overrides
,
132 const ParseNode
* root
);
134 // Posted to the main thread when any file other than a build config file
135 // file has completed running.
138 // Posted to the main thread when any build config file has completed
139 // running. The label should be the name of the toolchain.
141 // If there is no defauled toolchain loaded yet, we'll assume that the first
142 // call to this indicates to the default toolchain, and this function will
143 // set the default toolchain name to the given label.
144 void DidLoadBuildConfig(const Label
& label
);
146 // Decrements the pending_loads_ variable and issues the complete callback if
148 void DecrementPendingLoads();
150 // Forwards to the appropriate location to load the file.
151 bool AsyncLoadFile(const LocationRange
& origin
,
152 const BuildSettings
* build_settings
,
153 const SourceFile
& file_name
,
154 const base::Callback
<void(const ParseNode
*)>& callback
,
157 base::MessageLoop
* main_loop_
;
160 base::Closure complete_callback_
;
162 // When non-null, use this callback instead of the InputFileManager for
164 AsyncLoadFileCallback async_load_file_
;
166 typedef std::set
<LoadID
> LoadIDSet
;
167 LoadIDSet invocations_
;
169 const BuildSettings
* build_settings_
;
170 Label default_toolchain_label_
;
172 // Records for the build config file loads.
174 typedef std::map
<Label
, ToolchainRecord
*> ToolchainRecordMap
;
175 ToolchainRecordMap toolchain_records_
;
178 #endif // TOOLS_GN_LOADER_H_