xref: /aosp_15_r20/external/perfetto/src/protozero/filtering/filter_bytecode_generator.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_GENERATOR_H_
18 #define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_GENERATOR_H_
19 
20 #include <stddef.h>
21 #include <stdint.h>
22 
23 #include <string>
24 #include <vector>
25 
26 namespace protozero {
27 
28 // Creates a filter bytecode that can be passed to the FilterBytecodeParser.
29 // This class is typically only used by offline tools (e.g. the proto_filter
30 // cmdline tool). See go/trace-filtering for the full filtering design.
31 class FilterBytecodeGenerator {
32  public:
33   FilterBytecodeGenerator();
34   ~FilterBytecodeGenerator();
35 
36   // Call at the end of every message. It implicitly starts a new message, there
37   // is no corresponding BeginMessage().
38   void EndMessage();
39 
40   // All the methods below must be called in monotonic field_id order or the
41   // generator will CHECK() and crash.
42 
43   // Allows a simple field (varint, fixed32/64, string or bytes).
44   void AddSimpleField(uint32_t field_id);
45 
46   // Allows a string field which needs to be filtered.
47   void AddFilterStringField(uint32_t field_id);
48 
49   // Allows a range of simple fields. |range_start| is the id of the first field
50   // in range, |range_len| the number of fields in the range.
51   // AddSimpleFieldRange(N,1) is semantically equivalent to AddSimpleField(N)
52   // (but it takes 2 words to encode, rather than just one).
53   void AddSimpleFieldRange(uint32_t range_start, uint32_t range_len);
54 
55   // Adds a nested field. |message_index| is the index of the message that the
56   // parser must recurse into. This implies that at least |message_index| calls
57   // to Begin/EndMessage will be made.
58   // The Serialize() method will fail if any field points to an index that is
59   // out of range (e.g., if message_index = 5 but only 3 EndMessage() calls were
60   // made).
61   void AddNestedField(uint32_t field_id, uint32_t message_index);
62 
63   // Returns the filter bytecode, which is a buffer containing a sequence of
64   // varints and a checksum. The returned string can be passed to
65   // FilterBytecodeParser.Load().
66   std::string Serialize();
67 
68  private:
69   uint32_t num_messages_ = 0;
70   uint32_t last_field_id_ = 0;
71   uint32_t max_msg_index_ = 0;
72   bool endmessage_called_ = false;
73 
74   std::vector<uint32_t> bytecode_;
75 };
76 
77 }  // namespace protozero
78 
79 #endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_GENERATOR_H_
80