PrettifierPrefixAnnotated.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_detail_PrettifierPrefixAnnotated_h
2 #define fhiclcpp_detail_PrettifierPrefixAnnotated_h
3 
4 /*
5  ======================================================================
6 
7  PrettifierPrefixAnnotated
8 
9  ======================================================================
10 
11  Class used when
12 
13  'ParameterSet::to_indented_string(unsigned,print_mode::prefix_annotated)'
14 
15  is called. This class provides a string representing the entire
16  (nested) contents of a ParameterSet object, as well as annotations
17  that describe in what FHiCL configuration file, and in what line of
18  that file, the particular parameter was set or reassigned. This
19  version provides annotations on the line preceding the parameter
20  assignment, which can help users who wish to parse the stringified
21  representation with their own scripts.
22 
23  Currently supported format:
24  ===========================
25 
26  This will provide a print out that looks like:
27 
28  ^<-IND->
29  ^#KEY|p1|$ #KEY|p1|
30  ^#SRC|file:1|$ #SRC|file:1|
31  ^ p1: {$ p1: {
32  ^ }$ }
33  ^#KEY|p2|$ #KEY|p2|
34  ^#SRC|file:2|$ #SRC|file:2|
35  ^ p2: {$ p2: {
36  ^#KEY|p2.a|$ #KEY|p2.a|
37  ^#SRC|file:2|$ #SRC|file:2|
38  ^ a: something$ a: something
39  ^ }$ }
40  ^#KEY|p3|$ #KEY|p3|
41  ^#SRC|new_file:14|$ #SRC|new_file:14|
42  ^ p3: {$ p3: {
43  ^#KEY|p3.a|$ #KEY|p3.a|
44  ^#SRC|new_file:15|$ #SRC|new_file:15|
45  ^ a: else$ a: else
46  ^#KEY|p3.b|$ #KEY|p3.b|
47  ^#SRC|file:7|$ #SRC|file:7|
48  ^ b: [$ b: [
49  ^ ]$ ]
50  ^#KEY|p3.c|$ Rendered #KEY|p3.c|
51  ^#SRC|file:9|$ ========> #SRC|file:9|
52  ^ c: [$ c: [
53  ^#KEY|p3.c[0]|$ #KEY|p3.c[0]|
54  ^#SRC|file:9|$ #SRC|file:9|
55  ^ 11$ 11
56  ^ ]$ ]
57  ^#KEY|p3.d|$ #KEY|p3.d|
58  ^#SRC|file:14|$ #SRC|file:14|
59  ^ d: [$ d: [
60  ^#KEY|p3.d[0]|$ #KEY|p3.d[0]|
61  ^#SRC|file:14|$ #SRC|file:14|
62  ^ 11,$ 11,
63  ^#KEY|p3.d[1]|$ #KEY|p3.d[1]|
64  ^#SRC|file:28|$ #SRC|file:28|
65  ^ 12$ 12
66  ^ ]$ ]
67  ^#KEY|p4|$ #KEY|p3.p4|
68  ^#SRC|new_file:16|$ #SRC|new_file:16
69  ^ p4: {$ p4: {
70  ^#KEY|p4.d|$ #KEY|p3.p4.d|
71  ^#SRC|new_file:17|$ #SRC|new_file:17|
72  ^ d: e$ d: e
73  ^ }$ }
74  ^ }$ }
75  ^<-IND->
76 
77 
78  Note that the caret ^ (dollar-sign $) represents the beginning (end)
79  of the line and is not printed, nor is the <-IND-> string, which
80  represents a user-provided width value for the initial indentation
81  level.
82 
83  The '#KEY' tag includes the fully-qualified key of the parameter two
84  lines below it. The '#SRC|*|' tag specifies the annotation
85  associated with the parameter one line below it. The vertical bars
86  are provided so that empty source annotations are still parsable by
87  a user's script.
88 
89  Maintenance notes:
90  ==================
91 
92  [1] A few stack objects are used: the Indentation class, as well as
93  std::stack<std::size_t>, and std::vector<name_t>.
94 
95  The std::stack<std::size_t> object is used to keep track of the
96  sizes of the stacked sequences. Keeping track of the sequence
97  is necessary so that the last sequence element does not have a
98  ',' character that follows it.
99 
100  The std::vector<name_t> object is used to keep track of the
101  stacked FHiCL names. This series of names is stitched together
102  to form the full key. The reason this object is not of type
103  std::stack is that we need to be able to iterate through each of
104  the stack elements to create the full key, which is not doable
105  with an std::stack object.
106 
107  To use these classes correctly, the Indentation must be updated
108  during each {enter,exit}_{table,sequence} call, the
109  sequence-sizes stack must be updated during each
110  {enter,exit}_sequence call, and the name stack must be updated
111  during each {enter,exit}_table call.
112 
113  [2] There are cases where the annotation information is not
114  available:
115 
116  (a) The parameter was introduced in the C++ code (either by the
117  user, or by the system) and, therefore, has no file source.
118 
119  (b) The parameter was introduced through a substitution:
120 
121  p1: { a: b }
122  p1.p2.c: d
123 
124  In this case, 'p1', 'a', and 'c' would each have source
125  annotations, but 'p2' would not.
126 
127  (c) The parameter originates from an external source (e.g. a
128  database), and no file source exists.
129 
130  In these cases, an empty annotation is provided in the '#SRC'
131  tag.
132 
133 */
134 
137 #include "fhiclcpp/fwd.h"
138 
139 #include <sstream>
140 #include <stack>
141 #include <string>
142 #include <vector>
143 
144 namespace fhicl::detail {
145 
147  public:
149 
151  result() const
152  {
153  return buffer_.str();
154  }
155 
156  private:
157  void before_action(key_t const&,
158  any_t const&,
159  ParameterSet const*) override;
160 
161  void enter_table(key_t const&, any_t const&) override;
162  void enter_sequence(key_t const&, any_t const&) override;
163 
164  void exit_table(key_t const&, any_t const&) override;
165  void exit_sequence(key_t const&, any_t const&) override;
166 
167  void atom(key_t const&, any_t const&) override;
168 
169  void push_size_(any_t const&);
170  void pop_size_();
171  std::string print_full_key_(name_t const& k) const;
172 
173  std::stringstream buffer_{};
176  std::stack<std::size_t> sequence_sizes_{{-1u}};
177  std::size_t curr_size_{};
178  std::vector<name_t> name_stack_{};
179  };
180 }
181 
182 #endif /* fhiclcpp_detail_PrettifierPrefixAnnotated_h */
183 
184 // Local variables:
185 // mode: c++
186 // End:
void atom(key_t const &, any_t const &) override
void enter_sequence(key_t const &, any_t const &) override
void exit_table(key_t const &, any_t const &) override
std::string string
Definition: nybbler.cc:12
void before_action(key_t const &, any_t const &, ParameterSet const *) override
std::string print_full_key_(name_t const &k) const
void enter_table(key_t const &, any_t const &) override
void exit_sequence(key_t const &, any_t const &) override