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 leading bits
54   virtual int GenBounds(std::ostream& s, Size start_offset, Size end_offset, Size size) const;
55 
56   // Get the name of the getter function, return empty string if there is a getter function
57   virtual std::string GetGetterFunctionName() const = 0;
58 
59   // Get parser getter definition. Start_offset points to the first bit of the
60   // field. end_offset is the first bit after the field. If an offset is empty
61   // that means that there was a field with an unknown size when trying to
62   // calculate the offset.
63   virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const = 0;
64 
65   // Get the type of parameter used in Create(), return empty string if a parameter type was NOT generated
66   virtual std::string GetBuilderParameterType() const = 0;
67 
68   // Generate the parameter for Create(), return true if a parameter was added.
69   virtual bool GenBuilderParameter(std::ostream& s) const;
70 
71   // Return true if the Builder parameter has to be moved.
72   virtual bool BuilderParameterMustBeMoved() const;
73 
74   // Generate the actual storage for the parameter, return true if it was added.
75   virtual bool GenBuilderMember(std::ostream& s) const;
76 
77   // Helper for reflection tests.
78   virtual void GenBuilderParameterFromView(std::ostream& s) const;
79 
80   // Returns whether or not the field must be validated.
81   virtual bool HasParameterValidator() const = 0;
82 
83   // Fail if the value doesn't fit in the field.
84   virtual void GenParameterValidator(std::ostream& s) const = 0;
85 
86   // Generate the inserter for pushing the data in the builder.
87   virtual void GenInserter(std::ostream& s) const = 0;
88 
89   // Generate the validator for a field for the IsValid() function.
90   //
91   // The way this function works is by assuming that there is an iterator |it|
92   // that was defined earlier. The implementer of the function will then move
93   // it forward based on the dynamic size of the field and then check to see if
94   // its past the end of the packet.
95   // It should be unused for fixed size fields unless special consideration is
96   // needed. This is because all fixed size fields are tallied together with
97   // GetSize() and used as an initial offset. One special consideration is for
98   // enums where instead of checking if they can be read, they are checked to
99   // see if they contain the correct value.
100   virtual void GenValidator(std::ostream& s) const = 0;
101 
102   // Some fields are containers of other fields, e.g. array, vector, etc.
103   // Assume STL containers that support swap()
104   virtual bool IsContainerField() const;
105 
106   // Get field of nested elements if this is a container field, nullptr if none
107   virtual const PacketField* GetElementField() const;
108 
109   // Return string representation of this field, that can be displayed for debugging or logging purposes
110   virtual void GenStringRepresentation(std::ostream& s, std::string accessor) const;
111 
112   std::string GetDebugName() const override;
113 
114   ParseLocation GetLocation() const override;
115 
116   virtual std::string GetName() const;
117 
118  private:
119   ParseLocation loc_;
120   std::string name_;
121 };
122