| Index: third_party/protobuf/src/google/protobuf/io/printer.h
|
| diff --git a/third_party/protobuf/src/google/protobuf/io/printer.h b/third_party/protobuf/src/google/protobuf/io/printer.h
|
| index f1490bbe5b1a48206e9700f9e89ab9e9f0c61b4f..2ba8455906d342a239dafe736e7bd8cdccbefbd0 100644
|
| --- a/third_party/protobuf/src/google/protobuf/io/printer.h
|
| +++ b/third_party/protobuf/src/google/protobuf/io/printer.h
|
| @@ -39,6 +39,7 @@
|
|
|
| #include <string>
|
| #include <map>
|
| +#include <vector>
|
| #include <google/protobuf/stubs/common.h>
|
|
|
| namespace google {
|
| @@ -47,6 +48,47 @@ namespace io {
|
|
|
| class ZeroCopyOutputStream; // zero_copy_stream.h
|
|
|
| +// Records annotations about a Printer's output.
|
| +class LIBPROTOBUF_EXPORT AnnotationCollector {
|
| + public:
|
| + // 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 string& file_path,
|
| + const vector<int>& path) = 0;
|
| +
|
| + virtual ~AnnotationCollector() {}
|
| +};
|
| +
|
| +// Records annotations about a Printer's output to the given protocol buffer,
|
| +// assuming that the buffer has an ::Annotation message exposing path,
|
| +// source_file, begin and end fields.
|
| +template <typename AnnotationProto>
|
| +class AnnotationProtoCollector : public AnnotationCollector {
|
| + public:
|
| + // annotation_proto is the protocol buffer to which new Annotations should be
|
| + // added. It is not owned by the AnnotationProtoCollector.
|
| + explicit AnnotationProtoCollector(AnnotationProto* annotation_proto)
|
| + : annotation_proto_(annotation_proto) {}
|
| +
|
| + // Override for AnnotationCollector::AddAnnotation.
|
| + virtual void AddAnnotation(size_t begin_offset, size_t end_offset,
|
| + const string& file_path, const vector<int>& path) {
|
| + typename AnnotationProto::Annotation* 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);
|
| + }
|
| +
|
| + private:
|
| + // The protocol buffer to which new annotations should be added.
|
| + AnnotationProto* const annotation_proto_;
|
| +};
|
| +
|
| // 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:
|
| @@ -61,13 +103,103 @@ class ZeroCopyOutputStream; // zero_copy_stream.h
|
| // 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", "rmark", call_);
|
| +//
|
| +// This code associates the span covering "call(bar,bar)" in the output with the
|
| +// call_ descriptor.
|
| +
|
| class LIBPROTOBUF_EXPORT Printer {
|
| public:
|
| // Create a printer that writes text to the given output stream. Use the
|
| // given character as the delimiter for variables.
|
| Printer(ZeroCopyOutputStream* output, char variable_delimiter);
|
| +
|
| + // Create a printer that writes text to the given output stream. Use the
|
| + // given character as the delimiter for variables. If annotation_collector
|
| + // is not null, Printer will provide it with annotations about code written
|
| + // to the stream. annotation_collector is not owned by Printer.
|
| + Printer(ZeroCopyOutputStream* output, char variable_delimiter,
|
| + AnnotationCollector* annotation_collector);
|
| +
|
| ~Printer();
|
|
|
| + // Link a subsitution variable emitted by the last call to Print to the object
|
| + // described by descriptor.
|
| + template <typename SomeDescriptor>
|
| + void Annotate(const char* 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(const char* begin_varname, const char* end_varname,
|
| + const SomeDescriptor* descriptor) {
|
| + if (annotation_collector_ == NULL) {
|
| + // Annotations aren't turned on for this Printer, so don't pay the cost
|
| + // of building the location path.
|
| + return;
|
| + }
|
| + vector<int> path;
|
| + descriptor->GetLocationPath(&path);
|
| + Annotate(begin_varname, end_varname, descriptor->file()->name(), path);
|
| + }
|
| +
|
| // Print some text after applying variable substitutions. If a particular
|
| // variable in the text is not defined, this will crash. Variables to be
|
| // substituted are identified by their names surrounded by delimiter
|
| @@ -149,16 +281,48 @@ class LIBPROTOBUF_EXPORT Printer {
|
| bool failed() const { return failed_; }
|
|
|
| private:
|
| + // Link the output range defined by the substitution variables as emitted by
|
| + // the last call to Print to the object found at the SourceCodeInfo-style path
|
| + // in a file with path file_path. The range begins at the start of
|
| + // begin_varname's value and ends after the last character of the value
|
| + // substituted for end_varname. Note that begin_varname and end_varname
|
| + // may refer to the same variable.
|
| + void Annotate(const char* begin_varname, const char* end_varname,
|
| + const string& file_path, const vector<int>& path);
|
| +
|
| const char variable_delimiter_;
|
|
|
| ZeroCopyOutputStream* const output_;
|
| char* buffer_;
|
| int buffer_size_;
|
| + // The current position, in bytes, in the output stream. This is equivalent
|
| + // to the total number of bytes that have been written so far. This value is
|
| + // used to calculate annotation ranges in the substitutions_ map below.
|
| + size_t offset_;
|
|
|
| string indent_;
|
| bool at_start_of_line_;
|
| bool failed_;
|
|
|
| + // A map from variable name to [start, end) offsets in the output buffer.
|
| + // These refer to the offsets used for a variable after the last call to
|
| + // Print. If a variable was used more than once, the entry used in
|
| + // this map is set to a negative-length span. For singly-used variables, the
|
| + // start offset is the beginning of the substitution; the end offset is the
|
| + // last byte of the substitution plus one (such that (end - start) is the
|
| + // length of the substituted string).
|
| + map<string, pair<size_t, size_t> > substitutions_;
|
| +
|
| + // Returns true and sets range to the substitution range in the output for
|
| + // varname if varname was used once in the last call to Print. If varname
|
| + // was not used, or if it was used multiple times, returns false (and
|
| + // fails a debug assertion).
|
| + bool GetSubstitutionRange(const char* varname, pair<size_t, size_t>* range);
|
| +
|
| + // If non-null, annotation_collector_ is used to store annotations about
|
| + // generated code.
|
| + AnnotationCollector* const annotation_collector_;
|
| +
|
| GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Printer);
|
| };
|
|
|
|
|