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 
136 #include "fhiclcpp/coding.h"
138 #include "fhiclcpp/fwd.h"
139 
140 #include <sstream>
141 #include <stack>
142 #include <string>
143 #include <vector>
144 
145 namespace fhicl {
146  namespace detail {
147 
149  public:
151 
153 
155  result() const
156  {
157  return buffer_.str();
158  }
159 
160  private:
161  void before_action(key_t const&,
162  any_t const&,
163  ParameterSet const*) override;
164 
165  void enter_table(key_t const&, any_t const&) override;
166  void enter_sequence(key_t const&, any_t const&) override;
167 
168  void exit_table(key_t const&, any_t const&) override;
169  void exit_sequence(key_t const&, any_t const&) override;
170 
171  void atom(key_t const&, any_t const&) override;
172 
173  void push_size_(any_t const&);
174  void pop_size_();
175  std::string print_full_key_(name_t const& k) const;
176 
177  std::stringstream buffer_;
180  std::stack<std::size_t> sequence_sizes_;
181  std::size_t curr_size_;
182  std::vector<name_t> name_stack_;
183  };
184  }
185 }
186 
187 #endif /* fhiclcpp_detail_PrettifierPrefixAnnotated_h */
188 
189 // Local variables:
190 // mode: c++
191 // End:
void before_action(key_t const &, any_t const &, ParameterSet const *) override
void enter_table(key_t const &, any_t const &) override
void exit_sequence(key_t const &, any_t const &) override
void exit_table(key_t const &, any_t const &) override
void atom(key_t const &, any_t const &) override
std::string print_full_key_(name_t const &k) const
void enter_sequence(key_t const &, any_t const &) override
enum BeamMode string