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