diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn
index 510c178..b77d2af 100644
--- a/tools/gn/BUILD.gn
+++ b/tools/gn/BUILD.gn
@@ -58,6 +58,8 @@
     "create_bundle_target_generator.h",
     "deps_iterator.cc",
     "deps_iterator.h",
+    "desc_builder.cc",
+    "desc_builder.h",
     "eclipse_writer.cc",
     "eclipse_writer.h",
     "err.cc",
@@ -101,6 +103,8 @@
     "input_file_manager.h",
     "item.cc",
     "item.h",
+    "json_project_writer.cc",
+    "json_project_writer.h",
     "label.cc",
     "label.h",
     "label_pattern.cc",
diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc
index ea1bab3..72525e9 100644
--- a/tools/gn/command_desc.cc
+++ b/tools/gn/command_desc.cc
@@ -9,18 +9,14 @@
 #include <sstream>
 
 #include "base/command_line.h"
-#include "build/build_config.h"
+#include "base/json/json_writer.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_util.h"
 #include "tools/gn/commands.h"
 #include "tools/gn/config.h"
-#include "tools/gn/config_values_extractors.h"
-#include "tools/gn/deps_iterator.h"
-#include "tools/gn/filesystem_utils.h"
-#include "tools/gn/item.h"
-#include "tools/gn/label.h"
-#include "tools/gn/runtime_deps.h"
+#include "tools/gn/desc_builder.h"
 #include "tools/gn/setup.h"
 #include "tools/gn/standard_out.h"
-#include "tools/gn/substitution_writer.h"
 #include "tools/gn/switches.h"
 #include "tools/gn/target.h"
 #include "tools/gn/variables.h"
@@ -32,725 +28,258 @@
 // Desc-specific command line switches.
 const char kBlame[] = "blame";
 const char kTree[] = "tree";
+const char kAll[] = "all";
 
