// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.
//
// Utility class for writing text to a ZeroCopyOutputStream.

#ifndef GOOGLE_PROTOBUF_IO_PRINTER_H__
#define GOOGLE_PROTOBUF_IO_PRINTER_H__

#include <cstddef>
#include <functional>
#include <initializer_list>
#include <map>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include "google/protobuf/stubs/logging.h"
#include "google/protobuf/stubs/common.h"
#include "absl/cleanup/cleanup.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/function_ref.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "google/protobuf/io/zero_copy_sink.h"


// Must be included last.
#include "google/protobuf/port_def.inc"

namespace google {
namespace protobuf {
namespace io {
// Records annotations about a Printer's output.
class PROTOBUF_EXPORT AnnotationCollector {
 public:
  // Annotation is a offset range and a payload pair. This payload's layout is
  // specific to derived types of AnnotationCollector.
  using Annotation = std::pair<std::pair<size_t, size_t>, std::string>;

  virtual ~AnnotationCollector() = default;

  // Records that the bytes in file_path beginning with begin_offset and ending
  // before end_offset are associated with the SourceCodeInfo-style path.
  virtual void AddAnnotation(size_t begin_offset, size_t end_offset,
                             const std::string& file_path,
                             const std::vector<int>& path) = 0;

  // TODO(gerbens) I don't see why we need virtuals here. Just a vector of
  // range, payload pairs stored in a context should suffice.
  virtual void AddAnnotationNew(Annotation&) {}
};

// Records annotations about a Printer's output to a Protobuf message,
// assuming that it has a repeated submessage field named `annotation` with
// fields matching
//
// message ??? {
//   repeated int32 path = 1;
//   optional string source_file = 2;
//   optional int32 begin = 3;
//   optional int32 end = 4;
// }
template <typename AnnotationProto>
class AnnotationProtoCollector : public AnnotationCollector {
 public:
  explicit AnnotationProtoCollector(AnnotationProto* annotation_proto)
      : annotation_proto_(annotation_proto) {}

  void AddAnnotation(size_t begin_offset, size_t end_offset,
                     const std::string& file_path,
                     const std::vector<int>& path) override {
    auto* annotation = annotation_proto_->add_annotation();
    for (int i = 0; i < path.size(); ++i) {
      annotation->add_path(path[i]);
    }
    annotation->set_source_file(file_path);
    annotation->set_begin(begin_offset);
    annotation->set_end(end_offset);
  }

  void AddAnnotationNew(Annotation& a) override {
    auto* annotation = annotation_proto_->add_annotation();
    annotation->ParseFromString(a.second);
    annotation->set_begin(a.first.first);
    annotation->set_end(a.first.second);
  }

