Interface Generator: Initialize static maps with initializer lists
[profile/ivi/smartdevicelink.git] / SDL_Core / tools / InterfaceGenerator / generator / generators / SmartFactoryBase.py
1 """SmartFactory code generator base.
2
3 Base of code generator for SmartFactory that provides SmartSchema object in
4 accordance with given internal model.
5
6 """
7 # pylint: disable=W0402
8 # pylint: disable=C0302
9 import codecs
10 import collections
11 import os
12 import string
13 import uuid
14
15 from generator import Model
16
17
18 class GenerateError(Exception):
19
20     """Generate error.
21
22     This exception is raised when SmartFactory generator is unable to create
23     output from given model.
24
25     """
26
27     pass
28
29
30 class CodeGenerator(object):
31
32     """Base SmartFactory generator.
33
34     This class provides service which allows to generate pair of *.h and
35     *.cc files by given interface model.
36
37     """
38
39     def __init__(self):
40         """Construct new object."""
41
42         self._generated_structs = []
43         self._structs_add_code = u""
44
45     def generate(self, interface, filename, namespace, destination_dir):
46         """Generate SmartFactory source files.
47
48         Generates source code files at destination directory in
49         accordance with given model in specified namespace.
50
51         Keyword arguments:
52         interface -- model of the interface to generate source code for.
53         filename -- name of initial XML file.
54         namespace -- name of destination namespace.
55         destination_dir -- directory to create source files.
56
57         """
58
59         namespace = unicode(namespace)
60
61         if interface is None:
62             raise GenerateError("Given interface is None.")
63
64         self._generated_structs = []
65         self._structs_add_code = ""
66
67         if "messageType" in interface.enums:
68             interface.enums["messageType"] = self._preprocess_message_type(
69                 interface.enums["messageType"])
70
71         if not os.path.exists(destination_dir):
72             os.makedirs(destination_dir)
73
74         namespace_open = u""
75         namespace_close = u""
76
77         if namespace:
78             parts = namespace.split(u"::")
79             for part in parts:
80                 namespace_open = u"".join(
81                     [namespace_open,
82                      self._namespace_open_template.substitute(name=part)])
83                 namespace_close = u"".join(
84                     [namespace_close,
85                      "}} // {0}\n".format(part)])
86
87         class_name = unicode(os.path.splitext(filename)[0])
88         guard = u"__CSMARTFACTORY_{0}_{1}_H__".format(
89             class_name.upper(),
90             unicode(uuid.uuid1().hex.capitalize()))
91         header_file_name = u"".join("{0}.h".format(class_name))
92
93         with codecs.open(os.path.join(destination_dir, header_file_name),
94                          encoding="utf-8",
95                          mode="w") as f_h:
96             f_h.write(self._h_file_tempalte.substitute(
97                 class_name=class_name,
98                 guard=guard,
99                 namespace_open=namespace_open,
100                 enums_content=self._gen_enums(
101                     interface.enums.values(),
102                     interface.structs.values()),
103                 namespace_close=namespace_close))
104
105         self._gen_struct_schema_items(interface.structs.values())
106
107         function_id_items = u""
108         if "FunctionID" in interface.enums:
109             function_id = interface.enums["FunctionID"]
110             function_id_items = u"\n".join(
111                 [self._impl_code_loc_decl_enum_insert_template.substitute(
112                     var_name="function_id_items",
113                     enum=function_id.name,
114                     value=x.primary_name)
115                  for x in function_id.elements.values()])
116
117         message_type_items = u""
118         if "messageType" in interface.enums:
119             message_type = interface.enums["messageType"]
120             message_type_items = u"\n".join(
121                 [self._impl_code_loc_decl_enum_insert_template.substitute(
122                     var_name="message_type_items",
123                     enum=message_type.name,
124                     value=x.primary_name)
125                  for x in message_type.elements.values()])
126
127         header_file_name = "".join("{0}_schema.h".format(class_name))
128         guard = u"__CSMARTFACTORY_{0}_{1}_HPP__".format(
129             class_name.upper(),
130             unicode(uuid.uuid1().hex.capitalize()))
131         with codecs.open(os.path.join(destination_dir, header_file_name),
132                          encoding="utf-8",
133                          mode="w") as f_h:
134             f_h.write(self._hpp_schema_file_tempalte.substitute(
135                 class_name=class_name,
136                 guard=guard,
137                 header_file_name=unicode("".join("{0}.h".format(class_name))),
138                 namespace_open=namespace_open,
139                 class_content=self._gen_h_class(
140                     class_name,
141                     interface.params,
142                     interface.functions.values(),
143                     interface.structs.values()),
144                 namespace_close=namespace_close))
145
146         with codecs.open(os.path.join(destination_dir,
147                                       u"".join("{0}_schema.cc".format(class_name))),
148                          encoding="utf-8", mode="w") as f_s:
149             f_s.write(self._cc_file_template.substitute(
150                 header_file_name=unicode(header_file_name),
151                 namespace=namespace,
152                 class_name=class_name,
153                 function_id_items=self._indent_code(function_id_items, 1),
154                 message_type_items=self._indent_code(message_type_items, 1),
155                 struct_schema_items=self._structs_add_code,
156                 pre_function_schemas=self._gen_pre_function_schemas(
157                     interface.functions.values()),
158                 function_schemas=self._gen_function_schemas(
159                     interface.functions.values()),
160                 init_function_impls=self._gen_function_impls(
161                     interface.functions.values(),
162                     namespace,
163                     class_name),
164                 init_structs_impls=self._gen_sturct_impls(
165                     interface.structs.values(),
166                     namespace,
167                     class_name),
168                 enum_string_coversions=self._gen_enum_to_str_converters(
169                     interface.enums.values(),
170                     namespace)))
171
172     def _preprocess_message_type(self, message_type):
173         """Preprocess message_type enum.
174
175         In base class this method is unimplemented and will cause runtime
176         exception. This method must be overridden by the subclasses to
177         return message_type enum after preprocessing.
178
179         Keyword arguments:
180         message_type -- message_type enum to preprocess.
181
182         """
183
184         raise GenerateError("Unexpected call to the unimplemented function.")
185
186     def _gen_enum_to_str_converters(self, enums, namespace):
187         """Generate enum to string converters.
188
189         Generates part of source code with specific enum to string value
190         converting functions.
191
192         Keyword arguments:
193         enums -- list of enums to generate string converting functions.
194         namespace -- namespace to address enums.
195
196         Returns:
197         String value with enum to string converting functions.
198
199         """
200
201         if enums is None:
202             raise GenerateError("Enums is None")
203
204         return u"\n".join([self._enum_to_str_converter_template.substitute(
205             namespace=namespace,
206             enum=x.name,
207             mapping=self._indent_code(self._gen_enum_to_str_mapping(
208                 x, namespace), 2)) for x in enums])
209
210     def _gen_enum_to_str_mapping(self, enum, namespace):
211         """Generate enum to string mapping code.
212
213         Generates part of source code with specific enum to string value
214         mapping.
215
216         Keyword arguments:
217         enums -- enum to generate string mapping.
218         namespace -- namespace to address enum.
219
220         Returns:
221         String value with enum to string mapping source code.
222
223         """
224
225         return u"\n".join([self._enum_to_str_mapping_template.substitute(
226             namespace=namespace,
227             enum_name=enum.name,
228             enum_value=x.primary_name,
229             string=x.name) for x in enum.elements.values()])
230
231     def _gen_h_class(self, class_name, params, functions, structs):
232         """Generate source code of class for header file.
233
234         Generates source code of class that should be used in the
235         header file.
236
237         Keyword arguments:
238         class_name -- name of the class to generate.
239         params -- class parameters.
240         functions -- list of functions to generate methods for.
241         structs -- structures to generate methods for.
242
243         Returns:
244         String with complete *.h file source code.
245
246         """
247
248         return self._class_h_template.substitute(
249             comment=self._gen_class_comment(class_name, params),
250             class_name=class_name,
251             init_function_decls=self._gen_function_decls(functions),
252             init_struct_decls=self._gen_structs_decls(structs))
253
254     def _gen_structs_decls(self, structs):
255         """Generate method prototypes for structs for header file.
256
257         Generates method prototypes for structs that should be used in the
258         header file.
259
260         Keyword arguments:
261         structs -- list of structs to generate methods for.
262
263         Returns:
264         String with structs init methods declarations source code.
265
266         """
267
268         if structs is None:
269             raise GenerateError("Structs is None")
270
271         return u"\n".join([self._indent_code(
272             self._gen_struct_decl(x), 1) for x in structs])
273
274     def _gen_struct_decl(self, struct):
275         """Generate method prototype for struct for header file.
276
277         Generates method prototype for struct that should be used in the
278         header file.
279
280         Keyword arguments:
281         struct -- struct to generate method for.
282
283         Returns:
284         String with struct inin method declaration source code.
285
286         """
287
288         return self._struct_decl_template.substitute(
289             comment=self._gen_comment(struct),
290             struct_name=struct.name)
291
292     def _gen_function_decls(self, functions):
293         """Generate method prototypes for functions for header file.
294
295         Generates method prototypes for functions that should be used in the
296         header file.
297
298         Keyword arguments:
299         functions -- list of functions to generate methods for.
300
301         Returns:
302         String with function init methods declarations source code.
303
304         """
305
306         if functions is None:
307             raise GenerateError("Functions is None")
308
309         return u"\n".join([self._indent_code(
310             self._gen_function_decl(x), 1) for x in functions])
311
312     def _gen_function_decl(self, function):
313         """Generate method prototype for function for header file.
314
315         Generates method prototype for function that should be used in the
316         header file.
317
318         Keyword arguments:
319         function -- function to generate method for.
320
321         Returns:
322         String with function declaration source code.
323
324         """
325
326         return self._function_decl_template.substitute(
327             comment=self._gen_comment(function),
328             function_id=function.function_id.primary_name,
329             message_type=function.message_type.primary_name)
330
331     def _gen_struct_schema_items(self, structs):
332         """Generate struct schema items initialization code for source file.
333
334         Generates struct schema items initialization code that should be used
335         in the source file.
336
337         Keyword arguments:
338         structs -- list of structs to generate code for.
339
340         Returns:
341         String with struct schema items initialization source code.
342
343         """
344
345         if structs is None:
346             raise GenerateError("Structs is None")
347
348         for struct in structs:
349             self._process_struct(struct)
350
351     def _process_struct(self, struct):
352         """Process struct recursively to provide correct initialization.
353
354         This method create source code for cc file that guarantees that
355         structures are initialized in right order (to resolve all
356         dependencies).
357
358         Keyword arguments:
359         struct -- struct to process.
360
361         """
362
363         if struct.name in self._generated_structs:
364             return
365
366         for member in struct.members.values():
367             self._process_struct_member(member)
368
369         self._structs_add_code = u"\n".join(
370             [self._structs_add_code, self._indent_code(
371                 self._gen_struct_schema_item(struct), 1)])
372         self._generated_structs.append(struct.name)
373
374     def _process_struct_member(self, member):
375         """Process struct member recursively to provide correct initialization.
376
377         This method ensures that nested structs (if any) are generated.
378
379         Keyword arguments:
380         member -- struct member to process.
381
382         """
383
384         if type(member.param_type) is Model.Struct:
385             self._ensure_struct_generated(member.param_type)
386
387     def _ensure_struct_generated(self, struct):
388         """Ensure that struct is already generated.
389
390         If struct is already created this method returns otherwise it
391         runs generation of struct to resolve dependency.
392
393         Keyword arguments:
394         struct -- struct to ensure existence.
395
396         """
397
398         if struct.name in self._generated_structs:
399             return
400
401         self._process_struct(struct)
402
403     def _gen_struct_schema_item(self, struct):
404         """Generate struct schema item initialization code for source file.
405
406         Generates struct schema item initialization code that should be used
407         in the source file.
408
409         Keyword arguments:
410         struct -- struct to generate code for.
411
412         Returns:
413         String with struct schema item initialization source code.
414
415         """
416
417         return self._struct_schema_item_template.substitute(name=struct.name)
418
419     def _gen_pre_function_schemas(self, functions):
420         """Generate specific code that goes before schema initialization.
421
422         In base class this function is unimplemented and it will raise an
423         runtime exception. Subclasses must implement this function in order
424         to provide format-specific code that goes before schema initialization.
425
426         Keyword arguments:
427         functions -- list of functions to generate code for.
428
429         """
430
431         raise GenerateError("Unexpected call to the unimplemented function.")
432
433     def _gen_function_schemas(self, functions):
434         """Generate functions initialization code for source file.
435
436         Generates functions schema initialization code that should be used
437         in the source file.
438
439         Keyword arguments:
440         functions -- list of functions to generate code for.
441
442         Returns:
443         String with functions schema initialization source code.
444
445         """
446
447         if functions is None:
448             raise GenerateError("Functions is None")
449
450         return u"".join([self._indent_code(
451             self._gen_function_schema(x), 1)
452             for x in functions])
453
454     def _gen_function_schema(self, function):
455         """Generate function initialization code for source file.
456
457         Generates function schema initialization code that should be used
458         in the source file.
459
460         Keyword arguments:
461         function -- function to generate method for.
462
463         Returns:
464         String with function schema initialization source code.
465
466         """
467
468         return self._function_schema_template.substitute(
469             function_id=function.function_id.primary_name,
470             message_type=function.message_type.primary_name)
471
472     def _gen_sturct_impls(self, structs, namespace, class_name):
473         """Generate structs implementation for source file.
474
475         Generates implementation code of methods that provide schema items for
476         structs. This code should be used in the source file.
477
478         Keyword arguments:
479         structs -- list of structs to generate methods for.
480         namespace -- name of destination namespace.
481         class_name -- name of the parent class.
482
483         Returns:
484         String with structs implementation source code.
485
486         """
487
488         if structs is None:
489             raise GenerateError("Structs is None")
490
491         return u"\n".join([self._gen_struct_impl(
492             x, namespace, class_name) for x in structs])
493
494     def _gen_struct_impl(self, struct, namespace, class_name):
495         """Generate struct implementation for source file.
496
497         Generates implementation code of method that provide schema item for
498         struct. This code should be used in the source file.
499
500         Keyword arguments:
501         struct -- struct to generate method for.
502         namespace -- name of destination namespace.
503         class_name -- name of the parent class.
504
505         Returns:
506         String with structs implementation source code.
507
508         """
509
510         processed_enums = []
511         return self._struct_impl_template.substitute(
512             namespace=namespace,
513             class_name=class_name,
514             struct_name=struct.name,
515             code=self._indent_code(
516                 self._struct_impl_code_tempate.substitute(
517                     schema_loc_decl=self._gen_schema_loc_decls(
518                         struct.members.values(), processed_enums),
519                     schema_items_decl=self._gen_schema_items_decls(
520                         struct.members.values()),
521                     schema_item_fill=self._gen_schema_items_fill(
522                         struct.members.values())),
523                 1))
524
525     def _gen_schema_loc_decls(self, members, processed_enums):
526         """Generate local declarations of variables for schema.
527
528         This method generates full set of required variables for
529         enums and enum subsets.
530
531         Keyword arguments:
532         members -- struct/function members/params.
533         processed_enums -- list of already processed enums.
534
535         Returns:
536         String with local declarations source code.
537
538         """
539
540         result = u""
541         for member in members:
542             if type(member.param_type) is Model.Enum and \
543                member.param_type.name not in processed_enums:
544                 local_var = self._gen_schema_loc_emum_var_name(
545                     member.param_type)
546                 result = u"\n".join(
547                     [u"".join(
548                         [result, self._impl_code_loc_decl_enum_template.
549                             substitute(
550                                 type=member.param_type.name,
551                                 var_name=local_var)]),
552                         u"\n".join(
553                             [self._impl_code_loc_decl_enum_insert_template.
554                                 substitute(
555                                     var_name=local_var,
556                                     enum=member.param_type.name,
557                                     value=x.primary_name)
558                              for x in member.param_type.elements.values()])])
559                 processed_enums.append(member.param_type.name)
560                 result = u"".join([result, u"\n\n"]) if result else u""
561             elif type(member.param_type) is Model.EnumSubset:
562                 local_var = self._gen_schema_loc_emum_s_var_name(member.name)
563                 result = u"\n".join(
564                     [u"".join(
565                         [result, self._impl_code_loc_decl_enum_template.
566                             substitute(
567                                 type=member.param_type.enum.name,
568                                 var_name=local_var)]),
569                         u"\n".join(
570                             [self._impl_code_loc_decl_enum_insert_template.
571                                 substitute(
572                                     var_name=local_var,
573                                     enum=member.param_type.enum.name,
574                                     value=x.primary_name)
575                              for x in member.param_type.
576                              allowed_elements.values()])])
577                 result = u"".join([result, u"\n\n"]) if result else u""
578             elif type(member.param_type) is Model.Array:
579                 result = u"".join(
580                     [result, self._gen_schema_loc_decls(
581                         [Model.Param(name=member.param_type.element_type.name
582                          if type(member.param_type.element_type) is
583                          Model.EnumSubset else "",
584                             param_type=member.param_type.element_type)],
585                         processed_enums)])
586
587         return result
588
589     def _gen_schema_items_decls(self, members):
590         """Generate schema items declarations.
591
592         Generates declaration and initialization of schema items
593         which is uses as struct members/function parameters.
594
595         Keyword arguments:
596         members -- list of struct members/function parameters.
597
598         Returns:
599         String with schema items declaration source code.
600
601         """
602
603         result = u"\n\n".join(
604             [self._gen_schema_item_decl(x) for x in members])
605
606         return u"".join([result, u"\n\n"]) if result else u""
607
608     def _gen_schema_item_decl(self, member):
609         """Generate schema item declaration.
610
611         Generates declaration and initialization of schema item
612         which is uses as struct member/function parameter.
613
614         Keyword arguments:
615         member -- struct member/function parameter.
616
617         Returns:
618         String with schema item declaration source code.
619
620         """
621
622         return self._impl_code_item_decl_temlate.substitute(
623             comment=self._gen_comment(member, False),
624             var_name=self._gen_schema_item_var_name(member),
625             item_decl=self._gen_schema_item_decl_code(
626                 member.param_type,
627                 member.name,
628                 member.default_value if type(member)
629                 is Model.FunctionParam else None))
630
631     def _gen_schema_item_decl_code(self, param, member_name, default_value):
632
633         """Generate schema item initialization code.
634
635         Generates type-specific code that initializes schema item
636
637         Keyword arguments:
638         param -- value of parameter type.
639         mamber_name -- name of struct member/function parameter.
640         default_value -- default value (used only for function parameters).
641
642         Returns:
643         String with schema item initialization source code.
644
645         """
646
647         code = u""
648         if type(param) is Model.Boolean:
649             code = self._impl_code_bool_item_template.substitute(
650                 params=self._gen_schema_item_param_values(
651                     [[u"bool", None if default_value is None
652                       else u"true" if default_value is True else u"false"]]))
653         elif type(param) is Model.Integer:
654             code = self._impl_code_integer_item_template.substitute(
655                 type=u"int",
656                 params=self._gen_schema_item_param_values(
657                     [[u"int", param.min_value],
658                      [u"int", param.max_value],
659                      [u"int", default_value]]))
660         elif type(param) is Model.Double:
661             code = self._impl_code_integer_item_template.substitute(
662                 type=u"double",
663                 params=self._gen_schema_item_param_values(
664                     [[u"double", param.min_value],
665                      [u"double", param.max_value],
666                      [u"double", default_value]]))
667         elif type(param) is Model.String:
668             code = self._impl_code_string_item_template.substitute(
669                 params=self._gen_schema_item_param_values(
670                     [[u"size_t", param.min_length],
671                      [u"size_t", param.max_length],
672                      [u"std::string", u"".join(
673                      [u'"', default_value, u'"']) if default_value
674                          is not None else u""]]))
675         elif type(param) is Model.Array:
676             code = self._impl_code_array_item_template.substitute(
677                 params=u"".join(
678                     [u"".join(
679                         [self._gen_schema_item_decl_code(
680                             param.element_type,
681                             param.element_type.name if type(param.element_type)
682                             is Model.EnumSubset else u"",
683                             None),
684                             u", "]),
685                         self._gen_schema_item_param_values(
686                             [[u"size_t", param.min_size],
687                              [u"size_t", param.max_size]])]))
688         elif type(param) is Model.Struct:
689             code = self._impl_code_struct_item_template.substitute(
690                 name=param.name)
691         elif type(param) is Model.Enum:
692             code = self._impl_code_enum_item_template.substitute(
693                 type=param.name,
694                 params=u"".join(
695                     [self._gen_schema_loc_emum_var_name(param),
696                      u", ",
697                      self._gen_schema_item_param_values(
698                          [[u"".join([param.name, u"::eType"]),
699                           u"".join([param.name, u"::",
700                                     default_value.primary_name]) if
701                            default_value is not None else None]])]))
702         elif type(param) is Model.EnumSubset:
703             code = self._impl_code_enum_item_template.substitute(
704                 type=param.enum.name,
705                 params=u"".join(
706                     [self._gen_schema_loc_emum_s_var_name(member_name),
707                      u", ",
708                      self._gen_schema_item_param_values(
709                          [[u"".join([param.enum.name, u"::eType"]),
710                           default_value.primary_name if default_value
711                           is not None else None]])]))
712         else:
713             raise GenerateError("Unexpected type of parameter: " +
714                                 str(type(param)))
715         return code
716
717     def _gen_schema_item_param_values(self, params):
718         """Generate values of schema item initialization parameters.
719
720         Generates part of code which is used as schema item initialization
721         parameters.
722
723         Keyword arguments:
724         params -- list of tuples which maps parameter type to parameter value.
725
726         Returns:
727         String with schema item initialization parameters source code.
728
729         """
730
731         result = u""
732         for param in params:
733             value = self._impl_code_item_param_value_template.substitute(
734                 type=param[0],
735                 value=str(param[1] if param[1] is not None else ""))
736             result = u"".join([result, u"".join(
737                 [u", ", value])
738                 if result else value])
739
740         return result
741
742     def _gen_schema_items_fill(self, members):
743         """Generate schema items fill code.
744
745         Generates source code that fills new schema with items.
746
747         Keyword arguments:
748         members -- list of struct members/function parameters to process.
749
750         Returns:
751         String with function schema items fill code.
752
753         """
754
755         result = u"\n".join(
756             [self._gen_schema_item_fill(x) for x in members])
757
758         return u"".join([result, u"\n\n"]) if result else u""
759
760     def _gen_schema_params_fill(self, message_type_name):
761         """Generate schema params fill code.
762
763         In the base class this method is not implemented (raises exception).
764         This method must be implemented by the subclasses to specify format
765         specific PARAMS for the function.
766
767         Keyword arguments:
768         message_type_name -- Name of the messageType enum element.
769
770         Returns:
771         String with function schema params fill code.
772
773         """
774
775         raise GenerateError("Unexpected call to the unimplemented function.")
776
777     def _gen_schema_item_fill(self, member):
778         """Generate schema item fill code.
779
780         Generates source code that fills new schema with item.
781
782         Keyword arguments:
783         member -- struct member/function parameter to process.
784
785         Returns:
786         String with schema item fill code.
787
788         """
789
790         return self._impl_code_item_fill_template.substitute(
791             name=member.name,
792             var_name=self._gen_schema_item_var_name(member),
793             is_mandatory=u"true" if member.is_mandatory is True else u"false")
794
795     @staticmethod
796     def _gen_schema_item_var_name(member):
797         """Generate schema item variable name.
798
799         Generates variable name for local declarations.
800
801         Keyword arguments:
802         member -- struct member/function parameter to process.
803
804         Returns:
805         String with schema item variable name.
806
807         """
808
809         return u"".join([member.name, u"_SchemaItem"])
810
811     @staticmethod
812     def _gen_schema_loc_emum_var_name(param_type):
813         """Generate name of enum local variable.
814
815         Generates name of local variable that defines allowed enum elements.
816
817         Keyword arguments:
818         param_type -- parameter type object.
819
820         Returns:
821         String with name of enum local variable.
822
823         """
824
825         return u"".join([param_type.name, u"_all_enum_values"])
826
827     @staticmethod
828     def _gen_schema_loc_emum_s_var_name(member_name):
829         """Generate name of enum subset local variable.
830
831         Generates name of local variable that defines allowed enum
832         subset elements.
833
834         Keyword arguments:
835         param_type -- parameter type object.
836
837         Returns:
838         String with name of enum subset local variable.
839
840         """
841
842         return u"".join([member_name, "_allowed_enum_subset_values"])
843
844     def _gen_function_impls(self, functions, namespace, class_name):
845         """Generate functions implementation for source file.
846
847         Generates implementation code of methods that provide schema for
848         functions. This code should be used in the source file.
849
850         Keyword arguments:
851         functions -- list of functions to generate methods for.
852         namespace -- name of destination namespace.
853         class_name -- name of the parent class.
854
855         Returns:
856         String with functions implementation source code.
857
858         """
859
860         if functions is None:
861             raise GenerateError("Functions is None")
862
863         return u"\n".join([self._gen_function_impl(
864             x, namespace, class_name) for x in functions])
865
866     def _gen_function_impl(self, function, namespace, class_name):
867         """Generate function implementation for source file.
868
869         Generates implementation code of method that provides schema for
870         function. This code should be used in the source file.
871
872         Keyword arguments:
873         function -- function to generate method for.
874         namespace -- name of destination namespace.
875         class_name -- name of the parent class.
876
877         Returns:
878         String with function implementation source code.
879
880         """
881
882         processed_enums = []
883         return self._function_impl_template.substitute(
884             namespace=namespace,
885             class_name=class_name,
886             function_id=function.function_id.primary_name,
887             message_type=function.message_type.primary_name,
888             code=self._indent_code(
889                 self._function_impl_code_tempate.substitute(
890                     schema_loc_decl=self._gen_schema_loc_decls(
891                         function.params.values(), processed_enums),
892                     schema_items_decl=self._gen_schema_items_decls(
893                         function.params.values()),
894                     schema_item_fill=self._gen_schema_items_fill(
895                         function.params.values()),
896                     schema_params_fill=self._gen_schema_params_fill(
897                         function.message_type.name)),
898                 1))
899
900     def _gen_enums(self, enums, structs):
901         """Generate enums for header file.
902
903         Generates declaration of enumerations for the header file.
904
905         Keyword arguments:
906         enums -- list of enums to generate.
907
908         Returns:
909         String with enums declaration source code.
910
911         """
912
913         if enums is None:
914             raise GenerateError("Enums is None")
915
916         if structs is None:
917             raise GenerateError("Structs is None")
918
919         if structs:
920             struct_id_enum_elements = collections.OrderedDict()
921             for struct in structs:
922                 struct_id_enum_elements[struct.name] = Model.EnumElement(
923                     name=struct.name)
924             return u"\n".join(
925                 [self._gen_enum(
926                     Model.Enum(name="StructIdentifiers",
927                                elements=struct_id_enum_elements)),
928                  u"\n".join([self._gen_enum(x) for x in enums])])
929
930         return u"\n".join([self._gen_enum(x) for x in enums])
931
932     def _gen_enum(self, enum):
933         """Generate enum for header file.
934
935         Generates declaration of enumeration for the header file.
936
937         Keyword arguments:
938         enum -- enum to generate.
939
940         Returns:
941         String with enum declaration source code.
942
943         """
944
945         enum_elements = enum.elements.values()
946         enum_elements.insert(0, Model.EnumElement(
947             name=u"INVALID_ENUM",
948             description=None,
949             design_description=None,
950             issues=None,
951             todos=None,
952             platform=None,
953             internal_name=None,
954             value=u"-1"))
955         return self._enum_template.substitute(
956             comment=self._gen_comment(enum),
957             name=enum.name,
958             enum_items=self._indent_code(self._gen_enum_elements(
959                 enum_elements), 1))
960
961     def _gen_enum_elements(self, enum_elements):
962         """Generate enum elements for header file.
963
964         Generates declaration of enumeration elements for the header file.
965
966         Keyword arguments:
967         enum_elements -- list of enum elements to generate.
968
969         Returns:
970         String with enum elements declaration source code.
971
972         """
973
974         return u",\n\n".join([self._gen_enum_element(x)
975                               for x in enum_elements])
976
977     def _gen_enum_element(self, enum_element):
978         """Generate enum element for header file.
979
980         Generates declaration of enumeration element for the header file.
981
982         Keyword arguments:
983         enum_element -- enum element to generate.
984
985         Returns:
986         String with enum element declaration source code.
987
988         """
989
990         if enum_element.value is not None:
991             return self._enum_element_with_value_template.substitute(
992                 comment=self._gen_comment(enum_element),
993                 name=enum_element.primary_name,
994                 value=enum_element.value)
995         else:
996             return self._enum_element_with_no_value_template.substitute(
997                 comment=self._gen_comment(enum_element),
998                 name=enum_element.primary_name)
999
1000     def _gen_class_comment(self, class_name, params):
1001         """Generate doxygen comment to the class for header file.
1002
1003         Generates doxygen comment for the class that should be used in
1004         the header file.
1005
1006         Keyword arguments:
1007         class_name -- name of the class.
1008         params -- class parameters.
1009
1010         Returns:
1011         String with generated doxygen class comment.
1012
1013         """
1014
1015         return self._class_comment_template.substitute(
1016             class_name=class_name,
1017             class_params=u"".join(
1018                 [u" *     {0} - {1}\n".format(x[0],
1019                  x[1]) for x in params.items()])
1020             if params else u" *    none\n")
1021
1022     def _gen_comment(self, interface_item_base, use_doxygen=True):
1023         """Generate doxygen comment for iterface_item_base for header file.
1024
1025         Generates doxygen comment for any iterface_item_base for the header
1026         file.
1027
1028         Keyword arguments:
1029         interface_item_base -- object to generate doxygen comment for.
1030         use_doxygen -- Flag that indicates does function uses doxygen or not.
1031
1032         Returns:
1033         String with generated doxygen comment.
1034
1035         """
1036
1037         brief_type_title = None
1038         interface_item_base_classname = interface_item_base.__class__.__name__
1039         if interface_item_base_classname in self._model_types_briefs:
1040             brief_type_title = \
1041                 self._model_types_briefs[interface_item_base_classname]
1042         else:
1043             raise GenerateError("Unable to create comment for unknown type " +
1044                                 interface_item_base_classname)
1045
1046         name = interface_item_base.primary_name if \
1047             type(interface_item_base) is Model.EnumElement else \
1048             interface_item_base.name
1049         brief_description = (u" * @brief {0}{1}.\n" if use_doxygen is
1050                              True else u"// {0}{1}.\n").format(
1051                                  brief_type_title,
1052                                  name)
1053
1054         description = u"".join([(u" * {0}\n" if use_doxygen
1055                                 is True else u"// {0}\n").format(x)
1056                                 for x in self._normalize_multiline_comments(
1057                                     interface_item_base.description)])
1058         if description is not u"":
1059             description = u"".join([u" *\n" if use_doxygen
1060                                     is True else u"//\n", description])
1061
1062         design_description = u"".join([(u" * {0}\n" if use_doxygen is
1063                                        True else u"// {0}\n").format(x)
1064                                        for x in
1065                                        self._normalize_multiline_comments(
1066                                            interface_item_base.
1067                                            design_description)])
1068         if design_description is not u"":
1069             design_description = u"".join([u" *\n" if use_doxygen is
1070                                            True else "//\n",
1071                                            design_description])
1072
1073         issues = u"".join([(u" * @note {0}\n" if use_doxygen is
1074                            True else u"// Note: {0}\n").format(x)
1075                            for x in self._normalize_multiline_comments(
1076                                [x.value for x in interface_item_base.issues])])
1077         if issues is not u"":
1078             issues = u"".join([u" *\n" if use_doxygen is
1079                               True else u"//\n", issues])
1080
1081         todos = u"".join([(u" * @todo {0}\n" if use_doxygen is
1082                           True else u"// ToDo: {0}\n").format(x)
1083                           for x in self._normalize_multiline_comments(
1084                               interface_item_base.todos)])
1085         if todos is not u"":
1086             todos = u"".join([u" *\n" if use_doxygen is
1087                               True else u"//\n", todos])
1088
1089         returns = u""
1090         if type(interface_item_base) is Model.Function:
1091             returns = u"".join([u" *\n", self._function_return_comment])
1092
1093         template = self._comment_doxygen_template if use_doxygen is \
1094             True else self._comment_cc_template
1095
1096         return template.substitute(
1097             brief_description=brief_description,
1098             description=description,
1099             design_description=design_description,
1100             issues=issues,
1101             todos=todos,
1102             returns=returns)
1103
1104     def _indent_code(self, code, indent_level):
1105         """Indent given source code.
1106
1107         Indents given source code right by given indentation level.
1108
1109         Keyword arguments:
1110         code -- given source code.
1111         indent_level -- desired indentation level.
1112
1113         Returns:
1114         String with processed code.
1115
1116         """
1117
1118         code_lines = code.split("\n")
1119         return u"".join(
1120             [u"{0}{1}\n".format(
1121                 self._indent_template * indent_level,
1122                 x) if x is not u"" else u"\n" for x in code_lines])
1123
1124     @staticmethod
1125     def _normalize_multiline_comments(initial_strings):
1126         """Normalize multiline comments.
1127
1128         Makes multiline comment clean of any line breaks creating additional
1129         strings for the comment.
1130
1131         Keyword arguments:
1132         initial_strings -- initial list of strings to process.
1133
1134         Returns:
1135         New list of the strings (with contains no strings with line breaks).
1136
1137         """
1138
1139         result = []
1140         for initial_string in initial_strings:
1141             result = result + initial_string.splitlines()
1142         return result
1143
1144     _model_types_briefs = dict(
1145         {u"EnumElement": u"",
1146          u"Enum": u"Enumeration ",
1147          u"Function": u"Method that generates schema for function ",
1148          u"Struct": u"Method that generates schema item for structure ",
1149          u"Param": u"Struct member ",
1150          u"FunctionParam": u"Function parameter "})
1151
1152     _h_file_tempalte = string.Template(
1153         u'''/**\n'''
1154         u''' * @file ${class_name}.h\n'''
1155         u''' * @brief Generated class ${class_name} header file.\n'''
1156         u''' *\n'''
1157         u''' * This class is a part of SmartObjects solution. It provides\n'''
1158         u''' * factory functionallity which allows client to use '''
1159         u'''SmartSchemas\n'''
1160         u''' * in accordance with definitions from ${class_name}.xml file\n'''
1161         u''' */\n'''
1162         u'''// Copyright (c) 2013, Ford Motor Company\n'''
1163         u'''// All rights reserved.\n'''
1164         u'''//\n'''
1165         u'''// Redistribution and use in source and binary forms, '''
1166         u'''with or without\n'''
1167         u'''// modification, are permitted provided that the following '''
1168         u'''conditions are met:\n'''
1169         u'''//\n'''
1170         u'''// Redistributions of source code must retain the above '''
1171         u'''copyright notice, this\n'''
1172         u'''// list of conditions and the following disclaimer.\n'''
1173         u'''//\n'''
1174         u'''// Redistributions in binary form must reproduce '''
1175         u'''the above copyright notice,\n'''
1176         u'''// this list of conditions and the following\n'''
1177         u'''// disclaimer in the documentation and/or other materials '''
1178         u'''provided with the\n'''
1179         u'''// distribution.\n'''
1180         u'''//\n'''
1181         u'''// Neither the name of the Ford Motor Company nor the names '''
1182         u'''of its contributors\n'''
1183         u'''// may be used to endorse or promote products derived '''
1184         u'''from this software\n'''
1185         u'''// without specific prior written permission.\n'''
1186         u'''//\n'''
1187         u'''// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND '''
1188         u'''CONTRIBUTORS "AS IS"\n'''
1189         u'''// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT '''
1190         u'''LIMITED TO, THE\n'''
1191         u'''// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR '''
1192         u'''A PARTICULAR PURPOSE\n'''
1193         u'''// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER '''
1194         u'''OR CONTRIBUTORS BE\n'''
1195         u'''// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, '''
1196         u'''EXEMPLARY, OR\n'''
1197         u'''// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, '''
1198         u'''PROCUREMENT OF\n'''
1199         u'''// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; '''
1200         u'''OR BUSINESS\n'''
1201         u'''// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, '''
1202         u'''WHETHER IN\n'''
1203         u'''// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE '''
1204         u'''OR OTHERWISE)\n'''
1205         u'''// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF '''
1206         u'''ADVISED OF THE\n'''
1207         u'''// POSSIBILITY OF SUCH DAMAGE.\n\n'''
1208         u'''#ifndef $guard\n'''
1209         u'''#define $guard\n'''
1210         u'''\n'''
1211         u'''$namespace_open'''
1212         u'''$enums_content'''
1213         u'''$namespace_close'''
1214         u'''#endif //$guard\n'''
1215         u'''\n\n''')
1216
1217     _hpp_schema_file_tempalte = string.Template(
1218         u'''/**\n'''
1219         u''' * @file ${class_name}.hpp\n'''
1220         u''' * @brief Generated class ${class_name} header file.\n'''
1221         u''' *\n'''
1222         u''' * This class is a part of SmartObjects solution. It provides\n'''
1223         u''' * factory functionallity which allows client to use '''
1224         u'''SmartSchemas\n'''
1225         u''' * in accordance with definitions from ${class_name}.xml file\n'''
1226         u''' */\n'''
1227         u'''// Copyright (c) 2013, Ford Motor Company\n'''
1228         u'''// All rights reserved.\n'''
1229         u'''//\n'''
1230         u'''// Redistribution and use in source and binary forms, '''
1231         u'''with or without\n'''
1232         u'''// modification, are permitted provided that the following '''
1233         u'''conditions are met:\n'''
1234         u'''//\n'''
1235         u'''// Redistributions of source code must retain the above '''
1236         u'''copyright notice, this\n'''
1237         u'''// list of conditions and the following disclaimer.\n'''
1238         u'''//\n'''
1239         u'''// Redistributions in binary form must reproduce '''
1240         u'''the above copyright notice,\n'''
1241         u'''// this list of conditions and the following\n'''
1242         u'''// disclaimer in the documentation and/or other materials '''
1243         u'''provided with the\n'''
1244         u'''// distribution.\n'''
1245         u'''//\n'''
1246         u'''// Neither the name of the Ford Motor Company nor the names '''
1247         u'''of its contributors\n'''
1248         u'''// may be used to endorse or promote products derived '''
1249         u'''from this software\n'''
1250         u'''// without specific prior written permission.\n'''
1251         u'''//\n'''
1252         u'''// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND '''
1253         u'''CONTRIBUTORS "AS IS"\n'''
1254         u'''// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT '''
1255         u'''LIMITED TO, THE\n'''
1256         u'''// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR '''
1257         u'''A PARTICULAR PURPOSE\n'''
1258         u'''// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER '''
1259         u'''OR CONTRIBUTORS BE\n'''
1260         u'''// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, '''
1261         u'''EXEMPLARY, OR\n'''
1262         u'''// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, '''
1263         u'''PROCUREMENT OF\n'''
1264         u'''// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; '''
1265         u'''OR BUSINESS\n'''
1266         u'''// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, '''
1267         u'''WHETHER IN\n'''
1268         u'''// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE '''
1269         u'''OR OTHERWISE)\n'''
1270         u'''// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF '''
1271         u'''ADVISED OF THE\n'''
1272         u'''// POSSIBILITY OF SUCH DAMAGE.\n\n'''
1273         u'''#ifndef $guard\n'''
1274         u'''#define $guard\n'''
1275         u'''\n'''
1276         u'''#include "formatters/CSmartFactory.hpp"\n'''
1277         u'''#include "smart_objects/smart_schema.h"\n'''
1278         u'''#include "smart_objects/schema_item.h"\n'''
1279         u'''#include "utils/shared_ptr.h"\n'''
1280         u'''#include "$header_file_name"\n'''
1281         u'''\n'''
1282         u'''$namespace_open'''
1283         u'''\n\n'''
1284         u'''$class_content'''
1285         u'''\n\n'''
1286         u'''$namespace_close'''
1287         u'''\n'''
1288         u'''#endif //$guard\n'''
1289         u'''\n''')
1290
1291     _namespace_open_template = string.Template(
1292         u'''namespace $name {\n''')
1293
1294     _cc_file_template = string.Template(
1295         u'''/**\n'''
1296         u''' * @file ${class_name}.cc\n'''
1297         u''' * @brief Generated class ${class_name} source file.\n'''
1298         u''' *\n'''
1299         u''' * This class is a part of SmartObjects solution. It provides\n'''
1300         u''' * factory functionallity which allows client to use '''
1301         u'''SmartSchemas\n'''
1302         u''' * in accordance with definitions from ${class_name}.xml file\n'''
1303         u''' */\n'''
1304         u'''// Copyright (c) 2013, Ford Motor Company\n'''
1305         u'''// All rights reserved.\n'''
1306         u'''//\n'''
1307         u'''// Redistribution and use in source and binary forms, '''
1308         u'''with or without\n'''
1309         u'''// modification, are permitted provided that the following '''
1310         u'''conditions are met:\n'''
1311         u'''//\n'''
1312         u'''// Redistributions of source code must retain the above '''
1313         u'''copyright notice, this\n'''
1314         u'''// list of conditions and the following disclaimer.\n'''
1315         u'''//\n'''
1316         u'''// Redistributions in binary form must reproduce '''
1317         u'''the above copyright notice,\n'''
1318         u'''// this list of conditions and the following\n'''
1319         u'''// disclaimer in the documentation and/or other materials '''
1320         u'''provided with the\n'''
1321         u'''// distribution.\n'''
1322         u'''//\n'''
1323         u'''// Neither the name of the Ford Motor Company nor the names '''
1324         u'''of its contributors\n'''
1325         u'''// may be used to endorse or promote products derived '''
1326         u'''from this software\n'''
1327         u'''// without specific prior written permission.\n'''
1328         u'''//\n'''
1329         u'''// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND '''
1330         u'''CONTRIBUTORS "AS IS"\n'''
1331         u'''// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT '''
1332         u'''LIMITED TO, THE\n'''
1333         u'''// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR '''
1334         u''''A PARTICULAR PURPOSE\n'''
1335         u'''// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER '''
1336         u'''OR CONTRIBUTORS BE\n'''
1337         u'''// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, '''
1338         u'''EXEMPLARY, OR\n'''
1339         u'''// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, '''
1340         u'''PROCUREMENT OF\n'''
1341         u'''// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; '''
1342         u'''OR BUSINESS\n'''
1343         u'''// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, '''
1344         u'''WHETHER IN\n'''
1345         u'''// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE '''
1346         u'''OR OTHERWISE)\n'''
1347         u'''// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF '''
1348         u'''ADVISED OF THE\n'''
1349         u'''// POSSIBILITY OF SUCH DAMAGE.\n\n'''
1350         u'''#include <map>\n'''
1351         u'''#include <set>\n'''
1352         u'''\n'''
1353         u'''#include "$header_file_name"\n'''
1354         u'''#include "smart_objects/always_true_schema_item.h"\n'''
1355         u'''#include "smart_objects/always_false_schema_item.h"\n'''
1356         u'''#include "smart_objects/array_schema_item.h"\n'''
1357         u'''#include "smart_objects/bool_schema_item.h"\n'''
1358         u'''#include "smart_objects/object_schema_item.h"\n'''
1359         u'''#include "smart_objects/string_schema_item.h"\n'''
1360         u'''#include "smart_objects/enum_schema_item.h"\n'''
1361         u'''#include "smart_objects/number_schema_item.h"\n'''
1362         u'''#include "smart_objects/schema_item_parameter.h"\n'''
1363         u'''\n'''
1364         u'''using namespace NsSmartDeviceLink::NsSmartObjects;\n'''
1365         u'''\n'''
1366         u'''$namespace::$class_name::$class_name()\n'''
1367         u''' : NsSmartDeviceLink::NsJSONHandler::CSmartFactory<FunctionID::eType, '''
1368         u'''messageType::eType, StructIdentifiers::eType>() {\n'''
1369         u'''  TStructsSchemaItems struct_schema_items;\n'''
1370         u'''  InitStructSchemes(struct_schema_items);\n'''
1371         u'''\n'''
1372         u'''  std::set<FunctionID::eType> function_id_items;\n'''
1373         u'''${function_id_items}'''
1374         u'''\n'''
1375         u'''  std::set<messageType::eType> message_type_items;\n'''
1376         u'''${message_type_items}'''
1377         u'''\n'''
1378         u'''  InitFunctionSchemes(struct_schema_items, function_id_items, '''
1379         u'''message_type_items);\n'''
1380         u'''}\n'''
1381         u'''\n'''
1382         u'''utils::SharedPtr<ISchemaItem> $namespace::$class_name::'''
1383         u'''ProvideObjectSchemaItemForStruct(\n'''
1384         u'''    const TStructsSchemaItems &struct_schema_items,\n'''
1385         u'''    const StructIdentifiers::eType struct_id) {\n'''
1386         u'''  const TStructsSchemaItems::const_iterator it = '''
1387         u'''struct_schema_items.find(struct_id);\n'''
1388         u'''  if (it != struct_schema_items.end()) {\n'''
1389         u'''    return it->second;\n'''
1390         u'''  }\n'''
1391         u'''\n'''
1392         u'''  return NsSmartDeviceLink::NsSmartObjects::'''
1393         u'''CAlwaysFalseSchemaItem::create();\n'''
1394         u'''}\n'''
1395         u'''\n'''
1396         u'''void $namespace::$class_name::InitStructSchemes(\n'''
1397         u'''    TStructsSchemaItems &struct_schema_items) {'''
1398         u'''$struct_schema_items'''
1399         u'''}\n'''
1400         u'''\n'''
1401         u'''void $namespace::$class_name::InitFunctionSchemes(\n'''
1402         u'''    const TStructsSchemaItems &struct_schema_items,\n'''
1403         u'''    const std::set<FunctionID::eType> &function_id_items,\n'''
1404         u'''    const std::set<messageType::eType> &message_type_items) {\n'''
1405         u'''$pre_function_schemas'''
1406         u'''$function_schemas'''
1407         u'''}\n'''
1408         u'''\n'''
1409         u'''//------------- Functions schemes initialization -------------\n'''
1410         u'''\n'''
1411         u'''$init_function_impls'''
1412         u'''\n'''
1413         u'''//----------- Structs schema items initialization ------------\n'''
1414         u'''\n'''
1415         u'''$init_structs_impls'''
1416         u'''\n'''
1417         u'''//-------------- String to value enum mapping ----------------\n'''
1418         u'''\n'''
1419         u'''namespace NsSmartDeviceLink {\n'''
1420         u'''namespace NsSmartObjects {\n'''
1421         u'''\n'''
1422         u'''$enum_string_coversions'''
1423         u'''\n'''
1424         u'''} // NsSmartObjects\n'''
1425         u'''} // NsSmartDeviceLink\n'''
1426         u'''\n''')
1427
1428     _enum_to_str_converter_template = string.Template(
1429         u'''template <>\n'''
1430         u'''const std::map<${namespace}::${enum}::eType, '''
1431         u'''std::string> &TEnumSchemaItem<${namespace}::${enum}::eType>::'''
1432         u'''getEnumElementsStringRepresentation() {\n'''
1433         u'''  static std::map<${namespace}::${enum}::eType, '''
1434         u'''std::string> enum_string_representation {\n'''
1435         u'''\n'''
1436         u'''${mapping}'''
1437         u'''\n'''
1438         u'''  };\n'''
1439         u'''\n'''
1440         u'''  return enum_string_representation;\n'''
1441         u'''}\n''')
1442
1443     _enum_to_str_mapping_template = string.Template(
1444         u'''{${namespace}::'''
1445         u'''${enum_name}::${enum_value}, "${string}"},''')
1446
1447     _struct_schema_item_template = string.Template(
1448         u'''utils::SharedPtr<ISchemaItem> struct_schema_item_${name} = '''
1449         u'''InitStructSchemaItem_${name}(struct_schema_items);\n'''
1450         u'''struct_schema_items.insert(std::make_pair('''
1451         u'''StructIdentifiers::${name}, struct_schema_item_${name}));\n'''
1452         u'''structs_schemes_.insert(std::make_pair('''
1453         u'''StructIdentifiers::${name}, CSmartSchema('''
1454         u'''struct_schema_item_${name})));''')
1455
1456     _function_schema_template = string.Template(
1457         u'''functions_schemes_.insert(std::make_pair(NsSmartDeviceLink::'''
1458         u'''NsJSONHandler::'''
1459         u'''SmartSchemaKey<FunctionID::eType, messageType::eType>'''
1460         u'''(FunctionID::$function_id, messageType::$message_type), '''
1461         u'''InitFunction_${function_id}_${message_type}('''
1462         u'''struct_schema_items, function_id_items, message_type_items)));''')
1463
1464     _struct_impl_template = string.Template(
1465         u'''utils::SharedPtr<ISchemaItem> $namespace::$class_name::'''
1466         u'''InitStructSchemaItem_${struct_name}(\n'''
1467         u'''    const TStructsSchemaItems &struct_schema_items) {\n'''
1468         u'''$code'''
1469         u'''}\n''')
1470
1471     _struct_impl_code_tempate = string.Template(
1472         u'''${schema_loc_decl}'''
1473         u'''${schema_items_decl}'''
1474         u'''std::map<std::string, CObjectSchemaItem::SMember> '''
1475         u'''schema_members;\n\n'''
1476         u'''${schema_item_fill}'''
1477         u'''return CObjectSchemaItem::create(schema_members);''')
1478
1479     _impl_code_loc_decl_enum_template = string.Template(
1480         u'''std::set<${type}::eType> ${var_name};''')
1481
1482     _impl_code_loc_decl_enum_insert_template = string.Template(
1483         u'''${var_name}.insert(${enum}::${value});''')
1484
1485     _impl_code_item_decl_temlate = string.Template(
1486         u'''${comment}'''
1487         u'''utils::SharedPtr<ISchemaItem> ${var_name} = ${item_decl};''')
1488
1489     _impl_code_integer_item_template = string.Template(
1490         u'''TNumberSchemaItem<${type}>::create(${params})''')
1491
1492     _impl_code_bool_item_template = string.Template(
1493         u'''CBoolSchemaItem::create(${params})''')
1494
1495     _impl_code_string_item_template = string.Template(
1496         u'''CStringSchemaItem::create(${params})''')
1497
1498     _impl_code_array_item_template = string.Template(
1499         u'''CArraySchemaItem::create(${params})''')
1500
1501     _impl_code_struct_item_template = string.Template(
1502         u'''ProvideObjectSchemaItemForStruct(struct_schema_items, '''
1503         u'''StructIdentifiers::${name})''')
1504
1505     _impl_code_enum_item_template = string.Template(
1506         u'''TEnumSchemaItem<${type}::eType>::create(${params})''')
1507
1508     _impl_code_item_param_value_template = string.Template(
1509         u'''TSchemaItemParameter<$type>($value)''')
1510
1511     _impl_code_item_fill_template = string.Template(
1512         u'''schema_members["${name}"] = CObjectSchemaItem::'''
1513         u'''SMember(${var_name}, ${is_mandatory});''')
1514
1515     _function_impl_template = string.Template(
1516         u'''CSmartSchema $namespace::$class_name::'''
1517         u'''InitFunction_${function_id}_${message_type}(\n'''
1518         u'''    const TStructsSchemaItems &struct_schema_items,\n'''
1519         u'''    const std::set<FunctionID::eType> &function_id_items,\n'''
1520         u'''    const std::set<messageType::eType> &message_type_items) {\n'''
1521         u'''$code'''
1522         u'''}\n''')
1523
1524     _function_impl_code_tempate = string.Template(
1525         u'''${schema_loc_decl}'''
1526         u'''${schema_items_decl}'''
1527         u'''std::map<std::string, CObjectSchemaItem::SMember> '''
1528         u'''schema_members;\n\n'''
1529         u'''${schema_item_fill}'''
1530         u'''std::map<std::string, CObjectSchemaItem::SMember> '''
1531         u'''params_members;\n'''
1532         u'''${schema_params_fill}'''
1533         u'''\n'''
1534         u'''std::map<std::string, CObjectSchemaItem::SMember> '''
1535         u'''root_members_map;\n'''
1536         u'''root_members_map[NsSmartDeviceLink::NsJSONHandler::'''
1537         u'''strings::S_MSG_PARAMS] = '''
1538         u'''CObjectSchemaItem::SMember(CObjectSchemaItem::'''
1539         u'''create(schema_members), true);\n'''
1540         u'''root_members_map[NsSmartDeviceLink::NsJSONHandler::'''
1541         u'''strings::S_PARAMS] = '''
1542         u'''CObjectSchemaItem::SMember(CObjectSchemaItem::'''
1543         u'''create(params_members), true);\n\n'''
1544         u'''return CSmartSchema(CObjectSchemaItem::'''
1545         u'''create(root_members_map));''')
1546
1547     _class_h_template = string.Template(
1548         u'''$comment\n'''
1549         u'''class $class_name : public NsSmartDeviceLink::NsJSONHandler::'''
1550         u'''CSmartFactory<FunctionID::eType, messageType::eType, '''
1551         u'''StructIdentifiers::eType> {\n'''
1552         u''' public:\n'''
1553         u'''  /**\n'''
1554         u'''   * @brief Constructor.\n'''
1555         u'''   */\n'''
1556         u'''  $class_name();\n'''
1557         u'''\n'''
1558         u''' protected:\n'''
1559         u'''  /**\n'''
1560         u'''   * @brief Type that maps of struct IDs to schema items.\n'''
1561         u'''   */\n'''
1562         u'''  typedef std::map<const StructIdentifiers::eType, '''
1563         u'''utils::SharedPtr<NsSmartDeviceLink::NsSmartObjects::'''
1564         u'''ISchemaItem> > TStructsSchemaItems;\n'''
1565         u'''\n'''
1566         u'''  /**\n'''
1567         u'''   * @brief Helper that allows to make reference to struct\n'''
1568         u'''   *\n'''
1569         u'''   * @param struct_schema_items Struct schema items.\n'''
1570         u'''   * @param struct_id ID of structure to provide.\n'''
1571         u'''   *\n'''
1572         u'''   * @return utils::SharedPtr of strucute\n'''
1573         u'''   */\n'''
1574         u'''  static '''
1575         u'''utils::SharedPtr<NsSmartDeviceLink::NsSmartObjects::ISchemaItem> '''
1576         u'''ProvideObjectSchemaItemForStruct(\n'''
1577         u'''        const TStructsSchemaItems &struct_schema_items,\n'''
1578         u'''        const StructIdentifiers::eType struct_id);\n'''
1579         u'''\n'''
1580         u'''  /**\n'''
1581         u'''   * @brief Initializes all struct schemes.\n'''
1582         u'''   */\n'''
1583         u'''  void InitStructSchemes('''
1584         u'''TStructsSchemaItems &struct_schema_items);\n'''
1585         u'''\n'''
1586         u'''  /**\n'''
1587         u'''   * @brief Initializes all function schemes.\n'''
1588         u'''   *\n'''
1589         u'''   * @param struct_schema_items Struct schema items.\n'''
1590         u'''   * @param function_id_items Set of all elements '''
1591         u'''of FunctionID enum.\n'''
1592         u'''   * @param message_type_items Set of all elements '''
1593         u'''of messageType enum.\n'''
1594         u'''   */\n'''
1595         u'''  void InitFunctionSchemes(\n'''
1596         u'''      const TStructsSchemaItems &struct_schema_items,\n'''
1597         u'''      const std::set<FunctionID::eType> &function_id_items,\n'''
1598         u'''      const std::set<messageType::eType> '''
1599         u'''&message_type_items);\n'''
1600         u'''\n'''
1601         u'''$init_function_decls'''
1602         u'''\n'''
1603         u'''$init_struct_decls'''
1604         u'''};''')
1605
1606     _function_return_comment = u''' * @return NsSmartDeviceLink::''' \
1607                                u'''NsSmartObjects::CSmartSchema\n'''
1608
1609     _function_decl_template = string.Template(
1610         u'''$comment\n'''
1611         u'''static NsSmartDeviceLink::NsSmartObjects::CSmartSchema '''
1612         u'''InitFunction_${function_id}_${message_type}(\n'''
1613         u'''    const TStructsSchemaItems &struct_schema_items,\n'''
1614         u'''    const std::set<FunctionID::eType> &function_id_items,\n'''
1615         u'''    const std::set<messageType::eType> &message_type_items);''')
1616
1617     _struct_decl_template = string.Template(
1618         u'''$comment\n'''
1619         u'''static '''
1620         u'''utils::SharedPtr<NsSmartDeviceLink::NsSmartObjects::ISchemaItem> '''
1621         u'''InitStructSchemaItem_${struct_name}(\n'''
1622         u'''    const TStructsSchemaItems &struct_schema_items);''')
1623
1624     _class_comment_template = string.Template(
1625         u'''/**\n'''
1626         u''' * @brief Class $class_name.\n'''
1627         u''' *\n'''
1628         u''' * Params:\n'''
1629         u'''$class_params'''
1630         u''' */''')
1631
1632     _comment_doxygen_template = string.Template(
1633         u'''/**\n'''
1634         u'''$brief_description'''
1635         u'''$description'''
1636         u'''$design_description'''
1637         u'''$issues'''
1638         u'''$todos'''
1639         u'''$returns */''')
1640
1641     _comment_cc_template = string.Template(
1642         u'''$brief_description'''
1643         u'''$description'''
1644         u'''$design_description'''
1645         u'''$issues'''
1646         u'''$todos'''
1647         u'''$returns''')
1648
1649     _enum_template = string.Template(
1650         u'''namespace $name {\n'''
1651         u'''$comment\n'''
1652         u'''enum eType {\n'''
1653         u'''$enum_items};\n'''
1654         u'''} // $name\n''')
1655
1656     _enum_element_with_value_template = string.Template(
1657         u'''$comment\n'''
1658         u'''$name = $value''')
1659
1660     _enum_element_with_no_value_template = string.Template(
1661         u'''$comment\n'''
1662         u'''$name''')
1663
1664     _indent_template = u"  "