1 /*
2  * Copyright 2019 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 #pragma once
18 
19 #include <iostream>
20 #include <string>
21 
22 #include "logging.h"
23 #include "parse_location.h"
24 #include "size.h"
25 
26 // The base field that every packet needs to inherit from.
27 class PacketField : public Loggable {
28 public:
29   virtual ~PacketField() = default;
30 
31   PacketField(std::string name, ParseLocation loc);
32 
33   // Get the type for this field.
34   virtual const std::string& GetFieldType() const = 0;
35 
36   // Returns the size of the field in bits.
37   virtual Size GetSize() const = 0;
38 
39   // Returns the size of the field in bits given the information in the builder.
40   // For most field types, this will be the same as GetSize();
41   virtual Size GetBuilderSize() const;
42 
43   // Returns the size of the field in bits given the information in the parsed struct.
44   // For most field types, this will be the same as GetSize();
45   virtual Size GetStructSize() const;
46 
47   // Get the type of the field to be used in the member variables.
48   virtual std::string GetDataType() const = 0;
49 
50   // Given an iterator {name}_it, extract the type.
51   virtual void GenExtractor(std::ostream& s, int num_leading_bits, bool for_struct) const = 0;
52 
53   // Calculate field_begin and field_end using the given offsets and size, return the number of
54   // leading bits
55   virtual int GenBounds(std::ostream& s, Size start_offset, Size end_offset, Size size) const;
56 
57   // Get the name of the getter function, return empty string if there is a getter function
58   virtual std::string GetGetterFunctionName() const = 0;
59 
60   // Get parser getter definition. Start_offset points to the first bit of the
61   // field. end_offset is the first bit after the field. If an offset is empty
62   // that means that there was a field with an unknown size when trying to
63   // calculate the offset.
64   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const = 0;
65 
66   // Get the type of parameter used in Create(), return empty string if a parameter type was NOT
67   // generated
68   virtual std::string GetBuilderParameterType() const = 0;
69 
70   // Generate the parameter for Create(), return true if a parameter was added.
71   virtual bool GenBuilderParameter(std::ostream& s) const;
72 
73   // Return true if the Builder parameter has to be moved.
74   virtual bool BuilderParameterMustBeMoved() const;
75 
76   // Generate the actual storage for the parameter, return true if it was added.
77   virtual bool GenBuilderMember(std::ostream& s) const;
78 
79   // Helper for reflection tests.
80   virtual void GenBuilderParameterFromView(std::ostream& s) const;
81 
82   // Returns whether or not the field must be validated.
83   virtual bool HasParameterValidator() const = 0;
84 
85   // Fail if the value doesn't fit in the field.
86   virtual void GenParameterValidator(std::ostream& s) const = 0;
87 
88   // Generate the inserter for pushing the data in the builder.
89   virtual void GenInserter(std::ostream& s) const = 0;
90 
91   // Generate the validator for a field for the IsValid() function.
92   //
93   // The way this function works is by assuming that there is an iterator |it|
94   // that was defined earlier. The implementer of the function will then move
95   // it forward based on the dynamic size of the field and then check to see if
96   // its past the end of the packet.
97   // It should be unused for fixed size fields unless special consideration is
98   // needed. This is because all fixed size fields are tallied together with
99   // GetSize() and used as an initial offset. One special consideration is for
100   // enums where instead of checking if they can be read, they are checked to
101   // see if they contain the correct value.
102   virtual void GenValidator(std::ostream& s) const = 0;
103 
104   // Some fields are containers of other fields, e.g. array, vector, etc.
105   // Assume STL containers that support swap()
106   virtual bool IsContainerField() const;
107 
108   // Get field of nested elements if this is a container field, nullptr if none
109   virtual const PacketField* GetElementField() const;
110 
111   // Return string representation of this field, that can be displayed for debugging or logging
112   // purposes
113   virtual void GenStringRepresentation(std::ostream& s, std::string accessor) const;
114 
115   std::string GetDebugName() const override;
116 
117   ParseLocation GetLocation() const override;
118 
119   virtual std::string GetName() const;
120 
GetterIsByRef()121   virtual bool GetterIsByRef() const { return true; }
122 
123 private:
124   ParseLocation loc_;
125   std::string name_;
126 };
127