 private:
  AnnotationProto* annotation_proto_;
};

// A source code printer for assisting in code generation.
//
// This type implements a simple templating language for substiting variables
// into static, user-provided strings, and also tracks indentation
// automatically.
//
// The main entry-point for this type is the Emit function, which can be used
// thus:
//
//   Printer p(output);
//   p.Emit({{"class", my_class_name}}, R"cc(
//     class $class$ {
//      public:
//       $class$(int x) : x_(x) {}
//      private:
//       int x_;
//     };
//   )cc");
//
// Substitutions are of the form $var$, which is looked up in the map passed in
// as the first argument. The variable delimiter character, $, can be chosen to
// be something convenient for the target language. For example, in PHP, which
// makes heavy use of $, it can be made into something like # instead.
//
// A literal $ can be emitted by writing $$.
//
// Substitutions may contain spaces around the name of the variable, which will
// be ignored for the purposes of looking up the variable to substitute in, but
// which will be reproduced in the output:
//
//   p.Emit({{"foo", "bar"}}, "$ foo $");
//
// emits the string " bar ". If the substituted-in variable is the empty string,
// then the surrounding spaces are *not* printed:
//
//   p.Emit({{"xzy", xyz}}, "$xyz $Thing");
//
// If xyz is "Foo", this will become "Foo Thing", but if it is "", this becomes
// "Thing", rather than " Thing". This helps minimize awkward whitespace in the
// output.
//
// The value may be any type that can be stringified with `absl::StrCat`:
//
//   p.Emit({{"num", 5}}, "x = $num$;");
//
// If a variable is referenced in the format string that is missing, the program
// will crash. Callers must statically know that every variable reference is
// valid, and MUST NOT pass user-provided strings directly into Emit().
//
// # Callback Substitution
//
// Instead of passing a string into Emit(), it is possible to pass in a callback
// as a variable mapping. This will take indentation into account, which allows
// factoring out parts of a formatting string while ensuring braces are
// balanced:
//
//   p.Emit(
//     {{"methods", [&] {
//       p.Emit(R"cc(
//         int Bar() {
//            return 42;
//         }
//       )cc");
//     }}},
//     R"cc(
//       class Foo {
//        public:
//         $methods$;
//       };
//     )cc"
//   );
//
// This emits
//
//   class Foo {
//    public:
//     int Bar() {
//       return 42;
//     }
//   };
//
// # Lookup Frames
//
// If many calls to Emit() use the same set of variables, they can be stored
// in a *variable lookup frame*, like so:
//
//   auto vars = p.WithVars({{"class_name", my_class_name}});
//   p.Emit(R"cc(
//     class $class_name$ {
//      public:
//       $class_name$(int x);
//       // Etc.
//     };
//   )cc");
//
// WithVars() returns an RAII object that will "pop" the lookup frame on scope
// exit, ensuring that the variables remain local. There are a few different
// overloads of WithVars(); it accepts a map type, like absl::flat_hash_map,
// either by-value (which will cause the Printer to store a copy), or by
// pointer (which will cause the Printer to store a pointer, potentially
// avoiding a copy.)
//
// p.Emit(vars, "..."); is effectively syntax sugar for
//
//  { auto v = p.WithVars(vars); p.Emit("..."); }
//
// NOTE: callbacks are *not* allowed with WithVars; callbacks should be local
// to a specific Emit() call.
//
// # Annotations
//
// If Printer is given an AnnotationCollector, it will use it to record which
// spans of generated code correspond to user-indicated descriptors. There are
// a few different ways of indicating when to emit annotations.
//
// The WithAnnotations() function is like WithVars(), but accepts maps with
// string keys and descriptor values. It adds an annotation variable frame and
// returns an RAII object that pops the frame.
//
// There are two different ways to annotate code. In the first, when
// substituting a variable, if there is an annotation with the same name, then
// the resulting expanded value's span will be annotated with that annotation.
// For example:
//
//   auto v = p.WithVars({{"class_name", my_class_name}});
//   auto a = p.WithAnnotations({{"class_name", message_descriptor}});
//   p.Emit(R"cc(
//     class $class_name$ {
//      public:
//       $class_name$(int x);
//       // Etc.
//     };
//   )cc");
//
// The span corresponding to whatever $class_name$ expands to will be annotated
// as having come from message_descriptor.
//
// For convenience, this can be done with a single WithVars(), using the special
// three-argument form:
//
//   auto v = p.WithVars({{"class_name", my_class_name, message_descriptor}});
//   p.Emit(R"cc(
//     class $class_name$ {
//      public:
//       $class_name$(int x);
//       // Etc.
//     };
//   )cc");
//
//
// Alternatively, a range may be given explicitly:
//
//   auto a = p.WithAnnotations({{"my_desc", message_descriptor}});
//   p.Emit(R"cc(
//     $_start$my_desc$
//     class Foo {
//       // Etc.
//     };
//     $_end$my_desc$
//   )cc");
//
// The special $_start$ and $_end$ variables indicate the start and end of an
// annotated span, which is annotated with the variable that follows. This
// form can produce somewhat unreadable format strings and is not recommended.
//
// Note that whitespace after a $_start$ and before an $_end$ is not printed.
//
// # Indentation
//
// Printer tracks an indentation amount to add to each new line, independent
// from indentation in an Emit() call's literal. The amount of indentation to
// add is controlled by the WithIndent() function:
//
//   p.Emit("class $class_name$ {");
//   {
//     auto indent = p.WithIndent();
//     p.Emit(R"cc(
//       public:
//        $class_name$(int x);
//     )cc");
//   }
//   p.Emit("};");
//
// This will automatically add one level of indentation to all code in scope of
// `indent`, which is an RAII object much like the return value of `WithVars()`.
//
// # Old API
// TODO(b/242326974): Delete this documentation.
//
// Printer supports an older-style API that is in the process of being
// re-written. The old documentation is reproduced here until all use-cases are
// handled.
//
// This simple utility class assists in code generation.  It basically
// allows the caller to define a set of variables and then output some
// text with variable substitutions.  Example usage:
//
//   Printer printer(output, '$');
//   map<string, string> vars;
//   vars["name"] = "Bob";
//   printer.Print(vars, "My name is $name$.");
//
// The above writes "My name is Bob." to the output stream.
//
// Printer aggressively enforces correct usage, crashing (with assert failures)
// in the case of undefined variables in debug builds. This helps greatly in
// debugging code which uses it.
//
// If a Printer is constructed with an AnnotationCollector, it will provide it
// with annotations that connect the Printer's output to paths that can identify
// various descriptors.  In the above example, if person_ is a descriptor that
// identifies Bob, we can associate the output string "My name is Bob." with
// a source path pointing to that descriptor with:
//
//   printer.Annotate("name", person_);
//
// The AnnotationCollector will be sent an annotation linking the output range
// covering "Bob" to the logical path provided by person_.  Tools may use
// this association to (for example) link "Bob" in the output back to the
// source file that defined the person_ descriptor identifying Bob.
//
// Annotate can only examine variables substituted during the last call to
// Print.  It is invalid to refer to a variable that was used multiple times
// in a single Print call.
//
// In full generality, one may specify a range of output text using a beginning
// substitution variable and an ending variable.  The resulting annotation will
// span from the first character of the substituted value for the beginning
// variable to the last character of the substituted value for the ending
// variable.  For example, the Annotate call above is equivalent to this one:
//
//   printer.Annotate("name", "name", person_);
//
// This is useful if multiple variables combine to form a single span of output
// that should be annotated with the same source path.  For example:
//
//   Printer printer(output, '$');
//   map<string, string> vars;
//   vars["first"] = "Alice";
//   vars["last"] = "Smith";
//   printer.Print(vars, "My name is $first$ $last$.");
//   printer.Annotate("first", "last", person_);
//
// This code would associate the span covering "Alice Smith" in the output with
// the person_ descriptor.
//
// Note that the beginning variable must come before (or overlap with, in the
// case of zero-sized substitution values) the ending variable.
//
// It is also sometimes useful to use variables with zero-sized values as
// markers.  This avoids issues with multiple references to the same variable
// and also allows annotation ranges to span literal text from the Print
// templates:
//
//   Printer printer(output, '$');
//   map<string, string> vars;
//   vars["foo"] = "bar";
//   vars["function"] = "call";
//   vars["mark"] = "";
//   printer.Print(vars, "$function$($foo$,$foo$)$mark$");
//   printer.Annotate("function", "mark", call_);
//
// This code associates the span covering "call(bar,bar)" in the output with the
// call_ descriptor.
class PROTOBUF_EXPORT Printer {
 private:
  // This type exists to work around an absl type that has not yet been
  // released.
  struct SourceLocation {
    static SourceLocation current() { return {}; }
    absl::string_view file_name() { return "<unknown>"; }
    int line() { return 0; }
  };

