pprint_utils.h
1 // Copyright 2016, Beeri 15. All rights reserved.
2 // Author: Roman Gershman (romange@gmail.com)
3 //
4 #ifndef _PPRINT_UTILS_H
5 #define _PPRINT_UTILS_H
6 
7 #include <google/protobuf/text_format.h>
8 #include <atomic>
9 #include <functional>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/integral_types.h"
15 #include "strings/stringpiece.h"
16 
17 namespace util {
18 namespace pprint {
19 
20 namespace gpb = ::google::protobuf;
21 
22 class FdPath {
23  public:
24  // msg, fd, index in repeated array.
25  typedef std::function<void(const gpb::Message& msg, const gpb::FieldDescriptor*, int, int)>
26  ValueCb;
27  FdPath() {
28  }
29  FdPath(const gpb::Descriptor* root, StringPiece path);
30  FdPath(const FdPath&) = default;
31  FdPath(FdPath&&) = default;
32  FdPath& operator=(const FdPath&) = default;
33 
34  void ExtractValue(const gpb::Message& msg, ValueCb cb) const {
35  ExtractValueRecur(msg, 0, cb);
36  }
37 
38  bool IsRepeated() const;
39 
40  const std::vector<const gpb::FieldDescriptor*> path() const {
41  return path_;
42  }
43  void push_back(const gpb::FieldDescriptor* fd) {
44  path_.push_back(fd);
45  }
46  bool valid() const {
47  return !path_.empty();
48  }
49 
50  private:
51  void ExtractValueRecur(const gpb::Message& msg, uint32 index, ValueCb cb) const;
52 
53  std::vector<const gpb::FieldDescriptor*> path_;
54  mutable std::vector<uint32> cur_repeated_stack_; // indices into the arrays of repeated messages.
55 };
56 
57 // Allocated a message instance based on the descriptor.
58 gpb::Message* AllocateMsgFromDescr(const gpb::Descriptor* descr);
59 
60 // Allocates message dynamically based on its type and serialized fs_set data.
61 // Both fields must be well defined and set.
62 gpb::Message* AllocateMsgByMeta(const std::string& type, const std::string& fd_set);
63 
64 struct PathNode {
65  std::vector<PathNode> children;
66  const gpb::FieldDescriptor* fd;
67 
68  explicit PathNode(const gpb::FieldDescriptor* fdescr = nullptr) : fd(fdescr) {
69  }
70 
71  PathNode* AddChild(const gpb::FieldDescriptor* fd);
72 };
73 
74 class Printer {
75  gpb::TextFormat::Printer printer_;
76  std::string type_name_;
77  std::vector<FdPath> fds_;
78  PathNode root_;
79 
80  FdPath root_path_;
81 
82  // void ExtractValueRecur(const gpb::Message& msg, const FdPath& fd_path, uint32 index, ValueCb
83  // cb);
84  void PrintValueRecur(size_t path_index, const std::string& prefix, bool has_value,
85  const gpb::Message& msg) const;
86 
87  public:
88  using FieldPrinterPredicate =
89  std::function<gpb::TextFormat::FieldValuePrinter*(const gpb::FieldDescriptor& fd)>;
90 
91  explicit Printer(const gpb::Descriptor* descriptor, FieldPrinterPredicate pred = nullptr);
92  void Output(const gpb::Message& msg) const;
93 };
94 
96  typedef std::function<std::string(const ::google::protobuf::FieldDescriptor& fd)> OverrideCb;
97 
98  OverrideCb field_name_cb;
99  OverrideCb type_name_cb;
100 };
101 
102 void PrintBqSchema(const gpb::Descriptor* descr,
103  const PrintBqSchemaOptions& options = PrintBqSchemaOptions{});
104 
106  public:
107  class Trie {
108  public:
109  Trie* Get(ptrdiff_t i) {
110  return children_[i].get();
111  }
112  const Trie* Get(ptrdiff_t i) const {
113  return children_[i].get();
114  }
115  void Put(ptrdiff_t i, std::unique_ptr<Trie> p) {
116  children_[i] = move(p);
117  }
118  void Resize(size_t sz) {
119  children_.resize(sz);
120  }
121  size_t Size() const {
122  return children_.size();
123  }
124 
125  size_t bytes = 0;
126  std::string name;
127 
128  private:
129  std::vector<std::unique_ptr<Trie> > children_;
130  };
131 
132  explicit SizeSummarizer(const gpb::Descriptor* descr);
133  void AddSizes(const gpb::Message& msg);
134  std::map<std::string, size_t> GetSizes() const;
135  void Print(std::ostream* out) const;
136 
137  private:
138  Trie trie_;
139 };
140 
141 inline std::ostream& operator<<(std::ostream& out, const SizeSummarizer& ss) {
142  ss.Print(&out);
143  return out;
144 }
145 } // namespace pprint
146 } // namespace util
147 
148 #endif // _PPRINT_UTILS_H