195640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org#!/usr/bin/env python
295640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org# Copyright (c) 2012 The Chromium Authors. All rights reserved.
301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Use of this source code is governed by a BSD-style license that can be
401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# found in the LICENSE file.
501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''Interface for all gatherers.
701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''
801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
10ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.orgimport os.path
11ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.orgimport types
12ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org
1301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit import clique
14ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.orgfrom grit import util
1501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgclass GathererBase(object):
1801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''Interface for all gatherer implementations.  Subclasses must implement
1901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  all methods that raise NotImplemented.'''
2001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
21ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org  def __init__(self, rc_file, extkey=None, encoding='cp1252', is_skeleton=False):
22ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    '''Initializes the gatherer object's attributes, but does not attempt to
23ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    read the input file.
24ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org
25ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    Args:
26ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      rc_file: The 'file' attribute of the <structure> node (usually the
27ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org               relative path to the source file).
28ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      extkey: e.g. 'ID_MY_DIALOG'
29ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      encoding: e.g. 'utf-8'
30ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      is_skeleton: Indicates whether this gatherer is a skeleton gatherer, in
31ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org                   which case we should not do some types of processing on the
32ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org                   translateable bits.
33ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    '''
34ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    self.rc_file = rc_file
35ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    self.extkey = extkey
36ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    self.encoding = encoding
3701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # A default uberclique that is local to this object.  Users can override
3801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # this with the uberclique they are using.
3901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.uberclique = clique.UberClique()
4001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Indicates whether this gatherer is a skeleton gatherer, in which case
4101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # we should not do some types of processing on the translateable bits.
42ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    self.is_skeleton = is_skeleton
43f07ff673a7c834bc676728aa399f1a5305f7b510flackr@chromium.org    # Stores the grd node on which this gatherer is running. This allows
44f07ff673a7c834bc676728aa399f1a5305f7b510flackr@chromium.org    # evaluating expressions.
45f07ff673a7c834bc676728aa399f1a5305f7b510flackr@chromium.org    self.grd_node = None
4601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
478a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org  def SetAttributes(self, attrs):
488a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    '''Sets node attributes used by the gatherer.
498a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
508a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    By default, this does nothing.  If special handling is desired, it should be
518a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    overridden by the child gatherer.
528a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
538a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    Args:
548a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org      attrs: The mapping of node attributes.
558a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    '''
568a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org    pass
578a303dc2cabedfd395b49f21310ea21c77056fe7joi@chromium.org
58bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org  def SetDefines(self, defines):
59bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    '''Sets global defines used by the gatherer.
60bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org
61bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    By default, this does nothing.  If special handling is desired, it should be
62bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    overridden by the child gatherer.
63bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org
64bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    Args:
65bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org      defines: The mapping of define values.
66bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    '''
67bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    pass
68bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org
69f07ff673a7c834bc676728aa399f1a5305f7b510flackr@chromium.org  def SetGrdNode(self, node):
70f07ff673a7c834bc676728aa399f1a5305f7b510flackr@chromium.org    '''Sets the grd node on which this gatherer is running.
71f07ff673a7c834bc676728aa399f1a5305f7b510flackr@chromium.org    '''
72f07ff673a7c834bc676728aa399f1a5305f7b510flackr@chromium.org    self.grd_node = node
73f07ff673a7c834bc676728aa399f1a5305f7b510flackr@chromium.org
7401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def SetUberClique(self, uberclique):
7501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Overrides the default uberclique so that cliques created by this object
7601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    become part of the uberclique supplied by the user.
7701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
7801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.uberclique = uberclique
7901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
8001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def Parse(self):
81ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    '''Reads and parses the contents of what is being gathered.'''
8201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    raise NotImplementedError()
8301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
84bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org  def GetData(self, lang, encoding):
85bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    '''Returns the data to be added to the DataPack for this node or None if
86bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    this node does not add a DataPack entry.
87bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    '''
88bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org    return None
89bcb40ba9feaa9b7f076133f5a4242b79270e77c1flackr@chromium.org
9001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetText(self):
9101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Returns the text of what is being gathered.'''
9201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    raise NotImplementedError()
9301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
9401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetTextualIds(self):
9501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Returns the mnemonic IDs that need to be defined for the resource
9601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    being gathered to compile correctly.'''
9701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return []
9801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
9901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetCliques(self):
10001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Returns the MessageClique objects for all translateable portions.'''
10101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return []
10201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
103ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org  def GetInputPath(self):
104ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    return self.rc_file
105ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org
106418c15a67abb1566529fb247af2fe3e1c9e8c17dflackr@chromium.org  def GetHtmlResourceFilenames(self):
107418c15a67abb1566529fb247af2fe3e1c9e8c17dflackr@chromium.org    """Returns a set of all filenames inlined by this gatherer."""
108418c15a67abb1566529fb247af2fe3e1c9e8c17dflackr@chromium.org    return []
109418c15a67abb1566529fb247af2fe3e1c9e8c17dflackr@chromium.org
11001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def Translate(self, lang, pseudo_if_not_available=True,
11101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                skeleton_gatherer=None, fallback_to_english=False):
11201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Returns the resource being gathered, with translateable portions filled
11301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    with the translation for language 'lang'.
11401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
11501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    If pseudo_if_not_available is true, a pseudotranslation will be used for any
11601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    message that doesn't have a real translation available.
11701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
11801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    If no translation is available and pseudo_if_not_available is false,
11901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    fallback_to_english controls the behavior.  If it is false, throw an error.
12001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    If it is true, use the English version of the message as its own
12101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    "translation".
12201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
12301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    If skeleton_gatherer is specified, the translation will use the nontranslateable
12401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    parts from the gatherer 'skeleton_gatherer', which must be of the same type
12501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    as 'self'.
12601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
12701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    If fallback_to_english
12801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
12901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Args:
13001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      lang: 'en'
13101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      pseudo_if_not_available: True | False
13201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      skeleton_gatherer: other_gatherer
13301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      fallback_to_english: True | False
13401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Return:
13601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      e.g. 'ID_THIS_SECTION TYPE\n...BEGIN\n  "Translated message"\n......\nEND'
13701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Raises:
13901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      grit.exception.NotReady() if used before Parse() has been successfully
14001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      called.
14101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      grit.exception.NoSuchTranslation() if 'pseudo_if_not_available' and
14201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      fallback_to_english are both false and there is no translation for the
14301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      requested language.
14401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
14501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    raise NotImplementedError()
14601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
14777cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org  def SubstituteMessages(self, substituter):
14877cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org    '''Applies substitutions to all messages in the gatherer.
14977cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org
15077cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org    Args:
15177cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org      substituter: a grit.util.Substituter object.
15277cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org    '''
15377cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org    pass
15401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
155006588227ffb5ff646051dcb4f04198edcf038c9joaodasilva@chromium.org  def SetFilenameExpansionFunction(self, fn):
156006588227ffb5ff646051dcb4f04198edcf038c9joaodasilva@chromium.org    '''Sets a function for rewriting filenames before gathering.'''
157006588227ffb5ff646051dcb4f04198edcf038c9joaodasilva@chromium.org    pass
158006588227ffb5ff646051dcb4f04198edcf038c9joaodasilva@chromium.org
159ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org  # TODO(benrg): Move this elsewhere, since it isn't part of the interface.
160b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org  def _LoadInputFile(self):
161ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    '''A convenience function for subclasses that loads the contents of the
162ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    input file.
163ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    '''
164ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    if isinstance(self.rc_file, types.StringTypes):
165ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      path = self.GetInputPath()
166ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      # Hack: some unit tests supply an absolute path and no root node.
167ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      if not os.path.isabs(path):
168ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org        path = self.grd_node.ToRealPath(path)
169b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.org      return util.ReadFile(path, self.encoding)
170ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org    else:
171ec8016c73b3b945b6284746230913d88653f35e7benrg@chromium.org      return self.rc_file.read()
172