  struct AnnotationRecord {
    std::vector<int> path;
    std::string file_path;

    // AnnotationRecord's constructors are *not* marked as explicit,
    // specifically so that it is possible to construct a
    // map<string, AnnotationRecord> by writing
    //
    // {{"foo", my_cool_descriptor}, {"bar", "file.proto"}}

    template <
        typename String,
        std::enable_if_t<std::is_convertible<const String&, std::string>::value,
                         int> = 0>
    AnnotationRecord(  // NOLINT(google-explicit-constructor)
        const String& file_path)
        : file_path(file_path) {}

    template <typename Desc,
              // This SFINAE clause excludes char* from matching this
              // constructor.
              std::enable_if_t<std::is_class<Desc>::value, int> = 0>
    AnnotationRecord(const Desc* desc)  // NOLINT(google-explicit-constructor)
        : file_path(desc->file()->name()) {
      desc->GetLocationPath(&path);
    }
  };

  // Sink type for constructing values to pass to WithVars() and Emit().
  template <typename K, bool allow_callbacks>
  struct VarDefinition {
    using StringOrCallback = absl::variant<std::string, std::function<void()>>;

    template <typename Key, typename Value>
    VarDefinition(Key&& key, Value&& value)
        : key(std::forward<Key>(key)),
          value(ToStringOrCallback(std::forward<Value>(value), Rank2{})),
          annotation(absl::nullopt) {}

