15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)"""Code shared by the various language-specific code generators."""
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochfrom functools import partial
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport os.path
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdochimport re
100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport module as mojom
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport pack
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)def GetStructFromMethod(method):
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  """Converts a method's parameters into the fields of a struct."""
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  params_class = "%s_%s_Params" % (method.interface.name, method.name)
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  struct = mojom.Struct(params_class, module=method.interface.module)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for param in method.parameters:
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    struct.AddField(param.name, param.kind, param.ordinal)
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  struct.packed = pack.PackedStruct(struct)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return struct
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)def GetResponseStructFromMethod(method):
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  """Converts a method's response_parameters into the fields of a struct."""
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  params_class = "%s_%s_ResponseParams" % (method.interface.name, method.name)
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  struct = mojom.Struct(params_class, module=method.interface.module)
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for param in method.response_parameters:
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    struct.AddField(param.name, param.kind, param.ordinal)
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  struct.packed = pack.PackedStruct(struct)
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return struct
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)def GetDataHeader(exported, struct):
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  struct.packed = pack.PackedStruct(struct)
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  struct.bytes = pack.GetByteLayout(struct.packed)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct.exported = exported
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return struct
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdef ExpectedArraySize(kind):
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if mojom.IsFixedArrayKind(kind):
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return kind.length
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return 0
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def StudlyCapsToCamel(studly):
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return studly[0].lower() + studly[1:]
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdef CamelCaseToAllCaps(camel_case):
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return '_'.join(
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      word for word in re.split(r'([A-Z][^A-Z]+)', camel_case) if word).upper()
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Generator(object):
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # Pass |output_dir| to emit files to disk. Omit |output_dir| to echo all
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # files to stdout.
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def __init__(self, module, output_dir=None):
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    self.module = module
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    self.output_dir = output_dir
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def GetStructsFromMethods(self):
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result = []
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for interface in self.module.interfaces:
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for method in interface.methods:
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        result.append(GetStructFromMethod(method))
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        if method.response_parameters != None:
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          result.append(GetResponseStructFromMethod(method))
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return map(partial(GetDataHeader, False), result)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def GetStructs(self):
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return map(partial(GetDataHeader, True), self.module.structs)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  def Write(self, contents, filename):
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if self.output_dir is None:
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      print contents
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    with open(os.path.join(self.output_dir, filename), "w+") as f:
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      f.write(contents)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  def GenerateFiles(self, args):
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    raise NotImplementedError("Subclasses must override/implement this method")
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  def GetJinjaParameters(self):
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    """Returns default constructor parameters for the jinja environment."""
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return {}
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  def GetGlobals(self):
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    """Returns global mappings for the template generation."""
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return {}
86