1. scope
  2. hob

Commits

Christian Krebs  committed 095c866

Auto generated classes to convert messages to objects.

  • Participants
  • Parent commits 2104383
  • Branches default

Comments (0)

Files changed (2)

File hob/_js.py

View file
  • Ignore whitespace
 import os
 import codecs
 import shutil
+from hob import proto
 from hob.proto import *
 from hob.proto import ServiceManager, iterProtoFiles  # fixme: presuambly redundant. runeh
 from hob.utils import dashed_name, DIST_ROOT, tempdir, strquote
         proto=proto,
         )
 
+def generate_message_classes(service, message, lookup, create_test_framework=False):
+    return lookup.get_template('js-message-classes.mako').render_unicode(
+        service=service,
+        message=message,
+        proto=proto,
+        )
+
 def generate_field_consts(
         message,
         lookup,
             javascript.up2date_count += 1
 
     if js_test_framework:
-        def_path = os.path.join(out_dir, 'defs')
-        if not os.path.exists(def_path):
-            os.mkdir(def_path)
+        for repo in ['defs', 'classes']:
+            def_path = os.path.join(out_dir, repo)
+            if not os.path.exists(def_path):
+                os.mkdir(def_path)
         message_defs = []
         for service in service_list:
             version = ".".join(service.options["version"].value.split('.')[:2])
             for command in service.itercommands():
-                message_defs.append(
-                    ("%s.%s.%s.%s.def" % (service.name, version, 'commands', command.name),
-                    generate_proto_defs(command.message,
-                            lookup, create_test_framework=js_test_framework)))
-                message_defs.append(
-                    ("%s.%s.%s.%s.def" % (service.name, version, 'responses', command.name),
-                    generate_proto_defs(command.response,
-                            lookup, create_test_framework=js_test_framework)))
+                message_defs.append((
+                    "defs", 
+                    "%s.%s.%s.%s.def" % (service.name, version, 'commands', command.name),
+                    generate_proto_defs(command.message, lookup, js_test_framework)
+                ))
+                message_defs.append((
+                    "defs", 
+                    "%s.%s.%s.%s.def" % (service.name, version, 'responses', command.name),
+                    generate_proto_defs(command.response, lookup, js_test_framework)
+                ))
+                message_defs.append((
+                    "classes", 
+                    "%s.%s.%s.%s.js" % (service.name, version, 'responses', command.name),
+                    generate_message_classes(service, command.response, lookup, js_test_framework)
+                ))
             for event in service.iterevents():
-                message_defs.append(
-                    ("%s.%s.%s.%s.def" % (service.name, version, 'events', event.name),
-                    generate_proto_defs(event.message,
-                            lookup, create_test_framework=js_test_framework)))
-        for file_name, text in message_defs:
-            short_path = os.path.join('defs', file_name)
+                message_defs.append((
+                    "defs", 
+                    "%s.%s.%s.%s.def" % (service.name, version, 'events', event.name),
+                    generate_proto_defs(event.message, lookup, js_test_framework)
+                ))
+                message_defs.append((
+                    "classes", 
+                    "%s.%s.%s.%s.js" % (service.name, version, 'events', event.name),
+                    generate_message_classes(service, event.message, lookup, js_test_framework)
+                ))
+        for repo, file_name, text in message_defs:
+            short_path = os.path.join(repo, file_name)
             path = os.path.join(out_dir, short_path)
             res = updateFile(path, text, mode="wb")
             if res in (WRITE_UPDATED, WRITE_CREATED):

File templates/js/js-message-classes.mako

View file
  • Ignore whitespace
+<%
+  INDENT = indent or '  '
+  local_comments = comments or ["/** \n", "  * ", "  */"]
+  version = ".".join(service.options["version"].value.split('.')[:2])
+  def get_submessages(fields, names=[]):
+      ret = []
+      for field in fields:
+          if field.message and isinstance(field.message, proto.Message) and not field.message.name in names:
+              names.append(field.message.name)
+              ret.append(field)
+              ret += get_submessages(field.message.fields, names)
+      return ret
+  submessages = get_submessages(message.fields)
+%>\
+  ## ************************************************************** ##
+  ## def print_doc
+  ## ************************************************************** ##
+<%def name="print_doc(doc, indent_level=0, indent='  ')">\
+${(local_comments[0] and indent_level or 0)*indent}${local_comments[0]}\
+      % for line in doc.text.splitlines():
+${(indent_level)*indent}${local_comments[1]}${line.strip('\r\n')}
+      % endfor
+${(indent_level)*indent}${local_comments[2]}\
+</%def>\
+  ## ************************************************************** ##
+  ## def message_class
+  ## ************************************************************** ##
+<%def name="message_class(message, submessages=None)">\
+  % if message.doc:
+${print_doc(message.doc, 0, INDENT)}
+  % endif
+  % if message.comment:
+${INDENT}// ${message.comment}
+  % endif
+cls.${service.name}["${version}"].${message.name} = function(arr)
+{
+  % for field in message.fields:
+    % if field.doc:
+${print_doc(field.doc, 1, INDENT)}
+    % endif
+    % if field.comment:
+${INDENT}// ${field.comment}
+    % endif
+    % if field.q.name == "repeated":
+${INDENT}this.${field.name} = (arr[${str(field.number - 1)}] || []).map(function(item)
+${INDENT}{
+${INDENT * 2}return new cls.${service.name}["${version}"].${field.typename()}(item);
+${INDENT}});
+    % elif field.message and isinstance(field.message, proto.Message):
+${INDENT}this.${field.name} = arr[${str(field.number - 1)}] ? new cls.${service.name}["${version}"].${field.typename()}(arr[${str(field.number - 1)}]) || null;
+    % else:
+      % if field.message and isinstance(field.message, proto.Enum):
+${INDENT}// cls.${service.name}["${version}"].${message.name}.${field.message.name}
+      % endif
+${INDENT}this.${field.name} = arr[${str(field.number - 1)}];
+    % endif
+  % endfor
+};
+% if message.enums:
+  % for enum in message.enums:
+    % if enum.doc:
+${print_doc(enum.doc, 0, INDENT)}
+    % endif
+cls.${service.name}["${version}"].${message.name}.${enum.name} =
+{
+    % for value in enum.values:
+      % if value.doc:
+${print_doc(value.doc, 1, INDENT)}
+      % endif
+${INDENT}${value.value}: "${value.name}",
+    % endfor
+};
+  % endfor
+% endif
+</%def>\
+  ## ************************************************************** ##
+  ## template
+  ## ************************************************************** ##
+// Autogenerated by hob
+window.cls || (window.cls = {});
+cls.${service.name} || (cls.${service.name} = {});
+cls.${service.name}["${version}"] || (cls.${service.name}["${version}"] = {});
+
+${message_class(message, submessages=submessages)}
+% for submsg in submessages:
+${message_class(submsg.message, submessages=None)}
+% endfor