    // NOTE: This is an overload rather than taking optional<AnnotationRecord>
    // with a default argument of nullopt, because we want to pick up
    // AnnotationRecord's user-defined conversions. Because going from
    // e.g. Descriptor* -> optional<AnnotationRecord> requires two user-defined
    // conversions, this does not work.
    template <typename Key, typename Value>
    VarDefinition(Key&& key, Value&& value, AnnotationRecord annotation)
        : key(std::forward<Key>(key)),
          value(ToStringOrCallback(std::forward<Value>(value), Rank2{})),
          annotation(std::move(annotation)) {}

    K key;
    StringOrCallback value;
    absl::optional<AnnotationRecord> annotation;

   private:
    // go/ranked-overloads
    struct Rank0 {};
    struct Rank1 : Rank0 {};
    struct Rank2 : Rank1 {};

    // Dummy template for delayed instantiation, which is required for the
    // static assert below to kick in only when this function is called when it
    // shouldn't.
    //
    // This is done to produce a better error message than the "candidate does
    // not match" SFINAE errors.
    template <bool allowed = allow_callbacks>
    StringOrCallback ToStringOrCallback(std::function<void()> cb, Rank2) {
      static_assert(
          allowed, "callback-typed variables are not allowed in this location");
      return cb;
    }

    // Separate from the AlphaNum overload to avoid copies when taking strings
    // by value.
    StringOrCallback ToStringOrCallback(std::string s, Rank1) { return s; }

    StringOrCallback ToStringOrCallback(const absl::AlphaNum& s, Rank0) {
      return std::string(s.Piece());
    }
  };

 public:
  static constexpr char kDefaultVariableDelimiter = '$';
  static constexpr absl::string_view kProtocCodegenTrace =
      "PROTOC_CODEGEN_TRACE";

  // Options for controlling how the output of a Printer is formatted.
  struct Options {
    Options() = default;
    Options(const Options&) = default;
    Options(Options&&) = default;
    Options(char variable_delimiter, AnnotationCollector* annotation_collector)
        : variable_delimiter(variable_delimiter),
          annotation_collector(annotation_collector) {}

