API: Use string type instead of u8.
[vpp.git] / extras / japi / java / jvpp / gen / jvppgen / jni_common_gen.py
1 #!/usr/bin/env python2
2 #
3 # Copyright (c) 2018 Cisco and/or its affiliates.
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 from string import Template
17
18 from jvpp_model import is_array, is_retval, Class, Enum, Union
19
20
21 def generate_j2c_identifiers(element, class_ref_name, object_ref_name):
22     identifiers = []
23     for field in element.fields:
24         field_type = field.type
25         identifiers.append(_REQUEST_FIELD_IDENTIFIER_TEMPLATE.substitute(
26             java_name=field.java_name,
27             class_ref_name=class_ref_name,
28             jni_signature=field_type.jni_signature,
29             jni_type=field_type.jni_type,
30             jni_accessor=field_type.jni_accessor,
31             object_ref_name=object_ref_name
32         ))
33     return "".join(identifiers)
34
35 _REQUEST_FIELD_IDENTIFIER_TEMPLATE = Template("""
36     jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}, "${java_name}", "${jni_signature}");
37     ${jni_type} ${java_name} = (*env)->Get${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId);
38 """)
39
40
41 # TODO(VPP-1187): do not inline JNI object creation inside message handlers to reduce number of special cases
42 def generate_j2c_swap(element, struct_ref_name, is_alias):
43     initialization = []
44     for field in element.fields:
45         initialization.append(generate_j2c_field_swap(field, struct_ref_name, is_alias))
46     return "\n".join(initialization)
47
48
49 def generate_j2c_field_swap(field, struct_ref_name, is_alias):
50     if is_array(field):
51         return _generate_j2c_array_swap(field, struct_ref_name, is_alias)
52     else:
53         return _generate_j2c_scalar_swap(field, struct_ref_name, is_alias)
54
55
56 def _generate_j2c_array_swap(field, struct_ref_name, is_alias):
57     # TODO(VPP-1186): move the logic to JNI generators
58     base_type = field.type.base_type
59     if isinstance(base_type, (Class, Enum, Union)):
60         return _generate_j2c_object_array_swap(field, struct_ref_name)
61     elif base_type.is_swap_needed:
62         return _generate_j2c_primitive_type_array_swap(field, struct_ref_name)
63     else:
64         return _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name, is_alias)
65
66
67 def _generate_j2c_object_array_swap(field, struct_ref_name):
68     field_type = field.type
69     field_reference_name = field.java_name
70     c_name = field.name
71     host = "%sArrayElement" % field_reference_name
72     net = "%s->%s[_i]" % (struct_ref_name, c_name)
73     swap_elements = field_type.get_host_to_net_function(host, net)
74     return _J2C_OBJECT_ARRAY_SWAP_TEMPLATE.substitute(
75         field_reference_name=field_reference_name,
76         field_length_check=_generate_field_length_check(field),
77         swap_elements=swap_elements)
78
79 _J2C_OBJECT_ARRAY_SWAP_TEMPLATE = Template("""
80     {
81         if (${field_reference_name}) {
82             size_t _i;
83             jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
84             ${field_length_check}
85             for (_i = 0; _i < cnt; _i++) {
86                 jobject ${field_reference_name}ArrayElement = (*env)->GetObjectArrayElement(env, ${field_reference_name}, _i);
87                 ${swap_elements};
88             }
89         }
90     }
91 """)
92
93
94 def _generate_j2c_primitive_type_array_swap(field, struct_ref_name):
95     field_reference_name = field.java_name
96     field_type = field.type
97     host = "%sArrayElements[_i]" % field_reference_name
98     net = "%s->%s[_i]" % (struct_ref_name,  field.name)
99     swap_elements = field_type.get_host_to_net_function(host, net)
100     return _J2C_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE.substitute(
101         field_reference_name=field_reference_name,
102         field_length_check=_generate_field_length_check(field),
103         base_type=field_type.base_type.jni_accessor,
104         jni_base_type=field_type.base_type.jni_type,
105         swap_elements=swap_elements
106     )
107
108 _J2C_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE = Template("""
109     if (${field_reference_name}) {
110         ${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL);
111         size_t _i;
112         jsize cnt = (*env)->GetArrayLength(env, ${field_reference_name});
113         ${field_length_check}
114         for (_i = 0; _i < cnt; _i++) {
115             ${swap_elements};
116         }
117         (*env)->Release${base_type}ArrayElements (env, ${field_reference_name}, ${field_reference_name}ArrayElements, 0);
118     }
119     """)
120
121
122 def _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name, is_alias):
123     field_type = field.type
124     if not is_alias:
125         template = _J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
126     else:
127         template = _J2C_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
128
129     return template.substitute(
130         field_reference_name=field.java_name,
131         field_length_check=_generate_field_length_check(field),
132         base_type=field_type.base_type.jni_accessor,
133         jni_base_type=field_type.base_type.jni_type,
134         struct_reference_name=struct_ref_name,
135         c_name=field.name
136     )
137
138 _J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
139     if (${field_reference_name}) {
140         jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
141         ${field_length_check}
142         (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name}->${c_name});
143     }
144 """)
145
146
147 _J2C_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
148     if (${field_reference_name}) {
149         jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
150         ${field_length_check}
151         (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name});
152     }
153 """)
154
155
156 def _generate_field_length_check(field):
157     # Enforce max length if array has fixed length or uses variable length syntax
158     field_length = str(field.array_len)
159     if field.array_len_field:
160         field_length = field.array_len_field.java_name
161
162     # TODO: remove when ZLAs without length field are disabled
163     if field_length != "0":
164         return _FIELD_LENGTH_CHECK.substitute(field_length=field_length)
165     else:
166         return ""
167
168
169 # Make sure we do not write more elements that are expected
170 _FIELD_LENGTH_CHECK = Template("""
171         size_t max_size = ${field_length};
172         if (cnt > max_size) cnt = max_size;""")
173
174
175 def _generate_j2c_scalar_swap(field, struct_ref_name, is_alias):
176     field_type = field.type
177     if field_type.is_swap_needed:
178         host = field.java_name
179         if not is_alias:
180             net = "%s->%s" % (struct_ref_name, field.name)
181             if field_type.name == "string":
182                 net = "%s->%s" % (struct_ref_name, field.name)
183                 return "    _host_to_net_%s(env, %s, (vl_api_string_t *) &%s);" % (field_type.name, host, net)
184             else:
185                 return "    %s;" % field_type.get_host_to_net_function(host, net)
186         else:
187             net = "%s" % struct_ref_name
188             return "    *%s;" % field_type.get_host_to_net_function(host, net)
189     else:
190         return "    %s->%s = %s;" % (struct_ref_name, field.name, field.java_name)
191
192
193 def generate_c2j_swap(element, object_ref_name, struct_ref_name, is_alias):
194     msg_java_name = element.java_name_lower
195     initialization = []
196     for field in element.fields:
197         if is_retval(field):
198             # For retval don't generate setters and generate retval check
199             continue
200         elif is_array(field):
201             initialization.append(_generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias))
202         else:
203             initialization.append(_generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias))
204     return "".join(initialization)
205
206
207 def _generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
208     # TODO(VPP-1186): move the logic to JNI generators
209     base_type = field.type.base_type
210     if isinstance(base_type, (Class, Union)):
211         return _generate_c2j_object_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
212     elif isinstance(base_type, Enum):
213         return _generate_c2j_enum_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
214     elif base_type.is_swap_needed:
215         return _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
216     else:
217         return _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias)
218
219
220 def _generate_c2j_object_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
221     field_type = field.type
222     return _C2J_OBJECT_ARRAY_SWAP_TEMPLATE.substitute(
223         field_reference_name=field.java_name,
224         class_ref_name=msg_java_name,
225         jni_signature=field_type.jni_signature,
226         jni_name=field_type.base_type.jni_name,
227         field_length=_generate_array_length(field, struct_ref_name),
228         net_to_host_function=field_type.net_to_host_function,
229         struct_ref_name=struct_ref_name,
230         object_ref_name=object_ref_name,
231         c_name=field.name
232     )
233
234 _C2J_OBJECT_ARRAY_SWAP_TEMPLATE = Template("""
235     jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
236     {
237         jclass ${field_reference_name}Class = (*env)->FindClass(env, "${jni_name}");
238         jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0);
239         jmethodID ${field_reference_name}Constructor = (*env)->GetMethodID(env, ${field_reference_name}Class, "<init>", "()V");
240         unsigned int _i;
241         for (_i = 0; _i < ${field_length}; _i++) {
242             jobject ${field_reference_name}ArrayElement = (*env)->NewObject(env, ${field_reference_name}Class,  ${field_reference_name}Constructor);
243             ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}[_i]), ${field_reference_name}ArrayElement);
244             (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement);
245             (*env)->DeleteLocalRef(env, ${field_reference_name}ArrayElement);
246         }
247         (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
248         (*env)->DeleteLocalRef(env, ${field_reference_name});
249     }
250 """)
251
252
253 def _generate_c2j_enum_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
254     field_type = field.type
255     base_type = field_type.base_type
256     return _C2J_ENUM_ARRAY_SWAP_TEMPLATE.substitute(
257         field_reference_name=field.java_name,
258         class_ref_name=msg_java_name,
259         jni_signature=field_type.jni_signature,
260         jni_name=base_type.jni_name,
261         field_length=_generate_array_length(field, struct_ref_name),
262         net_to_host_function=field_type.net_to_host_function,
263         jni_signature_enum_value=base_type.value.type.jni_signature,
264         struct_ref_name=struct_ref_name,
265         object_ref_name=object_ref_name,
266         c_name=field.name
267     )
268
269 _C2J_ENUM_ARRAY_SWAP_TEMPLATE = Template("""
270     jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
271     {
272         jclass ${field_reference_name}Class = (*env)->FindClass(env, "${jni_name}");
273         jobjectArray ${field_reference_name} = (*env)->NewObjectArray(env, ${field_length}, ${field_reference_name}Class, 0);
274         jmethodID ${field_reference_name}Constructor = (*env)->GetStaticMethodID(env, ${field_reference_name}Class, "forValue", "(${jni_signature_enum_value})${jni_signature}");
275         unsigned int _i;
276         for (_i = 0; _i < ${field_length}; _i++) {
277             jobject ${field_reference_name}ArrayElement = (*env)->CallStaticObjectMethod(env, ${field_reference_name}Class, ${field_reference_name}Constructor, ${net_to_host_function}(${struct_ref_name}->${c_name}[_i]));
278             (*env)->SetObjectArrayElement(env, ${field_reference_name}, _i, ${field_reference_name}ArrayElement);
279             (*env)->DeleteLocalRef(env, ${field_reference_name}ArrayElement);
280         }
281         (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
282         (*env)->DeleteLocalRef(env, ${field_reference_name});
283     }
284 """)
285
286
287 def _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
288     field_type = field.type
289     return _C2J_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE.substitute(
290         field_reference_name=field.java_name,
291         class_ref_name=msg_java_name,
292         jni_signature=field_type.jni_signature,
293         jni_type=field_type.jni_type,
294         base_type=field_type.base_type.jni_accessor,
295         field_length=_generate_array_length(field, struct_ref_name),
296         jni_base_type=field_type.base_type.jni_type,
297         object_ref_name=object_ref_name,
298         struct_ref_name=struct_ref_name,
299         net_to_host_function=field_type.net_to_host_function,
300         c_name=field.name
301     )
302
303 _C2J_PRIMITIVE_TYPE_ARRAY_SWAP_TEMPLATE = Template("""
304     jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
305     {
306         ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
307         ${jni_base_type} * ${field_reference_name}ArrayElements = (*env)->Get${base_type}ArrayElements(env, ${field_reference_name}, NULL);
308         unsigned int _i;
309         for (_i = 0; _i < ${field_length}; _i++) {
310             ${field_reference_name}ArrayElements[_i] = ${net_to_host_function}(${struct_ref_name}->${c_name}[_i]);
311         }
312
313         (*env)->Release${base_type}ArrayElements(env,  ${field_reference_name}, ${field_reference_name}ArrayElements, 0);
314         (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
315         (*env)->DeleteLocalRef(env, ${field_reference_name});
316     }
317 """)
318
319
320 def _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
321     field_type = field.type
322     if not is_alias:
323         template = _C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
324     else:
325         template = _C2J_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
326     return template.substitute(
327         field_reference_name=field.java_name,
328         class_ref_name=msg_java_name,
329         jni_signature=field_type.jni_signature,
330         jni_type=field_type.jni_type,
331         base_type=field_type.base_type.jni_accessor,
332         field_length=_generate_array_length(field, struct_ref_name),
333         jni_base_type=field_type.base_type.jni_type,
334         object_ref_name=object_ref_name,
335         struct_ref_name=struct_ref_name,
336         c_name=field.name
337     )
338
339 _C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
340     jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
341     ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
342     (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name}->${c_name});
343     (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
344     (*env)->DeleteLocalRef(env, ${field_reference_name});
345 """)
346
347
348 _C2J_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
349     jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
350     ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
351     (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name});
352     (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
353     (*env)->DeleteLocalRef(env, ${field_reference_name});
354 """)
355
356
357 def _generate_array_length(field, struct_ref_name):
358     if field.array_len_field:
359         len_field = field.array_len_field
360         if len_field.type.is_swap_needed:
361             return "%s(%s->%s)" % (len_field.type.host_to_net_function, struct_ref_name, len_field.name)
362         else:
363             return "%s->%s" % (struct_ref_name, len_field.name)
364     return field.array_len
365
366
367 def _generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
368     field_type = field.type
369     if field_type.is_swap_needed:
370         # TODO(VPP-1186): move the logic to JNI generators
371         if isinstance(field_type, (Class, Union)):
372             return _generate_c2j_object_swap(msg_java_name, field, object_ref_name, struct_ref_name)
373         elif isinstance(field_type, Enum):
374             return _generate_c2j_enum_swap(msg_java_name, field, object_ref_name, struct_ref_name)
375         else:
376             return _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias)
377     else:
378         return _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name)
379
380
381 def _generate_c2j_object_swap(msg_java_name, field, object_ref_name, struct_ref_name):
382     field_type = field.type
383     return _C2J_OBJECT_SWAP_TEMPLATE.substitute(
384         java_name=field.java_name,
385         class_ref_name=msg_java_name,
386         jni_signature=field_type.jni_signature,
387         jni_name=field_type.jni_name,
388         jni_accessor=field_type.jni_accessor,
389         object_ref_name=object_ref_name,
390         struct_ref_name=struct_ref_name,
391         net_to_host_function=field_type.net_to_host_function,
392         c_name=field.name)
393
394 _C2J_OBJECT_SWAP_TEMPLATE = Template("""
395     jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
396     jclass ${java_name}Class = (*env)->FindClass(env, "${jni_name}");
397     jmethodID ${java_name}Constructor = (*env)->GetMethodID(env, ${java_name}Class, "<init>", "()V");
398     jobject ${java_name} = (*env)->NewObject(env, ${java_name}Class,  ${java_name}Constructor);
399     ${net_to_host_function}(env, &(${struct_ref_name}->${c_name}), ${java_name});
400     (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${java_name});
401     (*env)->DeleteLocalRef(env, ${java_name});
402 """)
403
404
405 def _generate_c2j_enum_swap(msg_java_name, field, object_ref_name, struct_ref_name):
406     field_type = field.type
407     return _C2J_ENUM_SWAP_TEMPLATE.substitute(
408         java_name=field.java_name,
409         class_ref_name=msg_java_name,
410         jni_signature=field_type.jni_signature,
411         jni_signature_enum_value=field_type.value.type.jni_signature,
412         jni_name=field_type.jni_name,
413         jni_accessor=field_type.jni_accessor,
414         object_ref_name=object_ref_name,
415         struct_ref_name=struct_ref_name,
416         net_to_host_function=field_type.net_to_host_function,
417         c_name=field.name)
418
419 _C2J_ENUM_SWAP_TEMPLATE = Template("""
420     jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
421     jclass ${java_name}Class = (*env)->FindClass(env, "${jni_name}");
422     jmethodID ${java_name}Constructor = (*env)->GetStaticMethodID(env, ${java_name}Class, "forValue", "(${jni_signature_enum_value})${jni_signature}");
423     jobject ${java_name} = (*env)->CallStaticObjectMethod(env, ${java_name}Class, ${java_name}Constructor, ${net_to_host_function}(${struct_ref_name}->${c_name}));
424     (*env)->SetObjectField(env, ${object_ref_name}, ${java_name}FieldId, ${java_name});
425     (*env)->DeleteLocalRef(env, ${java_name});
426 """)
427
428
429 def _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
430     field_type = field.type
431     if not is_alias:
432         if field_type.name == "string":
433             template = _C2J_STRING_TYPE_SWAP_TEMPLATE
434         else:
435             template = _C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE
436     else:
437         template = _C2J_ALIAS_PRIMITIVE_TYPE_SWAP_TEMPLATE
438     return template.substitute(
439         java_name=field.java_name,
440         class_ref_name=msg_java_name,
441         jni_signature=field_type.jni_signature,
442         jni_accessor=field_type.jni_accessor,
443         object_ref_name=object_ref_name,
444         net_to_host_function=field_type.net_to_host_function,
445         struct_ref_name=struct_ref_name,
446         c_name=field.name
447     )
448
449 _C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE = Template("""
450     jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
451     (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(${struct_ref_name}->${c_name}));
452 """)
453
454
455 _C2J_STRING_TYPE_SWAP_TEMPLATE = Template("""
456     jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
457     (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(env, (const vl_api_string_t *) &${struct_ref_name}->${c_name}));
458 """)
459
460
461 _C2J_ALIAS_PRIMITIVE_TYPE_SWAP_TEMPLATE = Template("""
462     jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
463     (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(*${struct_ref_name}));
464 """)
465
466
467 def _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name):
468     field_type = field.type
469     return _C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE.substitute(
470         java_name=field.java_name,
471         class_ref_name=msg_java_name,
472         jni_signature=field_type.jni_signature,
473         jni_accessor=field_type.jni_accessor,
474         object_ref_name=object_ref_name,
475         struct_ref_name=struct_ref_name,
476         c_name=field.name
477     )
478
479 _C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE = Template("""
480     jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
481     (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${struct_ref_name}->${c_name});
482 """)