+ bits->used[static_cast<size_t>(ranges_[i].type)] = true;
+ }
+}
+
+bool SubstitutionPattern::IsInOutputDir(const BuildSettings* build_settings,
+ Err* err) const {
+ if (ranges_.empty()) {
+ *err = Err(origin_, "This is empty but I was expecting an output file.");
+ return false;
+ }
+
+ if (ranges_[0].type == SUBSTITUTION_LITERAL) {
+ // If the first thing is a literal, it must start with the output dir.
+ if (!EnsureStringIsInOutputDir(
+ build_settings->build_dir(),
+ ranges_[0].literal, origin_, err))
+ return false;
+ } else {
+ // Otherwise, the first subrange must be a pattern that expands to
+ // something in the output directory.
+ if (!SubstitutionIsInOutputDir(ranges_[0].type)) {
+ *err = Err(origin_,
+ "File is not inside output directory.",
+ "The given file should be in the output directory. Normally you\n"
+ "would specify\n\"$target_out_dir/foo\" or "
+ "\"{{source_gen_dir}}/foo\".");
+ return false;
+ }