    // The delimiter for variable substitutions, e.g. $foo$.
    char variable_delimiter = kDefaultVariableDelimiter;
    // An optional listener the Printer calls whenever it emits a source
    // annotation; may be null.
    AnnotationCollector* annotation_collector = nullptr;
    // The "comment start" token for the language being generated. This is used
    // to allow the Printer to emit debugging annotations in the source code
    // output.
    absl::string_view comment_start = "//";
    // The number of spaces that a single level of indentation adds by default;
    // this is the amount that WithIndent() increases indentation by.
    size_t spaces_per_indent = 2;
    // Whether to emit a "codegen trace" for calls to Emit(). If true, each call
    // to Emit() will print a comment indicating where in the source of the
    // compiler the Emit() call occurred.
    //
    // If disengaged, defaults to whether or not the environment variable
    // `PROTOC_CODEGEN_TRACE` is set.
    absl::optional<bool> enable_codegen_trace = absl::nullopt;
  };

  // Constructs a new Printer with the default options to output to
  // `output`.
  explicit Printer(ZeroCopyOutputStream* output) : Printer(output, Options{}) {}

  // Constructs a new printer with the given set of options to output to
  // `output`.
  Printer(ZeroCopyOutputStream* output, Options options);

  // Old-style constructor. Avoid in preference to the two constructors above.
  //
  // Will eventually be marked as deprecated.
  Printer(ZeroCopyOutputStream* output, char variable_delimiter,
          AnnotationCollector* annotation_collector = nullptr)
      : Printer(output, Options{variable_delimiter, annotation_collector}) {}

  Printer(const Printer&) = delete;
  Printer& operator=(const Printer&) = delete;

  // Pushes a new variable lookup frame that stores `vars` by reference.
  //
  // Returns an RAII object that pops the lookup frame.
  template <typename Map>
  auto WithVars(const Map* vars) {
    var_lookups_.emplace_back([vars](absl::string_view var) -> LookupResult {
      auto it = vars->find(std::string(var));
      if (it == vars->end()) {
        return absl::nullopt;
      }
      return absl::string_view(it->second);
    });
    return absl::MakeCleanup([this] { var_lookups_.pop_back(); });
  }

  // Pushes a new variable lookup frame that stores `vars` by value.
  //
  // When writing `WithVars({...})`, this is the overload that will be called,
  // and it will synthesize an `absl::flat_hash_map`.
  //
  // Returns an RAII object that pops the lookup frame.
  template <typename Map = absl::flat_hash_map<std::string, std::string>,
            std::enable_if_t<!std::is_pointer<Map>::value, int> = 0>
  auto WithVars(Map&& vars) {
    var_lookups_.emplace_back([vars = std::forward<Map>(vars)](
                                  absl::string_view var) -> LookupResult {
      auto it = vars.find(std::string(var));
      if (it == vars.end()) {
        return absl::nullopt;
      }
      return absl::string_view(it->second);
    });
    return absl::MakeCleanup([this] { var_lookups_.pop_back(); });
  }

  auto WithVars(std::initializer_list<
                VarDefinition<std::string, /*allow_callbacks=*/false>>
                    vars);

  // Looks up a variable set with WithVars().
  //
  // Will crash if:
  // - `var` is not present in the lookup frame table.
  // - `var` is a callback, rather than a string.
  absl::string_view LookupVar(absl::string_view var);

  // Pushes a new annotation lookup frame that stores `vars` by reference.
  //
  // Returns an RAII object that pops the lookup frame.
  template <typename Map>
  auto WithAnnotations(const Map* vars) {
    annotation_lookups_.emplace_back(
        [vars](absl::string_view var) -> absl::optional<AnnotationRecord> {
          auto it = vars->find(std::string(var));
          if (it == vars->end()) {
            return absl::nullopt;
          }
          return AnnotationRecord(it->second);
        });
    return absl::MakeCleanup([this] { annotation_lookups_.pop_back(); });
  }