-// Prints the given directory in a nice way for the user to view.
-std::string FormatSourceDir(const SourceDir& dir) {
-#if defined(OS_WIN)
-  // On Windows we fix up system absolute paths to look like native ones.
-  // Internally, they'll look like "/C:\foo\bar/"
-  if (dir.is_system_absolute()) {
-    std::string buf = dir.value();
-    if (buf.size() > 3 && buf[2] == ':') {
-      buf.erase(buf.begin());  // Erase beginning slash.
-      return buf;
+// Prints value with specified indentation level
+void PrintValue(const base::Value* value, int indentLevel) {
+  std::string indent(indentLevel * 2, ' ');
+  const base::ListValue* list_value = nullptr;
+  const base::DictionaryValue* dict_value = nullptr;
+  std::string string_value;
+  bool bool_value = false;
+  if (value->GetAsList(&list_value)) {
+    for (const auto& v : *list_value) {
+      PrintValue(v.get(), indentLevel);
     }
-  }
-#endif
-  return dir.value();
-}
-
-void RecursiveCollectChildDeps(const Target* target,
-                               std::set<const Target*>* result);
-
-void RecursiveCollectDeps(const Target* target,
-                          std::set<const Target*>* result) {
-  if (result->find(target) != result->end())
-    return;  // Already did this target.
-  result->insert(target);
-
-  RecursiveCollectChildDeps(target, result);
-}
-
-void RecursiveCollectChildDeps(const Target* target,
-                               std::set<const Target*>* result) {
-  for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
-    RecursiveCollectDeps(pair.ptr, result);
-}
-
-// Prints dependencies of the given target (not the target itself). If the
-// set is non-null, new targets encountered will be added to the set, and if
-// a dependency is in the set already, it will not be recused into. When the
-// set is null, all dependencies will be printed.
-void RecursivePrintDeps(const Target* target,
-                        const Label& default_toolchain,
-                        std::set<const Target*>* seen_targets,
-                        int indent_level) {
-  // Combine all deps into one sorted list.
-  std::vector<LabelTargetPair> sorted_deps;
-  for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
-    sorted_deps.push_back(pair);
-  std::sort(sorted_deps.begin(), sorted_deps.end(),
-            LabelPtrLabelLess<Target>());
-
-  std::string indent(indent_level * 2, ' ');
-  for (const auto& pair : sorted_deps) {
-    const Target* cur_dep = pair.ptr;
-
-    OutputString(indent +
-        cur_dep->label().GetUserVisibleName(default_toolchain));
-    bool print_children = true;
-    if (seen_targets) {
-      if (seen_targets->find(cur_dep) == seen_targets->end()) {
-        // New target, mark it visited.
-        seen_targets->insert(cur_dep);
-      } else {
-        // Already seen.
-        print_children = false;
-        // Only print "..." if something is actually elided, which means that
-        // the current target has children.
-        if (!cur_dep->public_deps().empty() ||
-            !cur_dep->private_deps().empty() ||
-            !cur_dep->data_deps().empty())
-          OutputString("...");
-      }
-    }
-
+  } else if (value->GetAsString(&string_value)) {
+    OutputString(indent);
+    OutputString(string_value);
     OutputString("\n");
-    if (print_children) {
-      RecursivePrintDeps(cur_dep, default_toolchain, seen_targets,
-                         indent_level + 1);
+  } else if (value->GetAsBoolean(&bool_value)) {
+    OutputString(indent);
+    OutputString(bool_value ? "true" : "false");
+    OutputString("\n");
+  } else if (value->GetAsDictionary(&dict_value)) {
+    base::DictionaryValue::Iterator iter(*dict_value);
+    while (!iter.IsAtEnd()) {
+      OutputString(indent + iter.key() + "\n");
+      PrintValue(&iter.value(), indentLevel + 1);
+      iter.Advance();
     }
+  } else if (value->IsType(base::Value::TYPE_NULL)) {
+    OutputString(indent + "<null>\n");
   }
 }
 
-void PrintDeps(const Target* target, bool display_header) {
-  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
-  Label toolchain_label = target->label().GetToolchainLabel();
+// Default handler for property
+void DefaultHandler(const std::string& name, const base::Value* value) {
+  OutputString("\n");
+  OutputString(name);
+  OutputString("\n");
+  PrintValue(value, 1);
+}
 
-  // Tree mode is separate.
-  if (cmdline->HasSwitch(kTree)) {
-    if (display_header)
-      OutputString("\nDependency tree\n");
+// Specific handler for properties that need different treatment
 
-    if (cmdline->HasSwitch("all")) {
-      // Show all tree deps with no eliding.
-      RecursivePrintDeps(target, toolchain_label, nullptr, 1);
+// Prints label and property value on one line, capitalizing the label.
+void LabelHandler(std::string name, const base::Value* value) {
+  name[0] = base::ToUpperASCII(name[0]);
+  std::string string_value;
+  if (value->GetAsString(&string_value)) {
+    OutputString(name + ": ", DECORATION_YELLOW);
+    OutputString(string_value + "\n");
+  }
+}
+
+void VisibilityHandler(const std::string& name, const base::Value* value) {
+  const base::ListValue* list;
+  if (value->GetAsList(&list)) {
+    if (list->empty()) {
+      base::StringValue str("(no visibility)");
+      DefaultHandler(name, &str);
     } else {
-      // Don't recurse into duplicates.
-      std::set<const Target*> seen_targets;
-      RecursivePrintDeps(target, toolchain_label, &seen_targets, 1);
+      DefaultHandler(name, value);
     }
-    return;
   }
+}
 
-  // Collect the deps to display.
-  if (cmdline->HasSwitch("all")) {
-    // Show all dependencies.
-    if (display_header)
-      OutputString("\nAll recursive dependencies\n");
-
-    std::set<const Target*> all_deps;
-    RecursiveCollectChildDeps(target, &all_deps);
-    FilterAndPrintTargetSet(display_header, all_deps);
-  } else {
-    std::vector<const Target*> deps;
-    // Show direct dependencies only.
-    if (display_header) {
-      OutputString(
-          "\nDirect dependencies "
-          "(try also \"--all\", \"--tree\", or even \"--all --tree\")\n");
+void PublicHandler(const std::string& name, const base::Value* value) {
+  std::string p;
+  if (value->GetAsString(&p)) {
+    if (p == "*") {
+      base::StringValue str("[All headers listed in the sources are public.]");
+      DefaultHandler(name, &str);
+      return;
     }
-    for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
-      deps.push_back(pair.ptr);
-    std::sort(deps.begin(), deps.end());
-    FilterAndPrintTargets(display_header, &deps);
   }
+  DefaultHandler(name, value);
 }
 
-// libs and lib_dirs are special in that they're inherited. We don't currently
-// implement a blame feature for this since the bottom-up inheritance makes
-// this difficult.
-void PrintLibDirs(const Target* target, bool display_header) {
-  const OrderedSet<SourceDir>& lib_dirs = target->all_lib_dirs();
-  if (lib_dirs.empty())
-    return;
-
-  if (display_header)
-    OutputString("\nlib_dirs\n");
-
-  for (size_t i = 0; i < lib_dirs.size(); i++)
-    OutputString("    " + FormatSourceDir(lib_dirs[i]) + "\n");
-}
-
-void PrintLibs(const Target* target, bool display_header) {
-  const OrderedSet<LibFile>& libs = target->all_libs();
-  if (libs.empty())
-    return;
-
-  if (display_header)
-    OutputString("\nlibs\n");
-
-  for (size_t i = 0; i < libs.size(); i++)
-    OutputString("    " + libs[i].value() + "\n");
-}
-
-void PrintPublic(const Target* target, bool display_header) {
-  if (display_header)
-    OutputString("\npublic\n");
-
-  if (target->all_headers_public()) {
-    OutputString("  [All headers listed in the sources are public.]\n");
-    return;
-  }
-
-  Target::FileList public_headers = target->public_headers();
-  std::sort(public_headers.begin(), public_headers.end());
-  for (const auto& hdr : public_headers)
-    OutputString("  " + hdr.value() + "\n");
-}
-
-void PrintCheckIncludes(const Target* target, bool display_header) {
-  if (display_header)
-    OutputString("\ncheck_includes\n");
-
-  if (target->check_includes())
-    OutputString("  true\n");
-  else
-    OutputString("  false\n");
-}
-
-void PrintAllowCircularIncludesFrom(const Target* target, bool display_header) {
-  if (display_header)
-    OutputString("\nallow_circular_includes_from\n");
-
-  Label toolchain_label = target->label().GetToolchainLabel();
-  for (const auto& cur : target->allow_circular_includes_from())
-    OutputString("  " + cur.GetUserVisibleName(toolchain_label) + "\n");
-}
-
-void PrintVisibility(const Target* target, bool display_header) {
-  if (display_header)
-    OutputString("\nvisibility\n");
-
-  OutputString(target->visibility().Describe(2, false));
-}
-
-void PrintTestonly(const Target* target, bool display_header) {
-  if (display_header)
-    OutputString("\ntestonly\n");
-
-  if (target->testonly())
-    OutputString("  true\n");
-  else
-    OutputString("  false\n");
-}
-
-// Recursively prints subconfigs of a config.
-void PrintSubConfigs(const Config* config, int indent_level) {
-  if (config->configs().empty())
-    return;
-
-  std::string indent(indent_level * 2, ' ');
-  Label toolchain_label = config->label().GetToolchainLabel();
-  for (const auto& pair : config->configs()) {
-    OutputString(
-        indent + pair.label.GetUserVisibleName(toolchain_label) + "\n");
-    PrintSubConfigs(pair.ptr, indent_level + 1);
-  }
-}
-
-// This allows configs stored as either std::vector<LabelConfigPair> or
-// UniqueVector<LabelConfigPair> to be printed.
-template <class VectorType>
-void PrintConfigsVector(const Item* item,
-                        const VectorType& configs,
-                        const std::string& heading,
-                        bool display_header) {
-  if (configs.empty())
-    return;
-
+void ConfigsHandler(const std::string& name, const base::Value* value) {
   bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
-
-  // Don't sort since the order determines how things are processed.
-  if (display_header) {
-    if (tree)
-      OutputString("\n" + heading + " tree (in order applying)\n");
-    else
-      OutputString("\n" + heading + " (in order applying, try also --tree)\n");
-  }
-
-  Label toolchain_label = item->label().GetToolchainLabel();
-  for (const auto& config : configs) {
-    OutputString("  " + config.label.GetUserVisibleName(toolchain_label) +
-                 "\n");
-    if (tree)
-      PrintSubConfigs(config.ptr, 2);  // 2 = start with double-indent.
-  }
+  if (tree)
+    DefaultHandler(name + " tree (in order applying)", value);
+  else
+    DefaultHandler(name + " (in order applying, try also --tree)", value);
 }
 
-void PrintConfigs(const Target* target, bool display_header) {
-  PrintConfigsVector(target, target->configs().vector(), "configs",
-                     display_header);
-}
-
-void PrintConfigs(const Config* config, bool display_header) {
-  PrintConfigsVector(config, config->configs().vector(), "configs",
-                     display_header);
-}
-
-void PrintPublicConfigs(const Target* target, bool display_header) {
-  PrintConfigsVector(target, target->public_configs(),
-                     "public_configs", display_header);
-}
-
-void PrintAllDependentConfigs(const Target* target, bool display_header) {
-  PrintConfigsVector(target, target->all_dependent_configs(),
-                     "all_dependent_configs", display_header);
-}
-
-void PrintFileList(const Target::FileList& files,
-                   const std::string& header,
-                   bool indent_extra,
-                   bool display_header) {
-  if (files.empty())
-    return;
-
-  if (display_header)
-    OutputString("\n" + header + "\n");
-
-  std::string indent = indent_extra ? "    " : "  ";
-
-  Target::FileList sorted = files;
-  std::sort(sorted.begin(), sorted.end());
-  for (const auto& elem : sorted)
-    OutputString(indent + elem.value() + "\n");
-}
-
-void PrintSources(const Target* target, bool display_header) {
-  PrintFileList(target->sources(), "sources", false, display_header);
-}
-
-void PrintInputs(const Target* target, bool display_header) {
-  PrintFileList(target->inputs(), "inputs", false, display_header);
-}
-
-void PrintOutputs(const Target* target, bool display_header) {
-  if (display_header)
-    OutputString("\noutputs\n");
-
-  if (target->output_type() == Target::ACTION) {
-    // Action, print out outputs, don't apply sources to it.
-    for (const auto& elem : target->action_values().outputs().list()) {
-      OutputString("  " + elem.AsString() + "\n");
+void DepsHandler(const std::string& name, const base::Value* value) {
+  bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
+  bool all = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
+  if (tree) {
+    DefaultHandler("Dependency tree", value);
+  } else {
+    if (!all) {
+      DefaultHandler(
+          "Direct dependencies "
+          "(try also \"--all\", \"--tree\", or even \"--all --tree\")",
+          value);
+    } else {
+      DefaultHandler("All recursive dependencies", value);
     }
-  } else if (target->output_type() == Target::CREATE_BUNDLE) {
-    std::vector<SourceFile> output_files;
-    target->bundle_data().GetOutputsAsSourceFiles(target->settings(),
-                                                  &output_files);
-    PrintFileList(output_files, std::string(), true, false);
-  } else if (target->output_type() == Target::ACTION_FOREACH) {
-    const SubstitutionList& outputs = target->action_values().outputs();
-    if (!outputs.required_types().empty()) {
-      // Display the pattern and resolved pattern separately, since there are
-      // subtitutions used.
-      OutputString("  Output pattern\n");
-      for (const auto& elem : outputs.list())
-        OutputString("    " + elem.AsString() + "\n");
+  }
+}
 
-      // Now display what that resolves to given the sources.
+// Outputs need special processing when output patterns are present.
+void ProcessOutputs(base::DictionaryValue* target) {
+  base::ListValue* patterns = nullptr;
+  base::ListValue* outputs = nullptr;
+  target->GetList("output_patterns", &patterns);
+  target->GetList(variables::kOutputs, &outputs);
+
+  if (outputs || patterns) {
+    OutputString("\noutputs\n");
+    int indent = 1;
+    if (patterns) {
+      OutputString("  Output patterns\n");
+      indent = 2;
+      PrintValue(patterns, indent);
       OutputString("\n  Resolved output file list\n");
     }
+    if (outputs)
+      PrintValue(outputs, indent);
 
-    // Resolved output list.
-    std::vector<SourceFile> output_files;
-    SubstitutionWriter::ApplyListToSources(target->settings(), outputs,
-                                           target->sources(), &output_files);
-    PrintFileList(output_files, std::string(), true, false);
-  } else {
-    DCHECK(target->IsBinary());
-    const Tool* tool = target->toolchain()->GetToolForTargetFinalOutput(target);
-
-    std::vector<OutputFile> output_files;
-    SubstitutionWriter::ApplyListToLinkerAsOutputFile(
-        target, tool, tool->outputs(), &output_files);
-
-    std::vector<SourceFile> output_files_as_source_file;
-    for (const OutputFile& output_file : output_files) {
-      output_files_as_source_file.push_back(
-          output_file.AsSourceFile(target->settings()->build_settings()));
-    }
-
-    PrintFileList(output_files_as_source_file, std::string(), true, false);
+    target->Remove("output_patterns", nullptr);
+    target->Remove(variables::kOutputs, nullptr);
   }
 }
 
-void PrintScript(const Target* target, bool display_header) {
-  if (display_header)
-    OutputString("\nscript\n");
-  OutputString("  " + target->action_values().script().value() + "\n");
-}
-
-void PrintArgs(const Target* target, bool display_header) {
-  if (display_header)
-    OutputString("\nargs\n");
-  for (const auto& elem : target->action_values().args().list()) {
-    OutputString("  " + elem.AsString() + "\n");
-  }
-}
-
-void PrintDepfile(const Target* target, bool display_header) {
-  if (target->action_values().depfile().empty())
-    return;
-  if (display_header)
-    OutputString("\ndepfile\n");
-  OutputString("  " + target->action_values().depfile().AsString() + "\n");
-}
-
-// Attribute the origin for attributing from where a target came from. Does
-// nothing if the input is null or it does not have a location.
-void OutputSourceOfDep(const ParseNode* origin, std::ostream& out) {
-  if (!origin)
-    return;
-  Location location = origin->GetRange().begin();
-  out << "       (Added by " + location.file()->name().value() << ":"
-      << location.line_number() << ")\n";
-}
-
-// Templatized writer for writing out different config value types.
-template<typename T> struct DescValueWriter {};
-template<> struct DescValueWriter<std::string> {
-  void operator()(const std::string& str, std::ostream& out) const {
-    out << "    " << str << "\n";
-  }
-};
-
-template<> struct DescValueWriter<SourceDir> {
-  void operator()(const SourceDir& dir, std::ostream& out) const {
-    out << "    " << FormatSourceDir(dir) << "\n";
-  }
-};
-
-template<> struct DescValueWriter<LibFile> {
-  void operator()(const LibFile& lib, std::ostream& out) const {
-    if (lib.is_source_file())
-      out << "    " << lib.source_file().value() << "\n";
-    else
-      out << "    " << lib.value() << "\n";
-  }
-};
-
-// Writes a given config value type to the string, optionally with attribution.
-// This should match RecursiveTargetConfigToStream in the order it traverses.
-template<typename T> void OutputRecursiveTargetConfig(
-    const Target* target,
-    const char* header_name,
-    const std::vector<T>& (ConfigValues::* getter)() const) {
-  bool display_blame =
-      base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame);
-
-  DescValueWriter<T> writer;
-  std::ostringstream out;
-
-  for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) {
-    if ((iter.cur().*getter)().empty())
-      continue;
-
-    // Optional blame sub-head.
-    if (display_blame) {
-      const Config* config = iter.GetCurrentConfig();
-      if (config) {
-        // Source of this value is a config.
-        out << "  From " << config->label().GetUserVisibleName(false) << "\n";
-        OutputSourceOfDep(iter.origin(), out);
-      } else {
-        // Source of this value is the target itself.
-        out << "  From " << target->label().GetUserVisibleName(false) << "\n";
-      }
-    }
-
-    // Actual values.
-    ConfigValuesToStream(iter.cur(), getter, writer, out);
-  }
-
-  std::string out_str = out.str();
-  if (!out_str.empty()) {
-    if (header_name)
-      OutputString("\n" + std::string(header_name) + "\n");
-    OutputString(out_str);
-  }
-}
-
-template<typename T> void OutputConfigValueArray(
-    const ConfigValues& values,
-    const char* header_name,
-    const std::vector<T>& (ConfigValues::* getter)() const) {
-  std::ostringstream out;
-
-  DescValueWriter<T> writer;
-  for (const T& cur : (values.*getter)())
-    writer(cur, out);
-
-  std::string out_str = out.str();
-  if (!out_str.empty()) {
-    if (header_name)
-      OutputString("\n" + std::string(header_name) + "\n");
-    OutputString(out_str);
-  }
-}
-
-void PrintRuntimeDeps(const Target* target) {
-  bool display_blame =
-      base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame);
-  Label toolchain = target->label().GetToolchainLabel();
-
-  const Target* previous_from = NULL;
-  for (const auto& pair : ComputeRuntimeDeps(target)) {
-    if (display_blame) {
-      // Generally a target's runtime deps will be listed sequentially, so
-      // group them and don't duplicate the "from" label for two in a row.
-      if (previous_from == pair.second) {
-        OutputString("  ");  // Just indent.
-      } else {
-        previous_from = pair.second;
-        OutputString("From ");
-        OutputString(pair.second->label().GetUserVisibleName(toolchain));
-        OutputString("\n  ");  // Make the file name indented.
-      }
-    }
-    OutputString(pair.first.value());
-    OutputString("\n");
-  }
-}
-
-// If "what" is empty, prints all PCH info. If "what" is nonempty, prints only
-// the things that match (if any). Returns true if anything was printed.
-bool PrintPrecompiledHeaderInfo(const ConfigValues& values,
-                                const std::string& what,
-                                bool display_headers) {
-  bool found_match = false;
-  if (what == variables::kPrecompiledHeader || what.empty()) {
-    if (!values.precompiled_header().empty()) {
-      if (display_headers)
-        OutputString("\nprecompiled_header\n");
-      OutputString(values.precompiled_header() + "\n");
-    }
-    found_match = true;
-  }
-  if (what == variables::kPrecompiledSource || what.empty()) {
-    if (!values.precompiled_source().is_null()) {
-      if (display_headers)
-        OutputString("\nprecompiled_source\n");
-      OutputString(values.precompiled_source().value() + "\n");
-    }
-    found_match = true;
-  }
-  return found_match;
-}
-
 bool PrintTarget(const Target* target,
                  const std::string& what,
-                 bool display_target_header) {
-  if (display_target_header) {
-    OutputString("Target: ", DECORATION_YELLOW);
-    OutputString(target->label().GetUserVisibleName(false) + "\n");
-    OutputString("Type: ", DECORATION_YELLOW);
-    OutputString(std::string(
-        Target::GetStringForOutputType(target->output_type())) + "\n");
-    OutputString("Toolchain: ", DECORATION_YELLOW);
-    OutputString(
-        target->label().GetToolchainLabel().GetUserVisibleName(false) + "\n");
-  }
-
-  // Display headers when outputting everything.
-  bool display_headers = what.empty();
-  bool is_binary_output = target->IsBinary();
-
-  bool found_match = false;
-
-  // General target meta variables.
-  if (what.empty() || what == variables::kVisibility) {
-    PrintVisibility(target, display_headers);
-    found_match = true;
-  }
-  if (what.empty() || what == variables::kTestonly) {
-    PrintTestonly(target, display_headers);
-    found_match  = true;
-  }
-
-  // Binary target meta variables.
-  if (is_binary_output) {
-    if (what.empty() || what == variables::kCheckIncludes) {
-      PrintCheckIncludes(target, display_headers);
-      found_match = true;
-    }
-    if (what.empty() || what == variables::kAllowCircularIncludesFrom) {
-      PrintAllowCircularIncludesFrom(target, display_headers);
-      found_match = true;
-    }
-  }
-
-  // Sources and inputs.
-  if (what.empty() || what == variables::kSources) {
-    PrintSources(target, display_headers);
-    found_match = true;
-  }
-  if (what.empty() || what == variables::kPublic) {
-    PrintPublic(target, display_headers);
-    found_match = true;
-  }
-  if (what.empty() || what == variables::kInputs) {
-    PrintInputs(target, display_headers);
-    found_match = true;
-  }
-
-  // Configs. Configs set directly on a target are only relevant for binary
-  // targets
-  if (is_binary_output && (what.empty() || what == variables::kConfigs)) {
-    PrintConfigs(target, display_headers);
-    found_match = true;
-  }
-
-  // Dependent/public configs can be applied to anything.
-  if (what.empty() || what == variables::kPublicConfigs) {
-    PrintPublicConfigs(target, display_headers);
-    found_match = true;
-  }
-  if (what.empty() || what == variables::kAllDependentConfigs) {
-    PrintAllDependentConfigs(target, display_headers);
-    found_match = true;
-  }
-
-  // Action values.
-  if (target->output_type() == Target::ACTION ||
-      target->output_type() == Target::ACTION_FOREACH) {
-    if (what.empty() || what == variables::kScript) {
-      PrintScript(target, display_headers);
-      found_match = true;
-    }
-    if (what.empty() || what == variables::kArgs) {
-      PrintArgs(target, display_headers);
-      found_match = true;
-    }
-    if (what.empty() || what == variables::kDepfile) {
-      PrintDepfile(target, display_headers);
-      found_match = true;
-    }
-  }
-
-  // Outputs.
-  if (target->output_type() != Target::SOURCE_SET &&
-      target->output_type() != Target::GROUP) {
-    if (what.empty() || what == variables::kOutputs) {
-      PrintOutputs(target, display_headers);
-      found_match = true;
-    }
-  }
-
-  // Values from configs only apply to binary targets.
-  if (is_binary_output) {
-    #define CONFIG_VALUE_ARRAY_HANDLER(name, type) \
-      if (what.empty() || what == #name) { \
-        OutputRecursiveTargetConfig<type>( \
-            target, display_headers ? #name : nullptr, &ConfigValues::name); \
-        found_match = true; \
-      }
-
-    CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
-    CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
-    // Libs and lib_dirs are handled specially below.
-
-    #undef CONFIG_VALUE_ARRAY_HANDLER
-
-    found_match |= PrintPrecompiledHeaderInfo(target->config_values(),
-                                              what, display_headers);
-  }
-
-  // Deps
-  if (what.empty() || what == "deps") {
-    PrintDeps(target, display_headers);
-    found_match = true;
-  }
-
-  // Runtime deps are special, print only when explicitly asked for and not in
-  // overview mode.
-  if (what == "runtime_deps") {
-    PrintRuntimeDeps(target);
-    found_match = true;
-  }
-
-  // Libs can be part of any target and get recursively pushed up the chain,
-  // so display them regardless of target type.
-  if (what.empty() || what == variables::kLibs) {
-    PrintLibs(target, display_headers);
-    found_match = true;
-  }
-  if (what.empty() || what == variables::kLibDirs) {
-    PrintLibDirs(target, display_headers);
-    found_match = true;
-  }
-
-  if (!found_match) {
+                 bool single_target,
+                 bool all,
+                 bool tree,
+                 bool blame) {
+  std::unique_ptr<base::DictionaryValue> dict =
+      DescBuilder::DescriptionForTarget(target, what, all, tree, blame);
+  if (!what.empty() && dict->empty()) {
     OutputString("Don't know how to display \"" + what + "\" for \"" +
-        Target::GetStringForOutputType(target->output_type()) + "\".\n");
+                 Target::GetStringForOutputType(target->output_type()) +
+                 "\".\n");
     return false;
   }
+  // Print single value, without any headers
+  if (!what.empty() && dict->size() == 1 && single_target) {
+    base::DictionaryValue::Iterator iter(*dict);
+    PrintValue(&iter.value(), 0);
+    return true;
+  }
+
+  OutputString("Target ", DECORATION_YELLOW);
+  OutputString(target->label().GetUserVisibleName(false));
+  OutputString("\n");
+
+  std::unique_ptr<base::Value> v;
+#define HANDLER(property, handler_name) \
+  if (dict->Remove(property, &v)) {     \
+    handler_name(property, v.get());    \
+  }
+
+  // Entries with DefaultHandler are present to enforce order
+  HANDLER("type", LabelHandler);
+  HANDLER("toolchain", LabelHandler);
+  HANDLER(variables::kVisibility, VisibilityHandler);
+  HANDLER(variables::kTestonly, DefaultHandler);
+  HANDLER(variables::kCheckIncludes, DefaultHandler);
+  HANDLER(variables::kAllowCircularIncludesFrom, DefaultHandler);
+  HANDLER(variables::kSources, DefaultHandler);
+  HANDLER(variables::kPublic, PublicHandler);
+  HANDLER(variables::kInputs, DefaultHandler);
+  HANDLER(variables::kConfigs, ConfigsHandler);
+  HANDLER(variables::kPublicConfigs, ConfigsHandler);
+  HANDLER(variables::kAllDependentConfigs, ConfigsHandler);
+  HANDLER(variables::kScript, DefaultHandler);
+  HANDLER(variables::kArgs, DefaultHandler);
+  HANDLER(variables::kDepfile, DefaultHandler);
+  ProcessOutputs(dict.get());
+  HANDLER("bundle_data", DefaultHandler);
+  HANDLER(variables::kArflags, DefaultHandler);
+  HANDLER(variables::kAsmflags, DefaultHandler);
+  HANDLER(variables::kCflags, DefaultHandler);
+  HANDLER(variables::kCflagsC, DefaultHandler);
+  HANDLER(variables::kCflagsCC, DefaultHandler);
+  HANDLER(variables::kCflagsObjC, DefaultHandler);
+  HANDLER(variables::kCflagsObjCC, DefaultHandler);
+  HANDLER(variables::kDefines, DefaultHandler);
+  HANDLER(variables::kIncludeDirs, DefaultHandler);
+  HANDLER(variables::kLdflags, DefaultHandler);
+  HANDLER(variables::kPrecompiledHeader, DefaultHandler);
+  HANDLER(variables::kPrecompiledSource, DefaultHandler);
+  HANDLER(variables::kDeps, DepsHandler);
+  HANDLER(variables::kLibs, DefaultHandler);
+  HANDLER(variables::kLibDirs, DefaultHandler);
+
+#undef HANDLER
+
+  // Process the rest (if any)
+  base::DictionaryValue::Iterator iter(*dict);
+  while (!iter.IsAtEnd()) {
+    DefaultHandler(iter.key(), &iter.value());
+    iter.Advance();
+  }
+
   return true;
 }
 
 bool PrintConfig(const Config* config,
                  const std::string& what,
-                 bool display_config_header) {
-  const ConfigValues& values = config->resolved_values();
-
-  if (display_config_header) {
-    OutputString("Config: ", DECORATION_YELLOW);
-    OutputString(config->label().GetUserVisibleName(false) + "\n");
-    OutputString("Toolchain: ", DECORATION_YELLOW);
-    OutputString(
-        config->label().GetToolchainLabel().GetUserVisibleName(false) + "\n");
-    if (what.empty() && !config->configs().empty()) {
-      OutputString(
-          "(This is a composite config, the values below are after the\n"
-          "expansion of the child configs.)\n");
-    }
-  }
-
-  // Display headers when outputting everything.
-  bool display_headers = what.empty();
-
-  if (what.empty() || what == variables::kConfigs)
-    PrintConfigs(config, display_headers);
-
-#define CONFIG_VALUE_ARRAY_HANDLER(name, type) \
-  if (what.empty() || what == #name) { \
-    OutputConfigValueArray<type>(values, display_headers ? #name : nullptr, \
-                                 &ConfigValues::name); \
-    found_match = true; \
-  }
-
-  bool found_match = false;
-
-  CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
-  CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
-  CONFIG_VALUE_ARRAY_HANDLER(lib_dirs, SourceDir)
-  CONFIG_VALUE_ARRAY_HANDLER(libs, LibFile)
-
-#undef CONFIG_VALUE_ARRAY_HANDLER
-
-  // Handles all PCH-related variables.
-  found_match |= PrintPrecompiledHeaderInfo(config->resolved_values(),
-                                            what, display_headers);
-
-  if (!found_match) {
+                 bool single_config) {
+  std::unique_ptr<base::DictionaryValue> dict =
+      DescBuilder::DescriptionForConfig(config, what);
+  if (!what.empty() && dict->empty()) {
     OutputString("Don't know how to display \"" + what + "\" for a config.\n");
     return false;
   }
+  // Print single value, without any headers
+  if (!what.empty() && dict->size() == 1 && single_config) {
+    base::DictionaryValue::Iterator iter(*dict);
+    PrintValue(&iter.value(), 0);
+    return true;
+  }
+
+  OutputString("Config: ", DECORATION_YELLOW);
+  OutputString(config->label().GetUserVisibleName(false));
+  OutputString("\n");
+
+  std::unique_ptr<base::Value> v;
+#define HANDLER(property, handler_name) \
+  if (dict->Remove(property, &v)) {     \
+    handler_name(property, v.get());    \
+  }
+
+  HANDLER("toolchain", LabelHandler);
+  if (!config->configs().empty()) {
+    OutputString(
+        "(This is a composite config, the values below are after the\n"
+        "expansion of the child configs.)\n");
+  }
+  HANDLER(variables::kArflags, DefaultHandler);
+  HANDLER(variables::kAsmflags, DefaultHandler);
+  HANDLER(variables::kCflags, DefaultHandler);
+  HANDLER(variables::kCflagsC, DefaultHandler);
+  HANDLER(variables::kCflagsCC, DefaultHandler);
+  HANDLER(variables::kCflagsObjC, DefaultHandler);
+  HANDLER(variables::kCflagsObjCC, DefaultHandler);
+  HANDLER(variables::kDefines, DefaultHandler);
+  HANDLER(variables::kIncludeDirs, DefaultHandler);
+  HANDLER(variables::kLdflags, DefaultHandler);
+  HANDLER(variables::kLibs, DefaultHandler);
+  HANDLER(variables::kLibDirs, DefaultHandler);
+  HANDLER(variables::kPrecompiledHeader, DefaultHandler);
+  HANDLER(variables::kPrecompiledSource, DefaultHandler);
+
+#undef HANDLER
+
   return true;
 }
 
@@ -762,7 +291,8 @@
 const char kDesc_HelpShort[] =
     "desc: Show lots of insightful information about a target or config.";
 const char kDesc_Help[] =
-    "gn desc <out_dir> <label or pattern> [<what to show>] [--blame]\n"
+    "gn desc <out_dir> <label or pattern> [<what to show>] [--blame] "
+    "[--format=json]\n"
     "\n"
     "  Displays information about a given target or config. The build\n"
     "  build parameters will be taken for the build in the given <out_dir>.\n"
@@ -814,6 +344,9 @@
     "\n"
     ALL_TOOLCHAINS_SWITCH_HELP
     "\n"
+    "  --format=json\n"
+    "      Format the output as JSON instead of text.\n"
+    "\n"
     "Target flags\n"
     "\n"
     "  --blame\n"
@@ -922,28 +455,52 @@
   if (args.size() == 3)
     what_to_print = args[2];
 
-  bool multiple_outputs = (target_matches.size() + config_matches.size()) > 1;
+  bool json = cmdline->GetSwitchValueASCII("format") == "json";
 
-  // Display headers for each target when printing all values, or when printing
-  // multiple targets or configs.
-  bool display_item_header = multiple_outputs || what_to_print.empty();
+  if (json) {
+    // Convert all targets/configs to JSON, serialize and print them
+    auto res = base::WrapUnique(new base::DictionaryValue());
+    if (!target_matches.empty()) {
+      for (const auto* target : target_matches) {
+        res->Set(target->label().GetUserVisibleName(
+                     target->settings()->default_toolchain_label()),
+                 DescBuilder::DescriptionForTarget(
+                     target, what_to_print, cmdline->HasSwitch(kAll),
+                     cmdline->HasSwitch(kTree), cmdline->HasSwitch(kBlame)));
+      }
+    } else if (!config_matches.empty()) {
+      for (const auto* config : config_matches) {
+        res->Set(config->label().GetUserVisibleName(false),
+                 DescBuilder::DescriptionForConfig(config, what_to_print));
+      }
+    }
+    std::string s;
+    base::JSONWriter::WriteWithOptions(
+        *res.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &s);
+    OutputString(s);
+  } else {
+    // Regular (non-json) formatted output
+    bool multiple_outputs = (target_matches.size() + config_matches.size()) > 1;
 
-  bool printed_output = false;
-  for (const Target* target : target_matches) {
-    if (printed_output)
-      OutputString("\n\n");
-    printed_output = true;
+    bool printed_output = false;
+    for (const Target* target : target_matches) {
+      if (printed_output)
+        OutputString("\n\n");
+      printed_output = true;
 
-    if (!PrintTarget(target, what_to_print, display_item_header))
-      return 1;
-  }
-  for (const Config* config : config_matches) {
-    if (printed_output)
-      OutputString("\n\n");
-    printed_output = true;
+      if (!PrintTarget(target, what_to_print, !multiple_outputs,
+                       cmdline->HasSwitch(kAll), cmdline->HasSwitch(kTree),
+                       cmdline->HasSwitch(kBlame)))
+        return 1;
+    }
+    for (const Config* config : config_matches) {
+      if (printed_output)
+        OutputString("\n\n");
+      printed_output = true;
 
-    if (!PrintConfig(config, what_to_print, display_item_header))
-      return 1;
+      if (!PrintConfig(config, what_to_print, !multiple_outputs))
+        return 1;
+    }
   }
 
   return 0;
diff --git a/tools/gn/command_gen.cc b/tools/gn/command_gen.cc
index 3d44274..06b99ca 100644
--- a/tools/gn/command_gen.cc
+++ b/tools/gn/command_gen.cc
@@ -11,6 +11,7 @@
 #include "tools/gn/build_settings.h"
 #include "tools/gn/commands.h"
 #include "tools/gn/eclipse_writer.h"
+#include "tools/gn/json_project_writer.h"
 #include "tools/gn/ninja_target_writer.h"
 #include "tools/gn/ninja_writer.h"
 #include "tools/gn/qt_creator_writer.h"
@@ -36,10 +37,14 @@
 const char kSwitchIdeValueVs2013[] = "vs2013";
 const char kSwitchIdeValueVs2015[] = "vs2015";
 const char kSwitchIdeValueXcode[] = "xcode";
+const char kSwitchIdeValueJson[] = "json";
 const char kSwitchNinjaExtraArgs[] = "ninja-extra-args";
 const char kSwitchRootTarget[] = "root-target";
 const char kSwitchSln[] = "sln";
 const char kSwitchWorkspace[] = "workspace";
+const char kSwitchJsonFileName[] = "json-file-name";
+const char kSwitchJsonIdeScript[] = "json-ide-script";
+const char kSwitchJsonIdeScriptArgs[] = "json-ide-script-args";
 
 // Called on worker thread to write the ninja file.
 void BackgroundDoWrite(const Target* target) {
@@ -113,7 +118,7 @@
 
   if (generator) {
     err += "but this file was not generated by any dependencies of the " +
-        target_str + ". The target\nthat generates the file is:\n  ";
+           target_str + ". The target\nthat generates the file is:\n  ";
     err += generator->label().GetUserVisibleName(show_toolchains);
   } else {
     err += "but no targets in the build generate that file.";
@@ -166,11 +171,12 @@
                   Err* err) {
   const base::CommandLine* command_line =
       base::CommandLine::ForCurrentProcess();
+  bool quiet = command_line->HasSwitch(switches::kQuiet);
   base::ElapsedTimer timer;
 
   if (ide == kSwitchIdeValueEclipse) {
     bool res = EclipseWriter::RunAndWriteFile(build_settings, builder, err);
-    if (res && !command_line->HasSwitch(switches::kQuiet)) {
+    if (res && !quiet) {
       OutputString("Generating Eclipse settings took " +
                    base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                    "ms\n");
@@ -189,7 +195,7 @@
       filters = command_line->GetSwitchValueASCII(kSwitchFilters);
     bool res = VisualStudioWriter::RunAndWriteFiles(
         build_settings, builder, version, sln_name, filters, err);
-    if (res && !command_line->HasSwitch(switches::kQuiet)) {
+    if (res && !quiet) {
       OutputString("Generating Visual Studio projects took " +
                    base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                    "ms\n");
@@ -202,7 +208,7 @@
         command_line->GetSwitchValueASCII(kSwitchNinjaExtraArgs),
         command_line->GetSwitchValueASCII(kSwitchFilters), build_settings,
         builder, err);
-    if (res && !command_line->HasSwitch(switches::kQuiet)) {
+    if (res && !quiet) {
       OutputString("Generating Xcode projects took " +
                    base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                    "ms\n");
@@ -214,12 +220,32 @@
       root_target = command_line->GetSwitchValueASCII(kSwitchRootTarget);
     bool res = QtCreatorWriter::RunAndWriteFile(build_settings, builder, err,
                                                 root_target);
-    if (res && !command_line->HasSwitch(switches::kQuiet)) {
+    if (res && !quiet) {
       OutputString("Generating QtCreator projects took " +
                    base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                    "ms\n");
     }
     return res;
+  } else if (ide == kSwitchIdeValueJson) {
+    std::string file_name =
+        command_line->GetSwitchValueASCII(kSwitchJsonFileName);
+    if (file_name.empty())
+      file_name = "project.json";
+    std::string exec_script =
+        command_line->GetSwitchValueASCII(kSwitchJsonIdeScript);
+    std::string exec_script_extra_args =
+        command_line->GetSwitchValueASCII(kSwitchJsonIdeScriptArgs);
+    std::string filters = command_line->GetSwitchValueASCII(kSwitchFilters);
+
+    bool res = JSONProjectWriter::RunAndWriteFiles(
+        build_settings, builder, file_name, exec_script, exec_script_extra_args,
+        filters, quiet, err);
+    if (res && !quiet) {
+      OutputString("Generating JSON projects took " +
+                   base::Int64ToString(timer.Elapsed().InMilliseconds()) +
+                   "ms\n");
+    }
+    return res;
   }
 
   *err = Err(Location(), "Unknown IDE: " + ide);
@@ -229,8 +255,7 @@
 }  // namespace
 
 const char kGen[] = "gen";
-const char kGen_HelpShort[] =
-    "gen: Generate ninja files.";
+const char kGen_HelpShort[] = "gen: Generate ninja files.";
 const char kGen_Help[] =
     "gn gen: Generate ninja files.\n"
     "\n"
@@ -259,12 +284,13 @@
     "      \"vs2015\" - Visual Studio 2015 project/solution files.\n"
     "      \"xcode\" - Xcode workspace/solution files.\n"
     "      \"qtcreator\" - QtCreator project files.\n"
+    "      \"json\" - JSON file containing target information\n"
     "\n"
     "  --filters=<path_prefixes>\n"
     "      Semicolon-separated list of label patterns used to limit the set\n"
     "      of generated projects (see \"gn help label_pattern\"). Only\n"
     "      matching targets and their dependencies will be included in the\n"
-    "      solution. Only used for Visual Studio and Xcode.\n"
+    "      solution. Only used for Visual Studio, Xcode and JSON.\n"
     "\n"
     "Visual Studio Flags\n"
     "\n"
@@ -305,7 +331,27 @@
     "  properly define includes/defines for each file individually.\n"
     "  Instead, one set of includes/defines is generated for the entire\n"
     "  project. This works fairly well but may still result in a few indexer\n"
-    "  issues here and there.\n";
+    "  issues here and there.\n"
+    "\n"
+    "Generic JSON Output\n"
+    "\n"
+    "  Dumps target information to JSON file and optionally invokes python\n"
+    "  script on generated file. \n"
+    "  See comments at the beginning of json_project_writer.cc and\n"
+    "  desc_builder.cc for overview of JSON file format.\n"
+    "\n"
+    "  --json-file-name=<json_file_name>\n"
+    "      Overrides default file name (project.json) of generated JSON file.\n"
+    "\n"
+    "  --json-ide-script=<path_to_python_script>\n"
+    "      Executes python script after the JSON file is generated.\n"
+    "      Path can be project absolute (//), system absolute (/) or\n"
+    "      relative, in which case the output directory will be base.\n"
+    "      Path to generated JSON file will be first argument when invoking\n"
+    "      script.\n"
+    "\n"
+    "  --json-ide-script-args=<argument>\n"
+    "      Optional second argument that will passed to executed script.\n";
 
 int RunGen(const std::vector<std::string>& args) {
   base::ElapsedTimer timer;
diff --git a/tools/gn/commands.cc b/tools/gn/commands.cc
index a646679..492b74f 100644
--- a/tools/gn/commands.cc
+++ b/tools/gn/commands.cc
@@ -6,6 +6,7 @@
 
 #include "base/command_line.h"
 #include "base/strings/string_split.h"
+#include "base/values.h"
 #include "tools/gn/builder.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/item.h"
@@ -280,22 +281,20 @@
   return item->defined_from()->GetRange().begin().file()->physical_name();
 }
 
-void PrintTargetsAsBuildfiles(bool indent,
-                              const std::vector<const Target*>& targets) {
+void PrintTargetsAsBuildfiles(const std::vector<const Target*>& targets,
+                              base::ListValue* out) {
   // Output the set of unique source files.
   std::set<std::string> unique_files;
   for (const Target* target : targets)
     unique_files.insert(FilePathToUTF8(BuildFileForItem(target)));
 
   for (const std::string& file : unique_files) {
-    if (indent)
-      OutputString("  ");
-    OutputString(file + "\n");
+    out->AppendString(file);
   }
 }
 
-void PrintTargetsAsLabels(bool indent,
-                          const std::vector<const Target*>& targets) {
+void PrintTargetsAsLabels(const std::vector<const Target*>& targets,
+                          base::ListValue* out) {
   // Putting the labels into a set automatically sorts them for us.
   std::set<Label> unique_labels;
   for (auto* target : targets)
@@ -307,16 +306,13 @@
 
   for (const Label& label : unique_labels) {
     // Print toolchain only for ones not in the default toolchain.
-    if (indent)
-      OutputString("  ");
-    OutputString(label.GetUserVisibleName(
-        label.GetToolchainLabel() != default_tc_label));
-    OutputString("\n");
+    out->AppendString(label.GetUserVisibleName(label.GetToolchainLabel() !=
+                                               default_tc_label));
   }
 }
 
-void PrintTargetsAsOutputs(bool indent,
-                           const std::vector<const Target*>& targets) {
+void PrintTargetsAsOutputs(const std::vector<const Target*>& targets,
+                           base::ListValue* out) {
   if (targets.empty())
     return;
 
@@ -336,10 +332,7 @@
     std::string result = RebasePath(output_as_source.value(),
                                     build_settings->build_dir(),
                                     build_settings->root_path_utf8());
-    if (indent)
-      OutputString("  ");
-    OutputString(result);
-    OutputString("\n");
+    out->AppendString(result);
   }
 }
 
@@ -490,7 +483,8 @@
   return true;
 }
 
-void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets) {
+void FilterAndPrintTargets(std::vector<const Target*>* targets,
+                           base::ListValue* out) {
   if (targets->empty())
     return;
 
@@ -504,21 +498,40 @@
     return;
   switch (printing_mode) {
     case TARGET_PRINT_BUILDFILE:
-      PrintTargetsAsBuildfiles(indent, *targets);
+      PrintTargetsAsBuildfiles(*targets, out);
       break;
     case TARGET_PRINT_LABEL:
-      PrintTargetsAsLabels(indent, *targets);
+      PrintTargetsAsLabels(*targets, out);
       break;
     case TARGET_PRINT_OUTPUT:
-      PrintTargetsAsOutputs(indent, *targets);
+      PrintTargetsAsOutputs(*targets, out);
       break;
   }
 }
 
+void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets) {
+  base::ListValue tmp;
+  FilterAndPrintTargets(targets, &tmp);
+  for (const auto& value : tmp) {
+    std::string string;
+    value->GetAsString(&string);
+    if (indent)
+      OutputString("  ");
+    OutputString(string);
+    OutputString("\n");
+  }
+}
+
 void FilterAndPrintTargetSet(bool indent,
                              const std::set<const Target*>& targets) {
   std::vector<const Target*> target_vector(targets.begin(), targets.end());
   FilterAndPrintTargets(indent, &target_vector);
 }
 
+void FilterAndPrintTargetSet(const std::set<const Target*>& targets,
+                             base::ListValue* out) {
+  std::vector<const Target*> target_vector(targets.begin(), targets.end());
+  FilterAndPrintTargets(&target_vector, out);
+}
+
 }  // namespace commands
diff --git a/tools/gn/commands.h b/tools/gn/commands.h
index fdd10fc..01bf0ee 100644
--- a/tools/gn/commands.h
+++ b/tools/gn/commands.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include "base/strings/string_piece.h"
+#include "base/values.h"
 #include "tools/gn/target.h"
 #include "tools/gn/unique_vector.h"
 
@@ -179,8 +180,13 @@
 //
 // The vector will be modified so that only the printed targets will remain.
 void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets);
+void FilterAndPrintTargets(std::vector<const Target*>* targets,
+                           base::ListValue* out);
+
 void FilterAndPrintTargetSet(bool indent,
                              const std::set<const Target*>& targets);
+void FilterAndPrintTargetSet(const std::set<const Target*>& targets,
+                             base::ListValue* out);
 
 // Extra help from command_check.cc
 extern const char kNoGnCheck_Help[];
diff --git a/tools/gn/desc_builder.cc b/tools/gn/desc_builder.cc
new file mode 100644
index 0000000..bc8f02a
--- /dev/null
+++ b/tools/gn/desc_builder.cc
@@ -0,0 +1,694 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <set>
+
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "tools/gn/commands.h"
+#include "tools/gn/config.h"
+#include "tools/gn/config_values_extractors.h"
+#include "tools/gn/deps_iterator.h"
+#include "tools/gn/desc_builder.h"
+#include "tools/gn/input_file.h"
+#include "tools/gn/parse_tree.h"
+#include "tools/gn/runtime_deps.h"
+#include "tools/gn/settings.h"
+#include "tools/gn/substitution_writer.h"
+#include "tools/gn/variables.h"
+
+// Example structure of Value for single target
+// (not applicable or empty fields will be ommitted depending on target type)
+//
+// target_properties = {
+//   "type" : "output_type", // matching Target::GetStringForOutputType
+//   "toolchain" : "toolchain_name",
+//   "visibility" : [ list of visibility pattern descriptions ],
+//   "test_only" : true or false,
+//   "check_includes": true or false,
+//   "allow_circular_includes_from": [ list of target names ],
+//   "sources" : [ list of source files ],
+//   "public" : either "*" or [ list of public headers],
+//   "inputs" : [ list of inputs for target ],
+//   "configs" : [ list of configs for this target ],
+//   "public_configs" : [ list of public configs for this taget],
+//   "all_dependent_configs", [ list of all dependent configs for this target],
+//   "script" : "script for action targets",
+//   "args" : [ argument list for action targets ],
+//   "depfile : "file name for action input dependencies",
+//   "outputs" : [ list of target outputs ],
+//   "arflags", "asmflags", "cflags", "cflags_c",
+//   "clfags_cc", "cflags_objc", "clfags_objcc" : [ list of flags],
+//   "defines" : [ list of preprocessor definitions ],
+//   "include_dirs" : [ list of include directories ],
+//   "precompiled_header" : "name of precompiled header file",
+//   "precompiled_source" : "path to precompiled source",
+//   "deps : [ list of target dependencies ],
+//   "libs" : [ list of libraries ],
+//   "lib_dirs" : [ list of library directories ]
+// }
+//
+// Optionally, if "what" is specified while generating description, two other
+// properties can be requested that are not included by default
+//
+// "runtime_deps" : [list of computed runtime dependencies]
+// "source_outputs" : {
+//    "source_file x" : [ list of outputs for source file x ]
+//    "source_file y" : [ list of outputs for source file y ]
+//    ...
+// }
+
+namespace {
+
+std::string FormatSourceDir(const SourceDir& dir) {
+#if defined(OS_WIN)
+  // On Windows we fix up system absolute paths to look like native ones.
+  // Internally, they'll look like "/C:\foo\bar/"
+  if (dir.is_system_absolute()) {
+    std::string buf = dir.value();
+    if (buf.size() > 3 && buf[2] == ':') {
+      buf.erase(buf.begin());  // Erase beginning slash.
+      return buf;
+    }
+  }
+#endif
+  return dir.value();
+}
+
+void RecursiveCollectChildDeps(const Target* target,
+                               std::set<const Target*>* result);
+
+void RecursiveCollectDeps(const Target* target,
+                          std::set<const Target*>* result) {
+  if (result->find(target) != result->end())
+    return;  // Already did this target.
+  result->insert(target);
+
+  RecursiveCollectChildDeps(target, result);
+}
+
+void RecursiveCollectChildDeps(const Target* target,
+                               std::set<const Target*>* result) {
+  for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
+    RecursiveCollectDeps(pair.ptr, result);
+}
+
+// Common functionality for target and config description builder
+class BaseDescBuilder {
+ public:
+  typedef std::unique_ptr<base::Value> ValuePtr;
+
+  BaseDescBuilder(const std::set<std::string>& what,
+                  bool all,
+                  bool tree,
+                  bool blame)
+      : what_(what), all_(all), tree_(tree), blame_(blame) {}
+
+ protected:
+  virtual Label GetToolchainLabel() const = 0;
+
+  bool what(const std::string& w) const {
+    return what_.empty() || what_.find(w) != what_.end();
+  }
+
+  template <typename T>
+  ValuePtr RenderValue(const std::vector<T>& vector) {
+    auto res = base::WrapUnique(new base::ListValue());
+    for (const auto& v : vector)
+      res->Append(RenderValue(v));
+
+    return std::move(res);
+  }
+
+  ValuePtr RenderValue(const std::string& s, bool optional = false) {
+    return (s.empty() && optional) ? base::Value::CreateNullValue()
+                                   : ValuePtr(new base::StringValue(s));
+  }
+
+  ValuePtr RenderValue(const SourceDir& d) {
+    return d.is_null() ? base::Value::CreateNullValue()
+                       : ValuePtr(new base::StringValue(FormatSourceDir(d)));
+  }
+
+  ValuePtr RenderValue(const SourceFile& f) {
+    return f.is_null() ? base::Value::CreateNullValue()
+                       : ValuePtr(new base::StringValue(f.value()));
+  }
+
+  ValuePtr RenderValue(const LibFile& lib) {
+    if (lib.is_source_file())
+      return RenderValue(lib.source_file());
+    return RenderValue(lib.value());
+  }
+
+  template <class VectorType>
+  void FillInConfigVector(base::ListValue* out,
+                          const VectorType& configs,
+                          int indent = 0) {
+    for (const auto& config : configs) {
+      std::string name(indent * 2, ' ');
+      name.append(config.label.GetUserVisibleName(GetToolchainLabel()));
+      out->AppendString(name);
+      if (tree_)
+        FillInConfigVector(out, config.ptr->configs(), indent + 1);
+    }
+  }
+
+  void FillInPrecompiledHeader(base::DictionaryValue* out,
+                               const ConfigValues& values) {
+    if (what(variables::kPrecompiledHeader) &&
+        !values.precompiled_header().empty()) {
+      out->Set(variables::kPrecompiledHeader,
+               RenderValue(values.precompiled_header(), true));
+    }
+    if (what(variables::kPrecompiledSource) &&
+        !values.precompiled_source().is_null()) {
+      out->Set(variables::kPrecompiledSource,
+               RenderValue(values.precompiled_source()));
+    }
+  }
+
+  std::set<std::string> what_;
+  bool all_;
+  bool tree_;
+  bool blame_;
+};
+
+class ConfigDescBuilder : public BaseDescBuilder {
+ public:
+  ConfigDescBuilder(const Config* config, const std::set<std::string>& what)
+      : BaseDescBuilder(what, false, false, false), config_(config) {}
+
+  std::unique_ptr<base::DictionaryValue> BuildDescription() {
+    auto res = base::WrapUnique(new base::DictionaryValue());
+    const ConfigValues& values = config_->resolved_values();
+
+    if (what_.empty())
+      res->SetString(
+          "toolchain",
+          config_->label().GetToolchainLabel().GetUserVisibleName(false));
+
+    if (what(variables::kConfigs) && !config_->configs().empty()) {
+      auto configs = base::WrapUnique(new base::ListValue());
+      FillInConfigVector(configs.get(), config_->configs().vector());
+      res->Set(variables::kConfigs, std::move(configs));
+    }
+
+#define CONFIG_VALUE_ARRAY_HANDLER(name, type)                        \
+  if (what(#name)) {                                                  \
+    ValuePtr ptr =                                                    \
+        render_config_value_array<type>(values, &ConfigValues::name); \
+    if (ptr) {                                                        \
+      res->Set(#name, std::move(ptr));                                \
+    }                                                                 \
+  }
+    CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
+    CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(lib_dirs, SourceDir)
+    CONFIG_VALUE_ARRAY_HANDLER(libs, LibFile)
+
+#undef CONFIG_VALUE_ARRAY_HANDLER
+
+    FillInPrecompiledHeader(res.get(), values);
+
+    return res;
+  }
+
+ protected:
+  Label GetToolchainLabel() const override {
+    return config_->label().GetToolchainLabel();
+  }
+
+ private:
+  template <typename T>
+  ValuePtr render_config_value_array(
+      const ConfigValues& values,
+      const std::vector<T>& (ConfigValues::*getter)() const) {
+    auto res = base::WrapUnique(new base::ListValue());
+
+    for (const T& cur : (values.*getter)())
+      res->Append(RenderValue(cur));
+
+    return res->empty() ? nullptr : std::move(res);
+  }
+
+  const Config* config_;
+};
+
+class TargetDescBuilder : public BaseDescBuilder {
+ public:
+  TargetDescBuilder(const Target* target,
+                    const std::set<std::string>& what,
+                    bool all,
+                    bool tree,
+                    bool blame)
+      : BaseDescBuilder(what, all, tree, blame), target_(target) {}
+
+  std::unique_ptr<base::DictionaryValue> BuildDescription() {
+    auto res = base::WrapUnique(new base::DictionaryValue());
+    bool is_binary_output = target_->IsBinary();
+
+    if (what_.empty()) {
+      res->SetString("type",
+                     Target::GetStringForOutputType(target_->output_type()));
+      res->SetString(
+          "toolchain",
+          target_->label().GetToolchainLabel().GetUserVisibleName(false));
+    }
+
+    // General target meta variables.
+    if (what(variables::kVisibility))
+      res->Set(variables::kVisibility, target_->visibility().AsValue());
+
+    if (what(variables::kTestonly))
+      res->SetBoolean(variables::kTestonly, target_->testonly());
+
+    if (is_binary_output) {
+      if (what(variables::kCheckIncludes))
+        res->SetBoolean(variables::kCheckIncludes, target_->check_includes());
+
+      if (what(variables::kAllowCircularIncludesFrom)) {
+        auto labels = base::WrapUnique(new base::ListValue());
+        for (const auto& cur : target_->allow_circular_includes_from())
+          labels->AppendString(cur.GetUserVisibleName(GetToolchainLabel()));
+
+        res->Set(variables::kAllowCircularIncludesFrom, std::move(labels));
+      }
+    }
+
+    if (what(variables::kSources) && !target_->sources().empty())
+      res->Set(variables::kSources, RenderValue(target_->sources()));
+
+    if (what(variables::kOutputName) && !target_->output_name().empty())
+      res->SetString(variables::kOutputName, target_->output_name());
+
+    if (what(variables::kOutputDir) && !target_->output_dir().is_null())
+      res->Set(variables::kOutputDir, RenderValue(target_->output_dir()));
+
+    if (what(variables::kOutputExtension) && target_->output_extension_set())
+      res->SetString(variables::kOutputExtension, target_->output_extension());
+
+    if (what(variables::kPublic)) {
+      if (target_->all_headers_public())
+        res->SetString(variables::kPublic, "*");
+      else
+        res->Set(variables::kPublic, RenderValue(target_->public_headers()));
+    }
+
+    if (what(variables::kInputs) && !target_->inputs().empty())
+      res->Set(variables::kInputs, RenderValue(target_->inputs()));
+
+    if (is_binary_output && what(variables::kConfigs) &&
+        !target_->configs().empty()) {
+      auto configs = base::WrapUnique(new base::ListValue());
+      FillInConfigVector(configs.get(), target_->configs().vector());
+      res->Set(variables::kConfigs, std::move(configs));
+    }
+
+    if (what(variables::kPublicConfigs) && !target_->public_configs().empty()) {
+      auto configs = base::WrapUnique(new base::ListValue());
+      FillInConfigVector(configs.get(), target_->public_configs());
+      res->Set(variables::kPublicConfigs, std::move(configs));
+    }
+
+    if (what(variables::kAllDependentConfigs) &&
+        !target_->all_dependent_configs().empty()) {
+      auto configs = base::WrapUnique(new base::ListValue());
+      FillInConfigVector(configs.get(), target_->all_dependent_configs());
+      res->Set(variables::kAllDependentConfigs, std::move(configs));
+    }
+
+    // Action
+    if (target_->output_type() == Target::ACTION ||
+        target_->output_type() == Target::ACTION_FOREACH) {
+      if (what(variables::kScript))
+        res->SetString(variables::kScript,
+                       target_->action_values().script().value());
+
+      if (what(variables::kArgs)) {
+        auto args = base::WrapUnique(new base::ListValue());
+        for (const auto& elem : target_->action_values().args().list())
+          args->AppendString(elem.AsString());
+
+        res->Set(variables::kArgs, std::move(args));
+      }
+      if (what(variables::kDepfile) &&
+          !target_->action_values().depfile().empty()) {
+        res->SetString(variables::kDepfile,
+                       target_->action_values().depfile().AsString());
+      }
+    }
+
+    if (target_->output_type() != Target::SOURCE_SET &&
+        target_->output_type() != Target::GROUP &&
+        target_->output_type() != Target::BUNDLE_DATA) {
+      if (what(variables::kOutputs))
+        FillInOutputs(res.get());
+    }
+
+    // Source outputs are only included when specifically asked for it
+    if (what_.find("source_outputs") != what_.end())
+      FillInSourceOutputs(res.get());
+
+    if (target_->output_type() == Target::CREATE_BUNDLE && what("bundle_data"))
+      FillInBundle(res.get());
+
+    if (is_binary_output) {
+#define CONFIG_VALUE_ARRAY_HANDLER(name, type)                    \
+  if (what(#name)) {                                              \
+    ValuePtr ptr = RenderConfigValues<type>(&ConfigValues::name); \
+    if (ptr) {                                                    \
+      res->Set(#name, std::move(ptr));                            \
+    }                                                             \
+  }
+      CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
+      CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
+      CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
+      CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
+      CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
+      CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
+      CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
+      CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
+      CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
+      CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
+#undef CONFIG_VALUE_ARRAY_HANDLER
+
+      // Libs and lib_dirs are handled specially below.
+
+      FillInPrecompiledHeader(res.get(), target_->config_values());
+    }
+
+    if (what(variables::kDeps))
+      res->Set(variables::kDeps, RenderDeps());
+
+    // Runtime deps are special, print only when explicitly asked for and not in
+    // overview mode.
+    if (what_.find("runtime_deps") != what_.end())
+      res->Set("runtime_deps", RenderRuntimeDeps());
+
+    // libs and lib_dirs are special in that they're inherited. We don't
+    // currently
+    // implement a blame feature for this since the bottom-up inheritance makes
+    // this difficult.
+
+    // Libs can be part of any target and get recursively pushed up the chain,
+    // so display them regardless of target type.
+    if (what(variables::kLibs)) {
+      const OrderedSet<LibFile>& all_libs = target_->all_libs();
+      if (!all_libs.empty()) {
+        auto libs = base::WrapUnique(new base::ListValue());
+        for (size_t i = 0; i < all_libs.size(); i++)
+          libs->AppendString(all_libs[i].value());
+        res->Set(variables::kLibs, std::move(libs));
+      }
+    }
+
+    if (what(variables::kLibDirs)) {
+      const OrderedSet<SourceDir>& all_lib_dirs = target_->all_lib_dirs();
+      if (!all_lib_dirs.empty()) {
+        auto lib_dirs = base::WrapUnique(new base::ListValue());
+        for (size_t i = 0; i < all_lib_dirs.size(); i++)
+          lib_dirs->AppendString(FormatSourceDir(all_lib_dirs[i]));
+        res->Set(variables::kLibDirs, std::move(lib_dirs));
+      }
+    }
+
+    return res;
+  }
+
+ private:
+  // Prints dependencies of the given target (not the target itself). If the
+  // set is non-null, new targets encountered will be added to the set, and if
+  // a dependency is in the set already, it will not be recused into. When the
+  // set is null, all dependencies will be printed.
+  void RecursivePrintDeps(base::ListValue* out,
+                          const Target* target,
+                          std::set<const Target*>* seen_targets,
+                          int indent_level) {
+    // Combine all deps into one sorted list.
+    std::vector<LabelTargetPair> sorted_deps;
+    for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
+      sorted_deps.push_back(pair);
+    std::sort(sorted_deps.begin(), sorted_deps.end(),
+              LabelPtrLabelLess<Target>());
+
+    std::string indent(indent_level * 2, ' ');
+
+    for (const auto& pair : sorted_deps) {
+      const Target* cur_dep = pair.ptr;
+      std::string str =
+          indent + cur_dep->label().GetUserVisibleName(GetToolchainLabel());
+
+      bool print_children = true;
+      if (seen_targets) {
+        if (seen_targets->find(cur_dep) == seen_targets->end()) {
+          // New target, mark it visited.
+          seen_targets->insert(cur_dep);
+        } else {
+          // Already seen.
+          print_children = false;
+          // Only print "..." if something is actually elided, which means that
+          // the current target has children.
+          if (!cur_dep->public_deps().empty() ||
+              !cur_dep->private_deps().empty() || !cur_dep->data_deps().empty())
+            str += "...";
+        }
+      }
+
+      out->AppendString(str);
+
+      if (print_children)
+        RecursivePrintDeps(out, cur_dep, seen_targets, indent_level + 1);
+    }
+  }
+
+  ValuePtr RenderDeps() {
+    auto res = base::WrapUnique(new base::ListValue());
+
+    // Tree mode is separate.
+    if (tree_) {
+      if (all_) {
+        // Show all tree deps with no eliding.
+        RecursivePrintDeps(res.get(), target_, nullptr, 0);
+      } else {
+        // Don't recurse into duplicates.
+        std::set<const Target*> seen_targets;
+        RecursivePrintDeps(res.get(), target_, &seen_targets, 0);
+      }
+    } else {  // not tree
+
+      // Collect the deps to display.
+      if (all_) {
+        // Show all dependencies.
+        std::set<const Target*> all_deps;
+        RecursiveCollectChildDeps(target_, &all_deps);
+        commands::FilterAndPrintTargetSet(all_deps, res.get());
+      } else {
+        // Show direct dependencies only.
+        std::vector<const Target*> deps;
+        for (const auto& pair : target_->GetDeps(Target::DEPS_ALL))
+          deps.push_back(pair.ptr);
+        std::sort(deps.begin(), deps.end());
+        commands::FilterAndPrintTargets(&deps, res.get());
+      }
+    }
+
+    return std::move(res);
+  }
+
+  ValuePtr RenderRuntimeDeps() {
+    auto res = base::WrapUnique(new base::ListValue());
+
+    const Target* previous_from = NULL;
+    for (const auto& pair : ComputeRuntimeDeps(target_)) {
+      std::string str;
+      if (blame_) {
+        // Generally a target's runtime deps will be listed sequentially, so
+        // group them and don't duplicate the "from" label for two in a row.
+        if (previous_from == pair.second) {
+          str = "  ";
+        } else {
+          previous_from = pair.second;
+          res->AppendString(
+              str + "From " +
+              pair.second->label().GetUserVisibleName(GetToolchainLabel()));
+          str = "  ";
+        }
+      }
+
+      res->AppendString(str + pair.first.value());
+    }
+
+    return std::move(res);
+  }
+
+  void FillInSourceOutputs(base::DictionaryValue* res) {
+    auto dict = base::WrapUnique(new base::DictionaryValue());
+    for (const auto& source : target_->sources()) {
+      std::vector<OutputFile> outputs;
+      Toolchain::ToolType tool_type = Toolchain::TYPE_NONE;
+      if (target_->GetOutputFilesForSource(source, &tool_type, &outputs)) {
+        auto list = base::WrapUnique(new base::ListValue());
+        for (const auto& output : outputs)
+          list->AppendString(output.value());
+
+        dict->SetWithoutPathExpansion(source.value(), std::move(list));
+      }
+    }
+    res->Set("source_outputs", std::move(dict));
+  }
+
+  void FillInBundle(base::DictionaryValue* res) {
+    auto data = base::WrapUnique(new base::DictionaryValue());
+    const BundleData& bundle_data = target_->bundle_data();
+    const Settings* settings = target_->settings();
+    BundleData::SourceFiles sources;
+    bundle_data.GetSourceFiles(&sources);
+    data->Set("source_files", RenderValue(sources));
+    data->SetString("root_dir_output",
+                    bundle_data.GetBundleRootDirOutput(settings).value());
+    data->Set("root_dir", RenderValue(bundle_data.root_dir()));
+    data->Set("resources_dir", RenderValue(bundle_data.resources_dir()));
+    data->Set("executable_dir", RenderValue(bundle_data.executable_dir()));
+    data->Set("plugins_dir", RenderValue(bundle_data.plugins_dir()));
+    data->SetString("product_type", bundle_data.product_type());
+
+    auto deps = base::WrapUnique(new base::ListValue());
+    for (const auto* dep : bundle_data.bundle_deps())
+      deps->AppendString(dep->label().GetUserVisibleName(GetToolchainLabel()));
+
+    data->Set("deps", std::move(deps));
+    res->Set("bundle_data", std::move(data));
+  }
+
+  void FillInOutputs(base::DictionaryValue* res) {
+    if (target_->output_type() == Target::ACTION) {
+      auto list = base::WrapUnique(new base::ListValue());
+      for (const auto& elem : target_->action_values().outputs().list())
+        list->AppendString(elem.AsString());
+
+      res->Set(variables::kOutputs, std::move(list));
+    } else if (target_->output_type() == Target::CREATE_BUNDLE) {
+      std::vector<SourceFile> output_files;
+      target_->bundle_data().GetOutputsAsSourceFiles(target_->settings(),
+                                                     &output_files);
+      res->Set(variables::kOutputs, RenderValue(output_files));
+    } else if (target_->output_type() == Target::ACTION_FOREACH ||
+               target_->output_type() == Target::COPY_FILES) {
+      const SubstitutionList& outputs = target_->action_values().outputs();
+      if (!outputs.required_types().empty()) {
+        auto patterns = base::WrapUnique(new base::ListValue());
+        for (const auto& elem : outputs.list())
+          patterns->AppendString(elem.AsString());
+
+        res->Set("output_patterns", std::move(patterns));
+      }
+      std::vector<SourceFile> output_files;
+      SubstitutionWriter::ApplyListToSources(target_->settings(), outputs,
+                                             target_->sources(), &output_files);
+      res->Set(variables::kOutputs, RenderValue(output_files));
+    } else {
+      DCHECK(target_->IsBinary());
+      const Tool* tool =
+          target_->toolchain()->GetToolForTargetFinalOutput(target_);
+
+      std::vector<OutputFile> output_files;
+      SubstitutionWriter::ApplyListToLinkerAsOutputFile(
+          target_, tool, tool->outputs(), &output_files);
+      std::vector<SourceFile> output_files_as_source_file;
+      for (const OutputFile& output_file : output_files)
+        output_files_as_source_file.push_back(
+            output_file.AsSourceFile(target_->settings()->build_settings()));
+
+      res->Set(variables::kOutputs, RenderValue(output_files_as_source_file));
+    }
+  }
+
+  // Writes a given config value type to the string, optionally with
+  // attribution.
+  // This should match RecursiveTargetConfigToStream in the order it traverses.
+  template <class T>
+  ValuePtr RenderConfigValues(const std::vector<T>& (ConfigValues::*getter)()
+                                  const) {
+    auto res = base::WrapUnique(new base::ListValue());
+    for (ConfigValuesIterator iter(target_); !iter.done(); iter.Next()) {
+      const std::vector<T>& vec = (iter.cur().*getter)();
+
+      if (vec.empty())
+        continue;
+
+      if (blame_) {
+        const Config* config = iter.GetCurrentConfig();
+        if (config) {
+          // Source of this value is a config.
+          std::string from =
+              "From " + config->label().GetUserVisibleName(false);
+          res->AppendString(from);
+          if (iter.origin()) {
+            Location location = iter.origin()->GetRange().begin();
+            from = "     (Added by " + location.file()->name().value() + ":" +
+                   base::IntToString(location.line_number()) + ")";
+            res->AppendString(from);
+          }
+        } else {
+          // Source of this value is the target itself.
+          std::string from =
+              "From " + target_->label().GetUserVisibleName(false);
+          res->AppendString(from);
+        }
+      }
+
+      for (const T& val : vec) {
+        ValuePtr rendered = RenderValue(val);
+        std::string str;
+        // Indent string values in blame mode
+        if (blame_ && rendered->GetAsString(&str)) {
+          str = "  " + str;
+          rendered = base::WrapUnique(new base::StringValue(str));
+        }
+        res->Append(std::move(rendered));
+      }
+    }
+    return res->empty() ? nullptr : std::move(res);
+  }
+
+  Label GetToolchainLabel() const override {
+    return target_->label().GetToolchainLabel();
+  }
+
+  const Target* target_;
+};
+
+}  // namespace
+
+std::unique_ptr<base::DictionaryValue> DescBuilder::DescriptionForTarget(
+    const Target* target,
+    const std::string& what,
+    bool all,
+    bool tree,
+    bool blame) {
+  std::set<std::string> w;
+  if (!what.empty())
+    w.insert(what);
+  TargetDescBuilder b(target, w, all, tree, blame);
+  return b.BuildDescription();
+}
+
+std::unique_ptr<base::DictionaryValue> DescBuilder::DescriptionForConfig(
+    const Config* config,
+    const std::string& what) {
+  std::set<std::string> w;
+  if (!what.empty())
+    w.insert(what);
+  ConfigDescBuilder b(config, w);
+  return b.BuildDescription();
+}
diff --git a/tools/gn/desc_builder.h b/tools/gn/desc_builder.h
new file mode 100644
index 0000000..1f0c395
--- /dev/null
+++ b/tools/gn/desc_builder.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_GN_DESC_BUILDER_H_
+#define TOOLS_GN_DESC_BUILDER_H_
+
+#include "base/values.h"
+#include "tools/gn/target.h"
+
+class DescBuilder {
+ public:
+  // Creates Dictionary representation for given target
+  static std::unique_ptr<base::DictionaryValue> DescriptionForTarget(
+      const Target* target,
+      const std::string& what,
+      bool all,
+      bool tree,
+      bool blame);
+
+  // Creates Dictionary representation for given config
+  static std::unique_ptr<base::DictionaryValue> DescriptionForConfig(
+      const Config* config,
+      const std::string& what);
+};
+
+#endif
diff --git a/tools/gn/gn.gyp b/tools/gn/gn.gyp
index ae486bb..6852ffe 100644
--- a/tools/gn/gn.gyp
+++ b/tools/gn/gn.gyp
@@ -58,6 +58,8 @@
         'create_bundle_target_generator.h',
         'deps_iterator.cc',
         'deps_iterator.h',
+        'desc_builder.cc',
+        'desc_builder.h',
         'eclipse_writer.cc',
         'eclipse_writer.h',
         'err.cc',
@@ -101,6 +103,8 @@
         'input_file_manager.h',
         'item.cc',
         'item.h',
+        'json_project_writer.cc',
+        'json_project_writer.h',
         'label.cc',
         'label.h',
         'label_pattern.cc',
diff --git a/tools/gn/json_project_writer.cc b/tools/gn/json_project_writer.cc
new file mode 100644
index 0000000..272a288
--- /dev/null
+++ b/tools/gn/json_project_writer.cc
@@ -0,0 +1,217 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tools/gn/json_project_writer.h"
+
+#include <iostream>
+
+#include "base/command_line.h"
+#include "base/json/json_writer.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "tools/gn/builder.h"
+#include "tools/gn/commands.h"
+#include "tools/gn/deps_iterator.h"
+#include "tools/gn/desc_builder.h"
+#include "tools/gn/exec_process.h"
+#include "tools/gn/filesystem_utils.h"
+#include "tools/gn/settings.h"
+
+// Structure of JSON output file
+// {
+//   "build_settings" = {
+//     "root_path" : "absolute path of project root",
+//     "build_dir" : "build directory (project relative)",
+//     "default_toolchain" : "name of default toolchain"
+//   }
+//   "targets" = {
+//      "target x name" : { target x properties },
+//      "target y name" : { target y properties },
+//      ...
+//    }
+// }
+// See desc_builder.cc for overview of target properties
+
+namespace {
+
+void AddTargetDependencies(const Target* target,
+                           std::set<const Target*>* deps) {
+  for (const auto& pair : target->GetDeps(Target::DEPS_LINKED)) {
+    if (deps->find(pair.ptr) == deps->end()) {
+      deps->insert(pair.ptr);
+      AddTargetDependencies(pair.ptr, deps);
+    }
+  }
+}
+
+// Filters targets according to filter string; Will also recursively
+// add dependent targets.
+bool FilterTargets(const BuildSettings* build_settings,
+                   std::vector<const Target*>& all_targets,
+                   std::vector<const Target*>* targets,
+                   const std::string& dir_filter_string,
+                   Err* err) {
+  if (dir_filter_string.empty()) {
+    *targets = all_targets;
+  } else {
+    targets->reserve(all_targets.size());
+    std::vector<LabelPattern> filters;
+    if (!commands::FilterPatternsFromString(build_settings, dir_filter_string,
+                                            &filters, err)) {
+      return false;
+    }
+    commands::FilterTargetsByPatterns(all_targets, filters, targets);
+
+    std::set<const Target*> target_set(targets->begin(), targets->end());
+    for (const auto* target : *targets)
+      AddTargetDependencies(target, &target_set);
+
+    targets->clear();
+    targets->insert(targets->end(), target_set.begin(), target_set.end());
+  }
+
+  // Sort the list of targets per-label to get a consistent ordering of them
+  // in the generated project (and thus stability of the file generated).
+  std::sort(targets->begin(), targets->end(),
+            [](const Target* a, const Target* b) {
+              return a->label().name() < b->label().name();
+            });
+
+  return true;
+}
+
+std::string RenderJSON(const BuildSettings* build_settings,
+                       const Builder* builder,
+                       std::vector<const Target*>& all_targets) {
+  Label default_toolchain_label;
+
+  auto targets = base::WrapUnique(new base::DictionaryValue());
+  for (const auto* target : all_targets) {
+    if (default_toolchain_label.is_null())
+      default_toolchain_label = target->settings()->default_toolchain_label();
+    auto description =
+        DescBuilder::DescriptionForTarget(target, "", false, false, false);
+    // Outputs need to be asked for separately.
+    auto outputs = DescBuilder::DescriptionForTarget(target, "source_outputs",
+                                                     false, false, false);
+    base::DictionaryValue* outputs_value = nullptr;
+    if (outputs->GetDictionary("source_outputs", &outputs_value) &&
+        !outputs_value->empty()) {
+      description->MergeDictionary(outputs.get());
+    }
+    targets->Set(target->label().GetUserVisibleName(default_toolchain_label),
+                 std::move(description));
+  }
+
+  auto settings = base::WrapUnique(new base::DictionaryValue());
+  settings->SetString("root_path", build_settings->root_path_utf8());
+  settings->SetString("build_dir", build_settings->build_dir().value());
+  settings->SetString("default_toolchain",
+                      default_toolchain_label.GetUserVisibleName(false));
+
+  auto output = base::WrapUnique(new base::DictionaryValue());
+  output->Set("targets", std::move(targets));
+  output->Set("build_settings", std::move(settings));
+
+  std::string s;
+  base::JSONWriter::WriteWithOptions(
+      *output.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &s);
+  return s;
+}
+
+bool InvokePython(const BuildSettings* build_settings,
+                  const base::FilePath& python_script_path,
+                  const std::string& python_script_extra_args,
+                  const base::FilePath& output_path,
+                  bool quiet,
+                  Err* err) {
+  const base::FilePath& python_path = build_settings->python_path();
+  base::CommandLine cmdline(python_path);
+  cmdline.AppendArg("--");
+  cmdline.AppendArgPath(python_script_path);
+  cmdline.AppendArgPath(output_path);
+  if (!python_script_extra_args.empty()) {
+    cmdline.AppendArg(python_script_extra_args);
+  }
+  base::FilePath startup_dir =
+      build_settings->GetFullPath(build_settings->build_dir());
+
+  std::string output;
+  std::string stderr_output;
+
+  int exit_code = 0;
+  if (!internal::ExecProcess(cmdline, startup_dir, &output, &stderr_output,
+                             &exit_code)) {
+    *err =
+        Err(Location(), "Could not execute python.",
+            "I was trying to execute \"" + FilePathToUTF8(python_path) + "\".");
+    return false;
+  }
+
+  if (!quiet) {
+    std::cout << output;
+    std::cerr << stderr_output;
+  }
+
+  if (exit_code != 0) {
+    *err = Err(Location(), "Python has quit with exit code " +
+                               base::IntToString(exit_code) + ".");
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace
+
+bool JSONProjectWriter::RunAndWriteFiles(
+    const BuildSettings* build_settings,
+    const Builder* builder,
+    const std::string& file_name,
+    const std::string& exec_script,
+    const std::string& exec_script_extra_args,
+    const std::string& dir_filter_string,
+    bool quiet,
+    Err* err) {
+  SourceFile output_file = build_settings->build_dir().ResolveRelativeFile(
+      Value(nullptr, file_name), err);
+  if (output_file.is_null()) {
+    return false;
+  }
+
+  base::FilePath output_path = build_settings->GetFullPath(output_file);
+
+  std::vector<const Target*> all_targets = builder->GetAllResolvedTargets();
+  std::vector<const Target*> targets;
+  if (!FilterTargets(build_settings, all_targets, &targets, dir_filter_string,
+                     err)) {
+    return false;
+  }
+
+  std::string json = RenderJSON(build_settings, builder, targets);
+  if (!ContentsEqual(output_path, json)) {
+    if (!WriteFileIfChanged(output_path, json, err)) {
+      return false;
+    }
+
+    if (!exec_script.empty()) {
+      SourceFile script_file;
+      if (exec_script[0] != '/') {
+        // Relative path, assume the base is in build_dir.
+        script_file = build_settings->build_dir().ResolveRelativeFile(
+            Value(nullptr, exec_script), err);
+        if (script_file.is_null()) {
+          return false;
+        }
+      } else {
+        script_file = SourceFile(exec_script);
+      }
+      base::FilePath script_path = build_settings->GetFullPath(script_file);
+      return InvokePython(build_settings, script_path, exec_script_extra_args,
+                          output_path, quiet, err);
+    }
+  }
+
+  return true;
+}
diff --git a/tools/gn/json_project_writer.h b/tools/gn/json_project_writer.h
new file mode 100644
index 0000000..e69dc3a
--- /dev/null
+++ b/tools/gn/json_project_writer.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_GN_JSON_WRITER_H_
+#define TOOLS_GN_JSON_WRITER_H_
+
+#include "tools/gn/err.h"
+#include "tools/gn/target.h"
+
+class Builder;
+class BuildSettings;
+
+class JSONProjectWriter {
+ public:
+  static bool RunAndWriteFiles(const BuildSettings* build_setting,
+                               const Builder* builder,
+                               const std::string& file_name,
+                               const std::string& exec_script,
+                               const std::string& exec_script_extra_args,
+                               const std::string& dir_filter_string,
+                               bool quiet,
+                               Err* err);
+};
+
+#endif
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index aa1fcf6..9851035 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -14,6 +14,7 @@
 #include "tools/gn/config_values_extractors.h"
 #include "tools/gn/deps_iterator.h"
 #include "tools/gn/filesystem_utils.h"
+#include "tools/gn/functions.h"
 #include "tools/gn/scheduler.h"
 #include "tools/gn/source_file_type.h"
 #include "tools/gn/substitution_writer.h"
@@ -215,29 +216,29 @@
 const char* Target::GetStringForOutputType(OutputType type) {
   switch (type) {
     case UNKNOWN:
-      return "Unknown";
+      return "unknown";
     case GROUP:
-      return "Group";
+      return functions::kGroup;
     case EXECUTABLE:
-      return "Executable";
+      return functions::kExecutable;
     case LOADABLE_MODULE:
-      return "Loadable module";
+      return functions::kLoadableModule;
     case SHARED_LIBRARY:
-      return "Shared library";
+      return functions::kSharedLibrary;
     case STATIC_LIBRARY:
-      return "Static library";
+      return functions::kStaticLibrary;
     case SOURCE_SET:
-      return "Source set";
+      return functions::kSourceSet;
     case COPY_FILES:
-      return "Copy";
+      return functions::kCopy;
     case ACTION:
-      return "Action";
+      return functions::kAction;
     case ACTION_FOREACH:
-      return "ActionForEach";
+      return functions::kActionForEach;
     case BUNDLE_DATA:
-      return "Bundle data";
+      return functions::kBundleData;
     case CREATE_BUNDLE:
-      return "Create bundle";
+      return functions::kCreateBundle;
     default:
       return "";
   }
diff --git a/tools/gn/visibility.cc b/tools/gn/visibility.cc
index a61a5cd..b32586c 100644
--- a/tools/gn/visibility.cc
+++ b/tools/gn/visibility.cc
@@ -4,8 +4,10 @@
 
 #include "tools/gn/visibility.h"
 
+#include "base/memory/ptr_util.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
+#include "base/values.h"
 #include "tools/gn/err.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/item.h"
@@ -83,6 +85,14 @@
   return result;
 }
 
+std::unique_ptr<base::Value> Visibility::AsValue() const {
+  auto* res = new base::ListValue();
+  for (const auto& pattern : patterns_)
+    res->AppendString(pattern.Describe());
+
+  return WrapUnique(res);
+}
+
 // static
 bool Visibility::CheckItemVisibility(const Item* from,
                                      const Item* to,
@@ -93,7 +103,7 @@
         "The item " + from->label().GetUserVisibleName(false) + "\n"
         "can not depend on " + to_label + "\n"
         "because it is not in " + to_label + "'s visibility list: " +
-        to->visibility().Describe(0, true));
+                   to->visibility().Describe(0, true));
     return false;
   }
   return true;
diff --git a/tools/gn/visibility.h b/tools/gn/visibility.h
index d6d7f1f..4228f9d 100644
--- a/tools/gn/visibility.h
+++ b/tools/gn/visibility.h
@@ -5,12 +5,17 @@
 #ifndef TOOLS_GN_VISIBILITY_H_
 #define TOOLS_GN_VISIBILITY_H_
 
+#include <memory>
 #include <vector>
 
 #include "base/macros.h"
 #include "tools/gn/label_pattern.h"
 #include "tools/gn/source_dir.h"
 
+namespace base {
+class Value;
+}
+
 class Err;
 class Item;
 class Label;
@@ -43,6 +48,9 @@
   // result will end in a newline.
   std::string Describe(int indent, bool include_brackets) const;
 
+  // Returns value representation of this visibility
+  std::unique_ptr<base::Value> AsValue() const;
+
   // Helper function to check visibility between the given two items. If
   // to is invisible to from, returns false and sets the error.
   static bool CheckItemVisibility(const Item* from, const Item* to, Err* err);
