EmbeddedProto 4.0.0.dev19__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- embeddedproto-4.0.0.dev19/EmbeddedProto/EmbeddedProto.py +63 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/Field.py +578 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/Oneof.py +78 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/ProtoFile.py +188 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/TypeDefinitions.py +255 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/__init__.py +0 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/__main__.py +35 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/embedded_proto_options_pb2.py +37 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/main.py +199 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldBasic_Deserialize.h.jinja2 +33 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldBasic_GetSet.h.jinja2 +92 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldBasic_Serialize.h.jinja2 +37 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldBytes_GetSet.h.jinja2 +86 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldEnum_Deserialize.h.jinja2 +33 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldEnum_GetSet.h.jinja2 +86 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldEnum_Serialize.h.jinja2 +37 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldErrorRecursive_GetSet.h.jinja2 +36 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldMsg_Deserialize.h.jinja2 +33 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldMsg_GetSet.h.jinja2 +100 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldMsg_Serialize.h.jinja2 +37 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldRepeated_GetSet.h.jinja2 +95 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldRepeated_Serialize.h.jinja2 +33 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldStringBytes_Serialize.h.jinja2 +37 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/FieldString_GetSet.h.jinja2 +86 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/Header.h.jinja2 +75 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/TypeDefEnum.h.jinja2 +35 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/TypeDefMsg.h.jinja2 +473 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/templates/TypeOneof.h.jinja2 +180 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto/version.json +3 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto.egg-info/PKG-INFO +210 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto.egg-info/SOURCES.txt +38 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto.egg-info/dependency_links.txt +1 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto.egg-info/entry_points.txt +3 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto.egg-info/requires.txt +6 -0
- embeddedproto-4.0.0.dev19/EmbeddedProto.egg-info/top_level.txt +1 -0
- embeddedproto-4.0.0.dev19/PKG-INFO +210 -0
- embeddedproto-4.0.0.dev19/README.md +195 -0
- embeddedproto-4.0.0.dev19/pyproject.toml +35 -0
- embeddedproto-4.0.0.dev19/setup.cfg +4 -0
- embeddedproto-4.0.0.dev19/setup.py +85 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (C) 2020-2024 Embedded AMS B.V. - All Rights Reserved
|
|
3
|
+
#
|
|
4
|
+
# This file is part of Embedded Proto.
|
|
5
|
+
#
|
|
6
|
+
# Embedded Proto is open source software: you can redistribute it and/or
|
|
7
|
+
# modify it under the terms of the GNU General Public License as published
|
|
8
|
+
# by the Free Software Foundation, version 3 of the license.
|
|
9
|
+
#
|
|
10
|
+
# Embedded Proto is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Embedded Proto. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
#
|
|
18
|
+
# For commercial and closed source application please visit:
|
|
19
|
+
# <https://embeddedproto.com/pricing/>.
|
|
20
|
+
#
|
|
21
|
+
# Embedded AMS B.V.
|
|
22
|
+
# Info:
|
|
23
|
+
# info at EmbeddedProto dot com
|
|
24
|
+
#
|
|
25
|
+
# Postal address:
|
|
26
|
+
# Atoomweg 2
|
|
27
|
+
# 1627 LE, Hoorn
|
|
28
|
+
# the Netherlands
|
|
29
|
+
#
|
|
30
|
+
|
|
31
|
+
import sys
|
|
32
|
+
import grpc_tools.protoc as protoc
|
|
33
|
+
from importlib import resources
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def get_well_known_types_location():
|
|
37
|
+
# Obtain the location of the Protobuf well known types, they are a resource
|
|
38
|
+
# to the grpc-tools package the file system.
|
|
39
|
+
file_name = (
|
|
40
|
+
resources.files("grpc_tools") / "_proto"
|
|
41
|
+
).resolve()
|
|
42
|
+
return str(file_name)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def run_protoc(argv=sys.argv):
|
|
46
|
+
# Remove the program name
|
|
47
|
+
argv.pop(0)
|
|
48
|
+
|
|
49
|
+
# Check if the well known types should be included.
|
|
50
|
+
argv = ["-I" + get_well_known_types_location() if x == "--IncludeWellKnownTypes" else x for x in argv]
|
|
51
|
+
|
|
52
|
+
# Check if a plugin is included
|
|
53
|
+
if not [x for x in argv if x.startswith("--plugin")]:
|
|
54
|
+
# If not add the EmbeddedProto plugin
|
|
55
|
+
argv.insert(0, "--plugin=protoc-gen-eams")
|
|
56
|
+
|
|
57
|
+
protoc.main(argv)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
####################################################################################
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
run_protoc(sys.argv)
|
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (C) 2020-2024 Embedded AMS B.V. - All Rights Reserved
|
|
3
|
+
#
|
|
4
|
+
# This file is part of Embedded Proto.
|
|
5
|
+
#
|
|
6
|
+
# Embedded Proto is open source software: you can redistribute it and/or
|
|
7
|
+
# modify it under the terms of the GNU General Public License as published
|
|
8
|
+
# by the Free Software Foundation, version 3 of the license.
|
|
9
|
+
#
|
|
10
|
+
# Embedded Proto is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Embedded Proto. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
#
|
|
18
|
+
# For commercial and closed source application please visit:
|
|
19
|
+
# <https://embeddedproto.com/pricing/>.
|
|
20
|
+
#
|
|
21
|
+
# Embedded AMS B.V.
|
|
22
|
+
# Info:
|
|
23
|
+
# info at EmbeddedProto dot com
|
|
24
|
+
#
|
|
25
|
+
# Postal address:
|
|
26
|
+
# Atoomweg 2
|
|
27
|
+
# 1627 LE, Hoorn
|
|
28
|
+
# the Netherlands
|
|
29
|
+
#
|
|
30
|
+
|
|
31
|
+
from google.protobuf.descriptor_pb2 import FieldDescriptorProto
|
|
32
|
+
from . import embedded_proto_options_pb2
|
|
33
|
+
import copy
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# This class is the base class for any kind of field used in protobuf messages.
|
|
37
|
+
class Field:
|
|
38
|
+
def __init__(self, proto_descriptor, parent_msg, template_filename, oneof=None):
|
|
39
|
+
# A reference to the FieldDescriptorProto object which defines this field.
|
|
40
|
+
self.descriptor = proto_descriptor
|
|
41
|
+
|
|
42
|
+
# A reference to the parent message in which this field is defined.
|
|
43
|
+
self.parent = parent_msg
|
|
44
|
+
|
|
45
|
+
# Is this field optional, so do we need to track the presence of the field.
|
|
46
|
+
self.optional = self.descriptor.proto3_optional
|
|
47
|
+
|
|
48
|
+
# If this field is part of an oneof this is the reference to it.
|
|
49
|
+
self.oneof = oneof
|
|
50
|
+
|
|
51
|
+
self.name = self.descriptor.name
|
|
52
|
+
self.variable_name = self.name + "_"
|
|
53
|
+
self.variable_id_name = self.name.upper()
|
|
54
|
+
self.variable_id = self.descriptor.number
|
|
55
|
+
self.template_file = template_filename
|
|
56
|
+
|
|
57
|
+
self.of_type_enum = FieldDescriptorProto.TYPE_ENUM == proto_descriptor.type
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
# This function create the appropriate field object for a variable defined in the message.
|
|
61
|
+
# The descriptor and parent message parameters are required parameters, all field need them to be created. The oneof
|
|
62
|
+
# parameter is only required for fields which are part of a oneof. The parameter is the reference to the oneof
|
|
63
|
+
# object.
|
|
64
|
+
# The last parameter is not to be used manually. It is set when we are already in a FieldNested class.
|
|
65
|
+
def factory(proto_descriptor, parent_msg, oneof=None, already_nested=False):
|
|
66
|
+
|
|
67
|
+
# If this field has the same type as the parent we got a recursive inclusion. We can not solve the template
|
|
68
|
+
# parameters in this case. This field is thus replaced by a dummy with a warning. Toposort is used to find more
|
|
69
|
+
# complex recursive inclusions which we can not solve like this.
|
|
70
|
+
parent_msg_type = "." + parent_msg.scope.get_scope_str().replace("::", ".")
|
|
71
|
+
if proto_descriptor.type_name == parent_msg_type:
|
|
72
|
+
result = FieldErrorRecursive(proto_descriptor, parent_msg, oneof)
|
|
73
|
+
# Now continue constructing the normal fields.
|
|
74
|
+
elif (FieldDescriptorProto.LABEL_REPEATED == proto_descriptor.label) and not already_nested:
|
|
75
|
+
result = FieldRepeated(proto_descriptor, parent_msg, oneof)
|
|
76
|
+
elif FieldDescriptorProto.TYPE_MESSAGE == proto_descriptor.type:
|
|
77
|
+
result = FieldMessage(proto_descriptor, parent_msg, oneof)
|
|
78
|
+
elif FieldDescriptorProto.TYPE_ENUM == proto_descriptor.type:
|
|
79
|
+
result = FieldEnum(proto_descriptor, parent_msg, oneof)
|
|
80
|
+
elif FieldDescriptorProto.TYPE_STRING == proto_descriptor.type:
|
|
81
|
+
result = FieldString(proto_descriptor, parent_msg, oneof)
|
|
82
|
+
elif FieldDescriptorProto.TYPE_BYTES == proto_descriptor.type:
|
|
83
|
+
result = FieldBytes(proto_descriptor, parent_msg, oneof)
|
|
84
|
+
else:
|
|
85
|
+
result = FieldBasic(proto_descriptor, parent_msg, oneof)
|
|
86
|
+
return result
|
|
87
|
+
|
|
88
|
+
def get_wire_type_str(self):
|
|
89
|
+
return ""
|
|
90
|
+
|
|
91
|
+
def get_type(self):
|
|
92
|
+
return ""
|
|
93
|
+
|
|
94
|
+
def get_short_type(self):
|
|
95
|
+
return ""
|
|
96
|
+
|
|
97
|
+
def get_default_value(self):
|
|
98
|
+
return ""
|
|
99
|
+
|
|
100
|
+
def get_name(self):
|
|
101
|
+
return self.name
|
|
102
|
+
|
|
103
|
+
def get_variable_name(self):
|
|
104
|
+
var_name = ""
|
|
105
|
+
if self.oneof:
|
|
106
|
+
var_name = self.oneof.get_variable_name() + "."
|
|
107
|
+
var_name += self.variable_name
|
|
108
|
+
return var_name
|
|
109
|
+
|
|
110
|
+
def get_variable_id_name(self):
|
|
111
|
+
return self.variable_id_name
|
|
112
|
+
|
|
113
|
+
# Returns a list with a dictionaries for each template parameter this field had. The dictionary holds the parameter
|
|
114
|
+
# name and its type.
|
|
115
|
+
def get_template_parameters(self):
|
|
116
|
+
# For the field that do not have any templates return an empty list.
|
|
117
|
+
return []
|
|
118
|
+
|
|
119
|
+
def match_field_with_definitions(self, all_types_definitions):
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
def register_template_parameters(self):
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
# Returns true if in oneof.init the new& function needs to be call to initialize already allocated memory.
|
|
126
|
+
def oneof_allocation_required(self):
|
|
127
|
+
return type(self) is not FieldEnum
|
|
128
|
+
|
|
129
|
+
def get_oneof_name(self):
|
|
130
|
+
return self.oneof.get_name()
|
|
131
|
+
|
|
132
|
+
def get_which_oneof(self):
|
|
133
|
+
return self.oneof.get_which_oneof()
|
|
134
|
+
|
|
135
|
+
# Get the scope relevant compared to the scope this field is used in.
|
|
136
|
+
def get_reduced_scope(self):
|
|
137
|
+
parent_scope = self.parent.scope.get()
|
|
138
|
+
def_scope = self.definition.scope.get()
|
|
139
|
+
start_index = 0
|
|
140
|
+
for ds, ps in zip(def_scope[:-1], parent_scope):
|
|
141
|
+
if ds == ps:
|
|
142
|
+
start_index += 1
|
|
143
|
+
else:
|
|
144
|
+
break
|
|
145
|
+
reduced_scope = def_scope[start_index:]
|
|
146
|
+
return reduced_scope
|
|
147
|
+
|
|
148
|
+
def render(self, filename, jinja_environment):
|
|
149
|
+
template = jinja_environment.get_template(filename)
|
|
150
|
+
rendered_str = template.render(field=self, environment=jinja_environment)
|
|
151
|
+
return rendered_str
|
|
152
|
+
|
|
153
|
+
# -----------------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# This class is used to define any type of basic field.
|
|
157
|
+
class FieldBasic(Field):
|
|
158
|
+
# A dictionary to convert the wire type into a default value.
|
|
159
|
+
type_to_default_value = {FieldDescriptorProto.TYPE_DOUBLE: "0.0",
|
|
160
|
+
FieldDescriptorProto.TYPE_FLOAT: "0.0f",
|
|
161
|
+
FieldDescriptorProto.TYPE_INT64: "0",
|
|
162
|
+
FieldDescriptorProto.TYPE_UINT64: "0U",
|
|
163
|
+
FieldDescriptorProto.TYPE_INT32: "0",
|
|
164
|
+
FieldDescriptorProto.TYPE_FIXED64: "0U",
|
|
165
|
+
FieldDescriptorProto.TYPE_FIXED32: "0U",
|
|
166
|
+
FieldDescriptorProto.TYPE_BOOL: "false",
|
|
167
|
+
FieldDescriptorProto.TYPE_UINT32: "0U",
|
|
168
|
+
FieldDescriptorProto.TYPE_SFIXED32: "0",
|
|
169
|
+
FieldDescriptorProto.TYPE_SFIXED64: "0",
|
|
170
|
+
FieldDescriptorProto.TYPE_SINT32: "0",
|
|
171
|
+
FieldDescriptorProto.TYPE_SINT64: "0"}
|
|
172
|
+
|
|
173
|
+
# A dictionary to convert the protobuf wire type into an Embedded Proto C++ type.
|
|
174
|
+
type_to_cpp_type = {FieldDescriptorProto.TYPE_DOUBLE: "EmbeddedProto::doublefixed",
|
|
175
|
+
FieldDescriptorProto.TYPE_FLOAT: "EmbeddedProto::floatfixed",
|
|
176
|
+
FieldDescriptorProto.TYPE_INT64: "EmbeddedProto::int64",
|
|
177
|
+
FieldDescriptorProto.TYPE_UINT64: "EmbeddedProto::uint64",
|
|
178
|
+
FieldDescriptorProto.TYPE_INT32: "EmbeddedProto::int32",
|
|
179
|
+
FieldDescriptorProto.TYPE_FIXED64: "EmbeddedProto::fixed64",
|
|
180
|
+
FieldDescriptorProto.TYPE_FIXED32: "EmbeddedProto::fixed32",
|
|
181
|
+
FieldDescriptorProto.TYPE_BOOL: "EmbeddedProto::boolean",
|
|
182
|
+
FieldDescriptorProto.TYPE_UINT32: "EmbeddedProto::uint32",
|
|
183
|
+
FieldDescriptorProto.TYPE_SFIXED32: "EmbeddedProto::sfixed32",
|
|
184
|
+
FieldDescriptorProto.TYPE_SFIXED64: "EmbeddedProto::sfixed64",
|
|
185
|
+
FieldDescriptorProto.TYPE_SINT32: "EmbeddedProto::sint32",
|
|
186
|
+
FieldDescriptorProto.TYPE_SINT64: "EmbeddedProto::sint64"}
|
|
187
|
+
|
|
188
|
+
# A dictionary to convert the protobuf wire type into a C++ type.
|
|
189
|
+
type_to_cstdint = {FieldDescriptorProto.TYPE_DOUBLE: "double",
|
|
190
|
+
FieldDescriptorProto.TYPE_FLOAT: "float",
|
|
191
|
+
FieldDescriptorProto.TYPE_INT64: "int64_t",
|
|
192
|
+
FieldDescriptorProto.TYPE_UINT64: "uint64_t",
|
|
193
|
+
FieldDescriptorProto.TYPE_INT32: "int32_t",
|
|
194
|
+
FieldDescriptorProto.TYPE_FIXED64: "uint64_t",
|
|
195
|
+
FieldDescriptorProto.TYPE_FIXED32: "uint32_t",
|
|
196
|
+
FieldDescriptorProto.TYPE_BOOL: "bool",
|
|
197
|
+
FieldDescriptorProto.TYPE_UINT32: "uint32_t",
|
|
198
|
+
FieldDescriptorProto.TYPE_SFIXED32: "int32_t",
|
|
199
|
+
FieldDescriptorProto.TYPE_SFIXED64: "int64_t",
|
|
200
|
+
FieldDescriptorProto.TYPE_SINT32: "int32_t",
|
|
201
|
+
FieldDescriptorProto.TYPE_SINT64: "int64_t"}
|
|
202
|
+
|
|
203
|
+
# A dictionary to convert the wire type number into a wire type string.
|
|
204
|
+
type_to_wire_type = {FieldDescriptorProto.TYPE_INT32: "VARINT",
|
|
205
|
+
FieldDescriptorProto.TYPE_INT64: "VARINT",
|
|
206
|
+
FieldDescriptorProto.TYPE_UINT32: "VARINT",
|
|
207
|
+
FieldDescriptorProto.TYPE_UINT64: "VARINT",
|
|
208
|
+
FieldDescriptorProto.TYPE_SINT32: "VARINT",
|
|
209
|
+
FieldDescriptorProto.TYPE_SINT64: "VARINT",
|
|
210
|
+
FieldDescriptorProto.TYPE_BOOL: "VARINT",
|
|
211
|
+
FieldDescriptorProto.TYPE_FIXED64: "FIXED64",
|
|
212
|
+
FieldDescriptorProto.TYPE_SFIXED64: "FIXED64",
|
|
213
|
+
FieldDescriptorProto.TYPE_DOUBLE: "FIXED64",
|
|
214
|
+
FieldDescriptorProto.TYPE_FIXED32: "FIXED32",
|
|
215
|
+
FieldDescriptorProto.TYPE_FLOAT: "FIXED32",
|
|
216
|
+
FieldDescriptorProto.TYPE_SFIXED32: "FIXED32"}
|
|
217
|
+
|
|
218
|
+
def __init__(self, proto_descriptor, parent_msg, oneof=None):
|
|
219
|
+
super().__init__(proto_descriptor, parent_msg, "FieldBasic.h.jinja2", oneof)
|
|
220
|
+
|
|
221
|
+
def get_wire_type_str(self):
|
|
222
|
+
return self.type_to_wire_type[self.descriptor.type]
|
|
223
|
+
|
|
224
|
+
def get_type(self):
|
|
225
|
+
return self.type_to_cpp_type[self.descriptor.type]
|
|
226
|
+
|
|
227
|
+
def get_short_type(self):
|
|
228
|
+
return self.get_type().split("::")[-1]
|
|
229
|
+
|
|
230
|
+
def get_cstdint_type(self):
|
|
231
|
+
return self.type_to_cstdint[self.descriptor.type]
|
|
232
|
+
|
|
233
|
+
def get_default_value(self):
|
|
234
|
+
return self.type_to_default_value[self.descriptor.type]
|
|
235
|
+
|
|
236
|
+
def render_get_set(self, jinja_env):
|
|
237
|
+
return self.render("FieldBasic_GetSet.h.jinja2", jinja_environment=jinja_env)
|
|
238
|
+
|
|
239
|
+
def render_serialize(self, jinja_env):
|
|
240
|
+
return self.render("FieldBasic_Serialize.h.jinja2", jinja_environment=jinja_env)
|
|
241
|
+
|
|
242
|
+
def render_deserialize(self, jinja_env):
|
|
243
|
+
str = self.render("FieldBasic_Deserialize.h.jinja2", jinja_environment=jinja_env)
|
|
244
|
+
return str.rstrip()
|
|
245
|
+
|
|
246
|
+
# -----------------------------------------------------------------------------
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
# A base class for both the String and Bytes type field
|
|
250
|
+
class BaseStringBytes(Field):
|
|
251
|
+
def __init__(self, proto_descriptor, parent_msg, oneof=None):
|
|
252
|
+
super().__init__(proto_descriptor, parent_msg, "FieldString.h.jinja2", oneof)
|
|
253
|
+
|
|
254
|
+
# This is the name given to the template parameter for the length.
|
|
255
|
+
self.template_param_str = self.parent.name + "_" + self.variable_name + "LENGTH"
|
|
256
|
+
|
|
257
|
+
# Find options we know and use in this type of field.
|
|
258
|
+
self.MaxLength = None
|
|
259
|
+
if self.descriptor.options.HasExtension(embedded_proto_options_pb2.options):
|
|
260
|
+
self.MaxLength = self.descriptor.options.Extensions[embedded_proto_options_pb2.options].maxLength
|
|
261
|
+
|
|
262
|
+
def get_wire_type_str(self):
|
|
263
|
+
return "LENGTH_DELIMITED"
|
|
264
|
+
|
|
265
|
+
def get_template_parameters(self):
|
|
266
|
+
result = []
|
|
267
|
+
# When we do not have a maximum length specified add the length as a template param.
|
|
268
|
+
if not self.MaxLength:
|
|
269
|
+
result.append({"name": self.template_param_str, "type": "uint32_t"})
|
|
270
|
+
return result
|
|
271
|
+
|
|
272
|
+
def register_template_parameters(self):
|
|
273
|
+
# If we do not have a max length defined register the template parameter.
|
|
274
|
+
if not self.MaxLength:
|
|
275
|
+
self.parent.register_child_with_template(self)
|
|
276
|
+
return True
|
|
277
|
+
|
|
278
|
+
def render_serialize(self, jinja_env):
|
|
279
|
+
return self.render("FieldStringBytes_Serialize.h.jinja2", jinja_environment=jinja_env)
|
|
280
|
+
|
|
281
|
+
def render_deserialize(self, jinja_env):
|
|
282
|
+
str = self.render("FieldBasic_Deserialize.h.jinja2", jinja_environment=jinja_env)
|
|
283
|
+
return str.rstrip()
|
|
284
|
+
|
|
285
|
+
# -----------------------------------------------------------------------------
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
# This class defines a string field
|
|
289
|
+
class FieldString(BaseStringBytes):
|
|
290
|
+
def __init__(self, proto_descriptor, parent_msg, oneof=None):
|
|
291
|
+
super().__init__(proto_descriptor, parent_msg, oneof)
|
|
292
|
+
|
|
293
|
+
def get_type(self):
|
|
294
|
+
str_type = "::EmbeddedProto::FieldString<"
|
|
295
|
+
if self.MaxLength:
|
|
296
|
+
str_type += str(self.MaxLength) + ">"
|
|
297
|
+
else:
|
|
298
|
+
str_type += self.template_param_str + ">"
|
|
299
|
+
return str_type
|
|
300
|
+
|
|
301
|
+
def get_short_type(self):
|
|
302
|
+
return "FieldString"
|
|
303
|
+
|
|
304
|
+
def render_get_set(self, jinja_env):
|
|
305
|
+
return self.render("FieldString_GetSet.h.jinja2", jinja_environment=jinja_env)
|
|
306
|
+
|
|
307
|
+
# -----------------------------------------------------------------------------
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
# This class defines a bytes array field
|
|
311
|
+
class FieldBytes(BaseStringBytes):
|
|
312
|
+
def __init__(self, proto_descriptor, parent_msg, oneof=None):
|
|
313
|
+
super().__init__(proto_descriptor, parent_msg, oneof)
|
|
314
|
+
|
|
315
|
+
def get_type(self):
|
|
316
|
+
str_type = "::EmbeddedProto::FieldBytes<"
|
|
317
|
+
if self.MaxLength:
|
|
318
|
+
str_type += str(self.MaxLength) + ">"
|
|
319
|
+
else:
|
|
320
|
+
str_type += self.template_param_str + ">"
|
|
321
|
+
return str_type
|
|
322
|
+
|
|
323
|
+
def get_short_type(self):
|
|
324
|
+
return "FieldBytes"
|
|
325
|
+
|
|
326
|
+
def render_get_set(self, jinja_env):
|
|
327
|
+
return self.render("FieldBytes_GetSet.h.jinja2", jinja_environment=jinja_env)
|
|
328
|
+
|
|
329
|
+
# -----------------------------------------------------------------------------
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
# This class is used to wrap around any enum used as a field.
|
|
333
|
+
class FieldEnum(Field):
|
|
334
|
+
def __init__(self, proto_descriptor, parent_msg, oneof=None):
|
|
335
|
+
super().__init__(proto_descriptor, parent_msg, "FieldEnum.h.jinja2", oneof)
|
|
336
|
+
|
|
337
|
+
# Reserve a member variable for the reference to the enum definition used for this field.
|
|
338
|
+
self.definition = None
|
|
339
|
+
|
|
340
|
+
def get_wire_type_str(self):
|
|
341
|
+
return "VARINT"
|
|
342
|
+
|
|
343
|
+
def get_type_as_defined(self):
|
|
344
|
+
if not self.definition:
|
|
345
|
+
# When the actual definition is unknown use the protobuf type.
|
|
346
|
+
type_name = self.descriptor.type_name if "." != self.descriptor.type_name[0] else self.descriptor.type_name[1:]
|
|
347
|
+
type_name = type_name.replace(".", "::")
|
|
348
|
+
else:
|
|
349
|
+
scopes = self.get_reduced_scope()
|
|
350
|
+
type_name = ""
|
|
351
|
+
for scope in scopes:
|
|
352
|
+
if scope["templates"]:
|
|
353
|
+
raise Exception("You are trying to use a field with the type: \"" + self.descriptor.type_name +
|
|
354
|
+
"\". It is defined in different scope as where you are using it. But the scope of "
|
|
355
|
+
"definition includes template parameters for repeated, string or byte fields. It "
|
|
356
|
+
"is there for not possible to define the field where you are using it as we do not "
|
|
357
|
+
"know the template value. Try defining the field in the main scope or the one you "
|
|
358
|
+
"are using it in.")
|
|
359
|
+
|
|
360
|
+
type_name += scope["name"] + "::"
|
|
361
|
+
# Remove the last ::
|
|
362
|
+
type_name = type_name[:-2]
|
|
363
|
+
|
|
364
|
+
return type_name
|
|
365
|
+
|
|
366
|
+
def get_max_enum_value(self):
|
|
367
|
+
# Return the maximum value used by any of the enum items as a string. This is used to calculate the maximum serialized size.
|
|
368
|
+
max_number = self.definition.descriptor.value[0].number
|
|
369
|
+
for value in self.definition.descriptor.value[1:]:
|
|
370
|
+
if max_number < value.number:
|
|
371
|
+
max_number = value.number
|
|
372
|
+
return str(max_number)
|
|
373
|
+
def get_type(self):
|
|
374
|
+
return "EmbeddedProto::enumeration<" + self.get_type_as_defined() + ", EmbeddedProto::WireFormatter::VarintSize(" + self.get_max_enum_value() + ")>"
|
|
375
|
+
|
|
376
|
+
def get_short_type(self):
|
|
377
|
+
return "EmbeddedProto::enumeration<" + self.get_type_as_defined().split("::")[-1] + ", EmbeddedProto::WireFormatter::VarintSize(" + self.get_max_enum_value() + ")>"
|
|
378
|
+
|
|
379
|
+
def get_default_value(self):
|
|
380
|
+
return "static_cast<" + self.get_type_as_defined() + ">(0)"
|
|
381
|
+
|
|
382
|
+
def match_field_with_definitions(self, all_types_definitions):
|
|
383
|
+
found = False
|
|
384
|
+
my_type = self.get_type_as_defined()
|
|
385
|
+
for enum_defs in all_types_definitions["enums"]:
|
|
386
|
+
other_scope = enum_defs.scope.get_scope_str()
|
|
387
|
+
if my_type == other_scope:
|
|
388
|
+
self.definition = enum_defs
|
|
389
|
+
found = True
|
|
390
|
+
break
|
|
391
|
+
|
|
392
|
+
if not found:
|
|
393
|
+
raise Exception("Unable to find the definition of this enum: " + self.name)
|
|
394
|
+
|
|
395
|
+
def render_get_set(self, jinja_env):
|
|
396
|
+
return self.render("FieldEnum_GetSet.h.jinja2", jinja_environment=jinja_env)
|
|
397
|
+
|
|
398
|
+
def render_serialize(self, jinja_env):
|
|
399
|
+
return self.render("FieldEnum_Serialize.h.jinja2", jinja_environment=jinja_env)
|
|
400
|
+
|
|
401
|
+
def render_deserialize(self, jinja_env):
|
|
402
|
+
return self.render("FieldEnum_Deserialize.h.jinja2", jinja_environment=jinja_env)
|
|
403
|
+
|
|
404
|
+
# -----------------------------------------------------------------------------
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
# This class is used to wrap around any type of message used as a field.
|
|
408
|
+
class FieldMessage(Field):
|
|
409
|
+
def __init__(self, proto_descriptor, parent_msg, oneof=None):
|
|
410
|
+
super().__init__(proto_descriptor, parent_msg, "FieldMsg.h.jinja2", oneof)
|
|
411
|
+
|
|
412
|
+
# Reserve a member variable for the reference to the message definition used for this field.
|
|
413
|
+
self.definition = None
|
|
414
|
+
|
|
415
|
+
def get_wire_type_str(self):
|
|
416
|
+
return "LENGTH_DELIMITED"
|
|
417
|
+
|
|
418
|
+
def get_type(self):
|
|
419
|
+
if not self.definition:
|
|
420
|
+
# When the actual definition is unknown use the protobuf type.
|
|
421
|
+
type_name = self.descriptor.type_name if "." != self.descriptor.type_name[0] else self.descriptor.type_name[1:]
|
|
422
|
+
type_name = type_name.replace(".", "::")
|
|
423
|
+
else:
|
|
424
|
+
scopes = self.get_reduced_scope()
|
|
425
|
+
type_name = ""
|
|
426
|
+
for scope in scopes:
|
|
427
|
+
type_name += scope["name"] + "::"
|
|
428
|
+
# Remove the last ::
|
|
429
|
+
type_name = type_name[:-2]
|
|
430
|
+
|
|
431
|
+
tmpl_param = self.get_template_parameters()
|
|
432
|
+
if tmpl_param:
|
|
433
|
+
type_name += "<"
|
|
434
|
+
for param in tmpl_param:
|
|
435
|
+
type_name += param["name"] + ", "
|
|
436
|
+
type_name = type_name[:-2] + ">"
|
|
437
|
+
|
|
438
|
+
return type_name
|
|
439
|
+
|
|
440
|
+
def get_short_type(self):
|
|
441
|
+
return self.get_type().split("::")[-1]
|
|
442
|
+
|
|
443
|
+
def get_default_value(self):
|
|
444
|
+
# Just call the default constructor.
|
|
445
|
+
return ""
|
|
446
|
+
|
|
447
|
+
def get_template_parameters(self):
|
|
448
|
+
# Get the template names used by the definition.
|
|
449
|
+
templates = copy.deepcopy(self.definition.get_templates())
|
|
450
|
+
# Next add our variable name to make them unique.
|
|
451
|
+
for tmp in templates:
|
|
452
|
+
tmp["name"] = self.parent.name + "_" + self.variable_name + tmp["name"]
|
|
453
|
+
return templates
|
|
454
|
+
|
|
455
|
+
def match_field_with_definitions(self, all_types_definitions):
|
|
456
|
+
found = False
|
|
457
|
+
my_type = self.get_type()
|
|
458
|
+
for msg_defs in all_types_definitions["messages"]:
|
|
459
|
+
other_scope = msg_defs.scope.get_scope_str()
|
|
460
|
+
if my_type == other_scope:
|
|
461
|
+
self.definition = msg_defs
|
|
462
|
+
found = True
|
|
463
|
+
break
|
|
464
|
+
|
|
465
|
+
if not found:
|
|
466
|
+
raise Exception("Unable to find the definition of this message: " + self.name)
|
|
467
|
+
|
|
468
|
+
def register_template_parameters(self):
|
|
469
|
+
if self.definition.all_parameters_registered:
|
|
470
|
+
if self.definition.contains_template_parameters:
|
|
471
|
+
self.parent.register_child_with_template(self)
|
|
472
|
+
return True
|
|
473
|
+
else:
|
|
474
|
+
return False
|
|
475
|
+
|
|
476
|
+
# Get the whole scope of the definition of this field.
|
|
477
|
+
def get_scope(self):
|
|
478
|
+
return self.definition.scope.get()
|
|
479
|
+
|
|
480
|
+
def render_get_set(self, jinja_env):
|
|
481
|
+
return self.render("FieldMsg_GetSet.h.jinja2", jinja_environment=jinja_env)
|
|
482
|
+
|
|
483
|
+
def render_serialize(self, jinja_env):
|
|
484
|
+
return self.render("FieldMsg_Serialize.h.jinja2", jinja_environment=jinja_env)
|
|
485
|
+
|
|
486
|
+
def render_deserialize(self, jinja_env):
|
|
487
|
+
return self.render("FieldMsg_Deserialize.h.jinja2", jinja_environment=jinja_env)
|
|
488
|
+
|
|
489
|
+
# -----------------------------------------------------------------------------
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
# This class wraps around any other type of field which is repeated.
|
|
493
|
+
class FieldRepeated(Field):
|
|
494
|
+
def __init__(self, proto_descriptor, parent_msg, oneof=None):
|
|
495
|
+
super().__init__(proto_descriptor, parent_msg, "FieldRepeated.h", oneof)
|
|
496
|
+
|
|
497
|
+
# To make use of the field object actual type create one of their objects.
|
|
498
|
+
self.actual_type = Field.factory(proto_descriptor, parent_msg, oneof, already_nested=True)
|
|
499
|
+
|
|
500
|
+
# This is the name given to the template parameter for the length.
|
|
501
|
+
self.template_param_str = self.parent.name + "_" + self.variable_name + "REP_LENGTH"
|
|
502
|
+
|
|
503
|
+
# Find options we know and use in this type of field.
|
|
504
|
+
self.MaxLength = None
|
|
505
|
+
if self.descriptor.options.HasExtension(embedded_proto_options_pb2.options):
|
|
506
|
+
self.MaxLength = self.descriptor.options.Extensions[embedded_proto_options_pb2.options].maxLength
|
|
507
|
+
|
|
508
|
+
def get_wire_type_str(self):
|
|
509
|
+
return "LENGTH_DELIMITED"
|
|
510
|
+
|
|
511
|
+
def get_type(self):
|
|
512
|
+
type_str = "::EmbeddedProto::RepeatedFieldFixedSize<" + self.actual_type.get_type() + ", "
|
|
513
|
+
if self.MaxLength:
|
|
514
|
+
type_str += str(self.MaxLength) + ">"
|
|
515
|
+
else:
|
|
516
|
+
type_str += self.template_param_str + ">"
|
|
517
|
+
return type_str
|
|
518
|
+
|
|
519
|
+
def get_short_type(self):
|
|
520
|
+
type_str = "::EmbeddedProto::RepeatedFieldFixedSize<" + self.actual_type.get_type() + ", "
|
|
521
|
+
if self.MaxLength:
|
|
522
|
+
type_str += str(self.MaxLength) + ">"
|
|
523
|
+
else:
|
|
524
|
+
type_str += self.template_param_str + ">"
|
|
525
|
+
return type_str
|
|
526
|
+
|
|
527
|
+
# As this is a repeated field we need a function to get the type we are repeating.
|
|
528
|
+
def get_base_type(self):
|
|
529
|
+
return self.actual_type.get_type()
|
|
530
|
+
|
|
531
|
+
def get_template_parameters(self):
|
|
532
|
+
result = []
|
|
533
|
+
# When we do not have a maximum length specified add the length as a template param.
|
|
534
|
+
if not self.MaxLength:
|
|
535
|
+
result.append({"name": self.template_param_str, "type": "uint32_t"})
|
|
536
|
+
result.extend(self.actual_type.get_template_parameters())
|
|
537
|
+
return result
|
|
538
|
+
|
|
539
|
+
def match_field_with_definitions(self, all_types_definitions):
|
|
540
|
+
self.actual_type.match_field_with_definitions(all_types_definitions)
|
|
541
|
+
|
|
542
|
+
def register_template_parameters(self):
|
|
543
|
+
# If we do not have a max length defined register the template parameter.
|
|
544
|
+
if not self.MaxLength:
|
|
545
|
+
self.parent.register_child_with_template(self)
|
|
546
|
+
return True
|
|
547
|
+
|
|
548
|
+
def render_get_set(self, jinja_env):
|
|
549
|
+
return self.render("FieldRepeated_GetSet.h.jinja2", jinja_environment=jinja_env)
|
|
550
|
+
|
|
551
|
+
def render_serialize(self, jinja_env):
|
|
552
|
+
return self.render("FieldRepeated_Serialize.h.jinja2", jinja_environment=jinja_env)
|
|
553
|
+
|
|
554
|
+
def render_deserialize(self, jinja_env):
|
|
555
|
+
str = self.render("FieldBasic_Deserialize.h.jinja2", jinja_environment=jinja_env)
|
|
556
|
+
return str.rstrip()
|
|
557
|
+
|
|
558
|
+
# -----------------------------------------------------------------------------
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
# This class represents a field we can not include because it causes a recursive inclusion.
|
|
562
|
+
class FieldErrorRecursive(Field):
|
|
563
|
+
def __init__(self, proto_descriptor, parent_msg, oneof=None):
|
|
564
|
+
super().__init__(proto_descriptor, parent_msg, "FieldRepeated.h.jinja2", oneof)
|
|
565
|
+
|
|
566
|
+
self.descriptor.type_name = "FieldErrorRecursive"
|
|
567
|
+
|
|
568
|
+
def get_type(self):
|
|
569
|
+
return "//"
|
|
570
|
+
|
|
571
|
+
def render_get_set(self, jinja_env):
|
|
572
|
+
return self.render("FieldErrorRecursive_GetSet.h.jinja2", jinja_environment=jinja_env)
|
|
573
|
+
|
|
574
|
+
def render_serialize(self, jinja_env):
|
|
575
|
+
return ""
|
|
576
|
+
|
|
577
|
+
def render_deserialize(self, jinja_env):
|
|
578
|
+
return ""
|