  // Pushes a new variable lookup frame that stores `vars` by value.
  //
  // When writing `WithAnnotations({...})`, this is the overload that will be
  // called, and it will synthesize an `absl::flat_hash_map`.
  //
  // Returns an RAII object that pops the lookup frame.
  template <typename Map = absl::flat_hash_map<std::string, AnnotationRecord>>
  auto WithAnnotations(Map&& vars) {
    annotation_lookups_.emplace_back(
        [vars = std::forward<Map>(vars)](
            absl::string_view var) -> absl::optional<AnnotationRecord> {
          auto it = vars.find(std::string(var));
          if (it == vars.end()) {
            return absl::nullopt;
          }
          return AnnotationRecord(it->second);
        });
    return absl::MakeCleanup([this] { annotation_lookups_.pop_back(); });
  }

  // Increases the indentation by `indent` spaces; when nullopt, increments
  // indentation by the configured default spaces_per_indent.
  //
  // Returns an RAII object that removes this indentation.
  auto WithIndent(absl::optional<size_t> indent = absl::nullopt) {
    size_t delta = indent.value_or(options_.spaces_per_indent);
    indent_ += delta;
    return absl::MakeCleanup([this, delta] { indent_ -= delta; });
  }

  // Emits formatted source code to the underlying output. See the class
  // documentation for more details.
  //
  // `format` MUST be a string constant.
  void Emit(absl::string_view format,
            SourceLocation loc = SourceLocation::current()) {
    Emit({}, format, loc);
  }

  // Emits formatted source code to the underlying output, injecting
  // additional variables as a lookup frame for just this call. See the class
  // documentation for more details.
  //
  // `format` MUST be a string constant.
  void Emit(std::initializer_list<
                VarDefinition<absl::string_view, /*allow_callbacks=*/true>>
                vars,
            absl::string_view format,
            SourceLocation loc = SourceLocation::current());

  // Write a string directly to the underlying output, performing no formatting
  // of any sort.
  void PrintRaw(absl::string_view data) { WriteRaw(data.data(), data.size()); }

  // Write a string directly to the underlying output, performing no formatting
  // of any sort.
  void WriteRaw(const char* data, size_t size);

  // True if any write to the underlying stream failed.  (We don't just
  // crash in this case because this is an I/O failure, not a programming
  // error.)
  bool failed() const { return failed_; }

  // -- Old-style API below; to be deprecated and removed. --
  // TODO(b/242326974): Deprecate these APIs.

  template <typename Map = absl::flat_hash_map<std::string, std::string>>
  void Print(const Map& vars, absl::string_view text) {
    PrintOptions opts;
    opts.checks_are_debug_only = true;
    opts.use_substitution_map = true;
    opts.allow_digit_substitions = false;

    auto pop = WithVars(&vars);
    PrintImpl(text, {}, opts);
  }

  template <typename... Args>
  void Print(absl::string_view text, const Args&... args) {
    static_assert(sizeof...(args) % 2 == 0, "");

    // Include an extra arg, since a zero-length array is ill-formed, and
    // MSVC complains.
    absl::string_view vars[] = {args..., ""};
    absl::flat_hash_map<std::string, std::string> map;
    map.reserve(sizeof...(args) / 2);
    for (size_t i = 0; i < sizeof...(args); i += 2) {
      map.emplace(std::string(vars[i]), std::string(vars[i + 1]));
    }

    Print(map, text);
  }

  // Link a substitution variable emitted by the last call to Print to the
  // object described by descriptor.
  template <typename SomeDescriptor>
  void Annotate(absl::string_view varname, const SomeDescriptor* descriptor) {
    Annotate(varname, varname, descriptor);
  }

  // Link the output range defined by the substitution variables as emitted by
  // the last call to Print to the object described by descriptor. The range
  // begins at begin_varname's value and ends after the last character of the
  // value substituted for end_varname.
  template <typename SomeDescriptor>
  void Annotate(absl::string_view begin_varname, absl::string_view end_varname,
                const SomeDescriptor* descriptor) {
    if (options_.annotation_collector == nullptr) {
      return;
    }

    std::vector<int> path;
    descriptor->GetLocationPath(&path);
    Annotate(begin_varname, end_varname, descriptor->file()->name(), path);
  }

  // Link a substitution variable emitted by the last call to Print to the file
  // with path file_name.
  void Annotate(absl::string_view varname, absl::string_view file_name) {
    Annotate(varname, varname, file_name);
  }

  // Link the output range defined by the substitution variables as emitted by
  // the last call to Print to the file with path file_name. The range begins
  // at begin_varname's value and ends after the last character of the value
  // substituted for end_varname.
  void Annotate(absl::string_view begin_varname, absl::string_view end_varname,
                absl::string_view file_name) {
    if (options_.annotation_collector == nullptr) {
      return;
    }

    Annotate(begin_varname, end_varname, file_name, {});
  }

  // Indent text by `options.spaces_per_indent`; undone by Outdent().
  void Indent() { indent_ += options_.spaces_per_indent; }

  // Undoes a call to Indent().
  void Outdent();

  // FormatInternal is a helper function not meant to use directly, use
  // compiler::cpp::Formatter instead.
  void FormatInternal(absl::Span<const std::string> args,
                      const std::map<std::string, std::string>& vars,
                      absl::string_view format) {
    PrintOptions opts;
    opts.use_curly_brace_substitutions = true;
    opts.strip_spaces_around_vars = true;

    auto pop = WithVars(&vars);
    PrintImpl(format, args, opts);
  }

 private:
  // Options for PrintImpl().
  struct PrintOptions {
    // The callsite of the public entry-point. Only Emit() sets this.
    absl::optional<SourceLocation> loc;
    // If set, Validate() calls will not crash the program.
    bool checks_are_debug_only = false;
    // If set, the `substitutions_` map will be populated as variables are
    // substituted.
    bool use_substitution_map = false;
    // If set, the ${1$ and $}$ forms will be substituted. These are used for
    // a slightly janky annotation-insertion mechanism in FormatInternal, that
    // requires that passed-in substitution variables be serialized protos.
    bool use_curly_brace_substitutions = false;
    // If set, the $n$ forms will be substituted, pulling from the `args`
    // argument to PrintImpl().
    bool allow_digit_substitions = true;
    // If set, when a variable substitution with spaces in it, such as $ var$,
    // is encountered, the spaces are stripped, so that it is as if it was
    // $var$. If $var$ substitutes to a non-empty string, the removed spaces are
    // printed around the substituted value.
    //
    // See the class documentation for more information on this behavior.
    bool strip_spaces_around_vars = true;
    // If set, leading whitespace will be stripped from the format string to
    // determine the "extraneous indentation" that is produced when the format
    // string is a C++ raw string. This is used to remove leading spaces from
    // a raw string that would otherwise result in erratic indentation in the
    // output.
    bool strip_raw_string_indentation = false;
    // If set, the annotation lookup frames are searched, per the annotation
    // semantics of Emit() described in the class documentation.
    bool use_annotation_frames = true;
  };

  // Emit an annotation for the range defined by the given substitution
  // variables, as set by the most recent call to PrintImpl() that set
  // `use_substitution_map` to true.
  //
  // The range begins at the start of `begin_varname`'s value and ends after the
  // last byte of `end_varname`'s value.
  //
  // `begin_varname` and `end_varname may` refer to the same variable.
  void Annotate(absl::string_view begin_varname, absl::string_view end_varname,
                absl::string_view file_path, const std::vector<int>& path);

  // The core printing implementation. There are three public entry points,
  // which enable different slices of functionality that are controlled by the
  // `opts` argument.
  void PrintImpl(absl::string_view format, absl::Span<const std::string> args,
                 PrintOptions opts);

  // This is a private function only so that it can see PrintOptions.
  static bool Validate(bool cond, PrintOptions opts,
                       absl::FunctionRef<std::string()> message);
  static bool Validate(bool cond, PrintOptions opts, absl::string_view message);

  // Performs calls to `Validate()` to check that `index < current_arg_index`
  // and `index < args_len`, producing appropriate log lines if the checks fail,
  // and crashing if necessary.
  bool ValidateIndexLookupInBounds(size_t index, size_t current_arg_index,
                                   size_t args_len, PrintOptions opts);

  // Prints indentation if `at_start_of_line_` is true.
  void IndentIfAtStart();

  // Prints a codegen trace, for the given location in the compiler's source.
  void PrintCodegenTrace(absl::optional<SourceLocation> loc);

  // The core implementation for "fully-elaborated" variable definitions. This
  // is a private function to avoid users being able to set `allow_callbacks`.
  template <typename K, bool allow_callbacks>
  auto WithDefs(std::initializer_list<VarDefinition<K, allow_callbacks>> vars);

  // Returns the start and end of the value that was substituted in place of
  // the variable `varname` in the last call to PrintImpl() (with
  // `use_substitution_map` set), if such a variable was substituted exactly
  // once.
  absl::optional<std::pair<size_t, size_t>> GetSubstitutionRange(
      absl::string_view varname, PrintOptions opts);

  google::protobuf::io::zc_sink_internal::ZeroCopyStreamByteSink sink_;
  Options options_;
  size_t indent_ = 0;
  bool at_start_of_line_ = true;
  bool failed_ = false;

  using LookupResult =
      absl::optional<absl::variant<absl::string_view, std::function<void()>>>;

  std::vector<std::function<LookupResult(absl::string_view)>> var_lookups_;

  std::vector<
      std::function<absl::optional<AnnotationRecord>(absl::string_view)>>
      annotation_lookups_;

  // A map from variable name to [start, end) offsets in the output buffer.
  //
  // This stores the data looked up by GetSubstitutionRange().
  std::map<std::string, std::pair<size_t, size_t>> substitutions_;
  // Keeps track of the keys in `substitutions_` that need to be updated when
  // indents are inserted. These are keys that refer to the beginning of the
  // current line.
  std::vector<std::string> line_start_variables_;
};

template <typename K, bool allow_callbacks>
auto Printer::WithDefs(
    std::initializer_list<VarDefinition<K, allow_callbacks>> vars) {
  absl::flat_hash_map<K, absl::variant<std::string, std::function<void()>>>
      var_map;
  var_map.reserve(vars.size());

  absl::flat_hash_map<K, AnnotationRecord> annotation_map;

  for (auto& var : vars) {
    auto result = var_map.insert({var.key, var.value});
    GOOGLE_CHECK(result.second) << "repeated variable in Emit() or WithVars() call: \""
                         << var.key << "\"";
    if (var.annotation.has_value()) {
      annotation_map.insert({var.key, *var.annotation});
    }
  }

  var_lookups_.emplace_back(
      [map = std::move(var_map)](absl::string_view var) -> LookupResult {
        auto it = map.find(var);
        if (it == map.end()) {
          return absl::nullopt;
        }
        if (auto* str = absl::get_if<std::string>(&it->second)) {
          return absl::string_view(*str);
        }

        auto* f = absl::get_if<std::function<void()>>(&it->second);
        GOOGLE_CHECK(f != nullptr);
        return *f;
      });

  bool has_annotations = !annotation_map.empty();
  if (has_annotations) {
    annotation_lookups_.emplace_back(
        [map = std::move(annotation_map)](
            absl::string_view var) -> absl::optional<AnnotationRecord> {
          auto it = map.find(var);
          if (it == map.end()) {
            return absl::nullopt;
          }
          return it->second;
        });
  }

  return absl::MakeCleanup([this, has_annotations] {
    var_lookups_.pop_back();
    if (has_annotations) {
      annotation_lookups_.pop_back();
    }
  });
}

inline auto Printer::WithVars(
    std::initializer_list<VarDefinition<std::string, /*allow_callbacks=*/false>>
        vars) {
  return WithDefs(vars);
}
}  // namespace io
}  // namespace protobuf
}  // namespace google

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_IO_PRINTER_H__
